System.Data.SQLite

Check-in Differences
Login

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

Difference From f909e1b7b15407de To ec237b012300b80f

2012-01-05
06:37
Merge the VS installer integration fixes and changes to the trunk. check-in: 2db8c0b5a5 user: mistachkin tags: trunk
2012-01-04
09:41
Add the VS designer components and the rewritten installer for them to the setup package. check-in: bcdca9ada5 user: mistachkin tags: VsSetupIntegration
07:15
Remove unnecessary nesting of 'if' blocks in the command line argument processing. Add comments and fixup some whitespace. check-in: f909e1b7b1 user: mistachkin tags: trunk
05:55
Fix an incorrect comment. check-in: 8887a9f786 user: mistachkin tags: trunk
2005-03-01
17:32
Initial revision check-in: 5b6332ffaa user: rmsimpson tags: sourceforge
16:04
Initial checkin Closed-Leaf check-in: 3ca8c53212 user: rmsimpson tags: start, sourceforge
16:04
Initial revision check-in: ec237b0123 user: rmsimpson tags: trunk, sourceforge

Deleted Doc/Extra/dbfactorysupport.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>DbProviderFactory Support</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">DbProviderFactory Support</span>
          </td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite.NET Class Library Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">DbProviderFactories and You</h1>
      <p>One of the great new features of ADO.NET 2.0 is the use of reflection as a 
        means of instantiating database providers programmatically. The information 
        .NET uses to enumerate the available data providers in the system is relatively 
        simple. It merely looks in the machine.config and in your own app.config file for some XML data to tell it what providers are 
        installed and what assemblies those providers are in.
      </p>
      <h4>
        Scenario 1:&nbsp; Version Independent (does not use the Global Assembly Cache)</h4>
      <p>
        This method allows you to drop any new version of the System.Data.SQLite.DLL into
        your application's folder and use it without any code modifications or recompiling.&nbsp;
        Add the following code to your app.config file:</p>
      <div class="syntax">
        <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"<br />           type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /&gt;
    &lt;/DbProviderFactories&gt;
  &lt;/system.data&gt;
&lt;/configuration&gt;
</PRE>
      </div>
      <h4>
        Scenario 2:&nbsp; Version Dependent, using either the DLL located in the same folder
        as the application or the Global Assembly Cache</h4>
      <p>
        This method expands on the above XML to provide the version number and key token
        of the SQLite DLL so it can be found either in the same folder as the application
        or looked up in the GAC.&nbsp; The downside to this method is that DbProviderFactories
        will use this version information to only load the version specified.&nbsp; This
        means if you update the DLL, you must also update this XML.</p>
      <div class="syntax">
        <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.77.0, Culture=neutral,
                 PublicKeyToken=db937bc2d44ff139"/&gt;
    &lt;/DbProviderFactories&gt;
  &lt;/system.data&gt;
&lt;/configuration&gt;
</pre>
      </div>
      <p>
        The following C# code demonstrates 
        instantiating SQLite through DbProviderFactories:</p>
      <div class="syntax"><pre>      DbProviderFactory fact = DbProviderFactories.GetFactory("System.Data.SQLite");
      using (DbConnection cnn = fact.CreateConnection())
      {
        cnn.ConnectionString = "Data Source=test.db3";
        cnn.Open();
      }</pre>
      </div>
      <hr>
      <div id="footer">
        <p>
          <a href="mailto:sqlite-users@sqlite.org?subject=SQLite.NET%20Class%20Library%20Documentation%20Feedback:%20Factory%20Support">
            Send comments on this topic.</a>
        </p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































Deleted Doc/Extra/designer.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>Design-Time Support</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">Design-Time Support</span>
          </td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite.NET Class Library Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">

      <h1 class="heading">Installing SQLite Visual Studio Design-Time Support</h1>
      <p>Supporting the Visual Studio query designer and allowing you to manipulate 
        SQLite databases from within Visual Studio is a great time-saver.&nbsp; Though 
        the support is not yet fully-implemented, there's certainly enough there to 
        keep you busy.&nbsp; You can create databases, design and execute queries, 
        create typed datasets and lots more all from Visual Studio.</p>
      <h3> Installation Instructions</h3>
      <p>
        In Windows Explorer, navigate to <STRONG>SQLite.Net\bin\Designer</STRONG>
        and execute the <STRONG>INSTALL.EXE</STRONG> program.&nbsp; It will automatically
        detect what eligible Visual Studio products are installed, and allow you to check
        and uncheck which environments to install the designer for.</p>
      <h3> Express Edition Limitations</h3>
      <p>All Express Editions (except Visual Web Developer) are hard-coded to only allow you to design for Jet and Sql Server Database Files.&nbsp; The only way for SQLite
        to install its designer is to temporarily replace one of the existing "approved"
        designers.&nbsp; Therefore, when you install the SQLite designer for one of these
        express editions, it will temporarily replace the Microsoft Access designer.&nbsp;
        You can revert back to the Access designer simply by re-running the install.exe
        program and un-checking the boxes.</p>
      <hr/>
      <div id="footer">
        <p>
          <a href="mailto:sqlite-users@sqlite.org?subject=SQLite.NET%20Class%20Library%20Documentation%20Feedback:%20Designer%20Support">
            Send comments on this topic.</a>
        </p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































Deleted Doc/Extra/lang_altertable.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>ALTER TABLE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">ALTER TABLE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        ALTER TABLE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ALTER TABLE </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">database-name</font></i><b><font color="#2c2cf0"> <big>.</big></font></b>]<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">table-name</font></i><b><font
                    color="#2c2cf0"> </font></b><i><font color="#ff3434">alteration</font></i><b><font
                      color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">alteration</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">RENAME TO </font></b><i><font color="#ff3434">new-table-name</font></i><b><font
                color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">alteration</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ADD </font></b>[<b><font color="#2c2cf0">COLUMN</font></b>]<b><font
                color="#2c2cf0"> </font></b><i><font color="#ff3434">column-def</font></i><b><font
                  color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        SQLite's version of the ALTER TABLE command allows the user to rename or add a new
        column to an existing table. It is not possible to remove a column from a table.
      </p>
      <p>
        The RENAME TO syntax is used to rename the table identified by <i>[database-name.]table-name</i>
        to <i>new-table-name</i>. This command cannot be used to move a table between attached
        databases, only to rename a table within the same database.</p>
      <p>
        If the table being renamed has triggers or indices, then these remain attached to
        the table after it has been renamed. However, if there are any view definitions,
        or statements executed by triggers that refer to the table being renamed, these
        are not automatically modified to use the new table name. If this is required, the
        triggers or view definitions must be dropped and recreated to use the new table
        name by hand.
      </p>
      <p>
        The ADD [COLUMN] syntax is used to add a new column to an existing table. The new
        column is always appended to the end of the list of existing columns. <i>Column-def</i>
        may take any of the forms permissable in a CREATE TABLE statement, with the following
        restrictions:
      </p>
      <ul>
        <li>The column may not have a PRIMARY KEY or UNIQUE constraint. </li>
        <li>The column may not have a default value of CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP.
        </li>
        <li>If a NOT NULL constraint is specified, then the column must have a default value
          other than NULL. </li>
      </ul>
      <p>
        The execution time of the ALTER TABLE command is independent of the amount of data
        in the table. The ALTER TABLE command runs as quickly on a table with 10 million
        rows as it does on a table with 1 row.
      </p>
      <p>
        After ADD COLUMN has been run on a database, that database will not be readable
        by SQLite version 3.1.3 and earlier until the database is <a href="lang_vacuum.html">
          VACUUM</a>ed.</p>
      <p>
        &nbsp;</p>
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































Deleted Doc/Extra/lang_analyze.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>ANALYZE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">ANALYZE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        ANALYZE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ANALYZE</font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ANALYZE </font></b><i><font color="#ff3434">database-name</font></i><b><font
                color="#2c2cf0"></font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ANALYZE </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">database-name</font></i><b><font color="#2c2cf0"> <big>.</big></font></b>]<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">table-name</font></i><b><font
                    color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The ANALYZE command gathers statistics about indices and stores them in a special
        tables in the database where the query optimizer can use them to help make better
        index choices. If no arguments are given, all indices in all attached databases
        are analyzed. If a database name is given as the argument, all indices in that one
        database are analyzed. If the argument is a table name, then only indices associated
        with that one table are analyzed.</p>
      <p>
        The initial implementation stores all statistics in a single table named <b>sqlite_stat1</b>.
        Future enhancements may create additional tables with the same name pattern except
        with the "1" changed to a different digit. The <b>sqlite_stat1</b> table cannot be <a href="lang_droptable.html">DROP</a>ped, but all the content can be <a href="lang_delete.html">
          DELETE</a>d which has the same effect.</p>
      <p>
        &nbsp;</p>
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































Deleted Doc/Extra/lang_attach.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>ATTACH DATABASE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">ATTACH DATABASE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        ATTACH DATABASE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ATTACH </font></b>[<b><font color="#2c2cf0">DATABASE</font></b>]<b><font
                color="#2c2cf0"> </font></b><i><font color="#ff3434">database-filename</font></i><b><font
                  color="#2c2cf0"> AS </font></b><i><font color="#ff3434">database-name</font></i><b><font
                    color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The ATTACH DATABASE statement adds another database file to the current database
        connection. If the filename contains punctuation characters it must be quoted. The
        names 'main' and 'temp' refer to the main database and the database used for temporary
        tables. These cannot be detached. Attached databases are removed using the <a href="lang_detach.html">
          DETACH DATABASE</a> statement.</p>
      <p>
        You can read from and write to an attached database and you can modify the schema
        of the attached database. This is a new feature of SQLite version 3.0. In SQLite
        2.8, schema changes to attached databases were not allowed.</p>
      <p>
        You cannot create a new table with the same name as a table in an attached database,
        but you can attach a database which contains tables whose names are duplicates of
        tables in the main database. It is also permissible to attach the same database
        file multiple times.</p>
      <p>
        Tables in an attached database can be referred to using the syntax <i>database-name.table-name</i>.
        If an attached table doesn't have a duplicate table name in the main database, it
        doesn't require a database name prefix. When a database is attached, all of its
        tables which don't have duplicate names become the default table of that name. Any
        tables of that name attached afterwards require the table prefix. If the default
        table of a given name is detached, then the last table of that name attached becomes
        the new default.</p>
      <p>
        Transactions involving multiple attached databases are atomic, assuming that the
        main database is not ":memory:". If the main database is ":memory:" then transactions
        continue to be atomic within each individual database file. But if the host computer
        crashes in the middle of a COMMIT where two or more database files are updated,
        some of those files might get the changes where others might not. Atomic commit
        of attached databases is a new feature of SQLite version 3.0. In SQLite version
        2.8, all commits to attached databases behaved as if the main database were ":memory:".
      </p>
      <p>
        There is a compile-time limit of 10 attached database files.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































Deleted Doc/Extra/lang_comment.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>comment</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">comment</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        comment</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">comment</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">SQL-comment</font></i><b><font
                color="#2c2cf0"> </font></b><big>|</big><b><font color="#2c2cf0"> </font></b><i><font
                  color="#ff3434">C-comment</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">SQL-comment</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">-- </font></b><i><font color="#ff3434">single-line</font></i><b><font
                color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">C-comment</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">/<big>*</big> </font></b><i><font color="#ff3434">multiple-lines</font></i><b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"><big>*</big>/</font></b>]<b><font
                  color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        Comments aren't SQL commands, but can occur in SQL queries. They are treated as
        whitespace by the parser. They can begin anywhere whitespace can be found, including
        inside expressions that span multiple lines.
      </p>
      <p>
        SQL comments only extend to the end of the current line.</p>
      <p>
        C comments can span any number of lines. If there is no terminating delimiter, they
        extend to the end of the input. This is not treated as an error. A new SQL statement
        can begin on a line after a multiline comment ends. C comments can be embedded anywhere
        whitespace can occur, including inside expressions, and in the middle of
          other SQL
        statements. C comments do not nest. SQL comments inside a C comment will be ignored.
      </p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































Deleted Doc/Extra/lang_conflict.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>ON CONFLICT</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">ON CONFLICT clause</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        ON CONFLICT clause</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">conflict-clause</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ON CONFLICT </font></b><i><font color="#ff3434">conflict-algorithm</font></i><b><font
                color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">conflict-algorithm</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ROLLBACK </font></b><big>|</big><b><font color="#2c2cf0">
                ABORT </font></b><big>|</big><b><font color="#2c2cf0"> FAIL </font></b><big>|</big><b><font
                  color="#2c2cf0"> IGNORE </font></b><big>|</big><b><font color="#2c2cf0"> REPLACE</font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The ON CONFLICT clause is not a separate SQL command. It is a non-standard clause
        that can appear in many
          other SQL commands. It is given its own section in this
        document because it is not part of standard SQL and therefore might not be familiar.</p>
      <p>
        The syntax for the ON CONFLICT clause is as shown above for the CREATE TABLE command.
        For the INSERT and UPDATE commands, the keywords "ON CONFLICT" are replaced by "OR",
        to make the syntax seem more natural. For example, instead of "INSERT ON CONFLICT
        IGNORE" we have "INSERT OR IGNORE". The keywords change but the meaning of the clause
        is the same either way.</p>
      <p>
        The ON CONFLICT clause specifies an algorithm used to resolve constraint conflicts.
        There are five choices: ROLLBACK, ABORT, FAIL, IGNORE, and REPLACE. The default
        algorithm is ABORT. This is what they mean:</p>
      <dl>
        <dt><b>ROLLBACK</b> </dt>
        <dd>
          <p>
            When a constraint violation occurs, an immediate ROLLBACK occurs, thus ending the
            current transaction, and the command aborts with a return code of SQLITE_CONSTRAINT.
            If no transaction is active (other than the implied transaction that is created
            on every command) then this algorithm works the same as ABORT.</p>
        </dd>
        <dt><b>ABORT</b> </dt>
        <dd>
          <p>
            When a constraint violation occurs, the command backs out any prior changes it might
            have made and aborts with a return code of SQLITE_CONSTRAINT. But no ROLLBACK is
            executed so changes from prior commands within the same transaction are preserved.
            This is the default behavior.</p>
        </dd>
        <dt><b>FAIL</b> </dt>
        <dd>
          <p>
            When a constraint violation occurs, the command aborts with a return code SQLITE_CONSTRAINT.
            But any changes to the database that the command made prior to encountering the
            constraint violation are preserved and are not backed out. For example, if an UPDATE
            statement encountered a constraint violation on the 100th row that it attempts to
            update, then the first 99 row changes are preserved but changes to rows 100 and
            beyond never occur.</p>
        </dd>
        <dt><b>IGNORE</b> </dt>
        <dd>
          <p>
            When a constraint violation occurs, the one row that contains the constraint violation
            is not inserted or changed. But the command continues executing normally. Other
            rows before and after the row that contained the constraint violation continue to
            be inserted or updated normally. No error is returned.</p>
        </dd>
        <dt><b>REPLACE</b> </dt>
        <dd>
          <p>
            When a UNIQUE constraint violation occurs, the pre-existing rows that are causing
            the constraint violation are removed prior to inserting or updating the current
            row. Thus the insert or update always occurs. The command continues executing normally.
            No error is returned. If a NOT NULL constraint violation occurs, the NULL value
            is replaced by the default value for that column. If the column has no default value,
            then the ABORT algorithm is used. If a CHECK constraint violation occurs then the
            IGNORE algorithm is used.</p>
          <p>
            When this conflict resolution strategy deletes rows in order to satisfy a constraint,
            it does not invoke delete triggers on those rows. This behavior might change in
            a future release.</p>
        </dd>
      </dl>
      <p>
        The algorithm specified in the OR clause of a INSERT or UPDATE overrides any algorithm
        specified in a CREATE TABLE. If no algorithm is specified anywhere, the ABORT algorithm
        is used.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































Deleted Doc/Extra/lang_createindex.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>CREATE INDEX</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">CREATE INDEX</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        CREATE INDEX</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">CREATE </font></b>[<b><font color="#2c2cf0">UNIQUE</font></b>]<b><font
                color="#2c2cf0"> INDEX </font></b>[<b><font color="#2c2cf0">IF NOT EXISTS</font></b>]<b><font
                  color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                    color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">index-name</font></i><b><font color="#2c2cf0">
                <br />
                ON </font></b><i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0">
                  <big>(</big> </font></b><i><font color="#ff3434">column-name</font></i><b><font color="#2c2cf0">
                  </font></b>[<b><font color="#2c2cf0"><big>,</big> </font></b><i><font color="#ff3434">
                    column-name</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b><big>*</big><b><font
                      color="#2c2cf0"> <big>)</big></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">column-name</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">name</font></i><b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"> COLLATE </font></b><i><font
                  color="#ff3434">collation-name</font></i><b><font color="#2c2cf0"></font></b>]<b><font
                    color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"> ASC </font></b><big>|</big><b><font
                      color="#2c2cf0"> DESC </font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The CREATE INDEX command consists of the keywords "CREATE INDEX" followed by the
        name of the new index, the keyword "ON", the name of a previously created table
        that is to be indexed, and a parenthesized list of names of columns in the table
        that are used for the index key. Each column name can be followed by one of the
        "ASC" or "DESC" keywords to indicate sort order, but the sort order is ignored in
        the current implementation. Sorting is always done in ascending order.</p>
      <p>
        The COLLATE clause following each column name defines a collating sequence used
        for text entires in that column. The default collating sequence is the collating
        sequence defined for that column in the CREATE TABLE statement. Or if no collating
        sequence is otherwise defined, the built-in BINARY collating sequence is used.</p>
      <p>
        There are no arbitrary limits on the number of indices that can be attached to a
        single table, nor on the number of columns in an index.</p>
      <p>
        If the UNIQUE keyword appears between CREATE and INDEX then duplicate index entries
        are not allowed. Any attempt to insert a duplicate entry will result in an error.</p>
      <p>
        The exact text of each CREATE INDEX statement is stored in the <b>sqlite_master</b>
        or <b>sqlite_temp_master</b> table, depending on whether the table being indexed
        is temporary. Every time the database is opened, all CREATE INDEX statements are
        read from the <b>sqlite_master</b> table and used to regenerate
        SQLite's internal
        representation of the index layout.</p>
      <p>
        If the optional IF NOT EXISTS clause is present and another index with the same name aleady exists, then this command becomes a no-op.</p>
      <p>
        Indexes are removed with the <a href="lang_dropindex.html">DROP INDEX</a> command.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































Deleted Doc/Extra/lang_createtable.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>CREATE TABLE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">CREATE TABLE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        CREATE TABLE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-command</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">CREATE </font></b>[<b><font color="#2c2cf0">TEMP </font></b>
              <big>|</big><b><font color="#2c2cf0"> TEMPORARY</font></b>]<b><font color="#2c2cf0">
                TABLE </font></b>[<b><font color="#2c2cf0">IF NOT EXISTS</font></b>]<b><font color="#2c2cf0">
                </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                  color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0"> <big>(</big><br />
                &nbsp; &nbsp; </font></b><i><font color="#ff3434">column-def</font></i><b><font color="#2c2cf0">
                </font></b>[<b><font color="#2c2cf0"><big>,</big> </font></b><i><font color="#ff3434">
                  column-def</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b><big>*</big><b><font
                    color="#2c2cf0"><br />
                    &nbsp; &nbsp; </font></b>[<b><font color="#2c2cf0"><big>,</big> </font></b>
              <i><font color="#ff3434">constraint</font></i><b><font color="#2c2cf0"></font></b>]<b><font
                color="#2c2cf0"></font></b><big>*</big><b><font color="#2c2cf0"><br />
                  <big>)</big></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-command</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">CREATE </font></b>[<b><font color="#2c2cf0">TEMP </font></b>
              <big>|</big><b><font color="#2c2cf0"> TEMPORARY</font></b>]<b><font color="#2c2cf0">
                TABLE </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                  color="#2c2cf0"><big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0"> AS </font>
              </b><i><font color="#ff3434">select-statement</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">column-def</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">name</font></i><b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">type</font></i><b><font
                  color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b>[<b><font
                    color="#2c2cf0">CONSTRAINT </font></b><i><font color="#ff3434">name</font></i><b><font
                      color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"> </font></b><i><font color="#ff3434">
                        column-constraint</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b><big>*</big><b><font
                          color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">type</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">typename</font></i><b><font
                color="#2c2cf0"> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                </font></b><i><font color="#ff3434">typename</font></i><b><font color="#2c2cf0"> <big>
                  (</big> </font></b><i><font color="#ff3434">number</font></i><b><font color="#2c2cf0">
                    <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                    </font></b><i><font color="#ff3434">typename</font></i><b><font color="#2c2cf0"> <big>
                      (</big> </font></b><i><font color="#ff3434">number</font></i><b><font color="#2c2cf0">
                        <big>,</big> </font></b><i><font color="#ff3434">number</font></i><b><font color="#2c2cf0">
                          <big>)</big></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">column-constraint</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">NOT NULL </font></b>[<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">conflict-clause</font></i><b><font color="#2c2cf0"> </font>
              </b>]<b><font color="#2c2cf0"> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                PRIMARY KEY </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">sort-order</font></i><b><font
                  color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0">
                  </font></b><i><font color="#ff3434">conflict-clause</font></i><b><font color="#2c2cf0">
                  </font></b>]<b><font color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0">AUTOINCREMENT</font></b>]<b><font
                    color="#2c2cf0"> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                      UNIQUE </font></b>[<b><font color="#2c2cf0"> </font></b><i><font color="#ff3434">conflict-clause</font></i><b><font
                        color="#2c2cf0"> </font></b>]<b><font color="#2c2cf0"> </font></b><big>|</big><b><font
                          color="#2c2cf0"><br />
                          CHECK <big>(</big> </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0">
                            <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                              DEFAULT </font></b><i><font color="#ff3434">value</font></i><b><font color="#2c2cf0">
                              </font></b><big>|</big><b><font color="#2c2cf0"><br />
                                COLLATE </font></b><i><font color="#ff3434">collation-name</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">constraint</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">PRIMARY KEY <big>(</big> </font></b><i><font color="#ff3434">
                column-list</font></i><b><font color="#2c2cf0"> <big>)</big> </font></b>[<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">conflict-clause</font></i><b><font
                    color="#2c2cf0"> </font></b>]<b><font color="#2c2cf0"> </font></b><big>|</big><b><font
                      color="#2c2cf0"><br />
                      UNIQUE <big>(</big> </font></b><i><font color="#ff3434">column-list</font></i><b><font
                        color="#2c2cf0"> <big>)</big> </font></b>[<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">conflict-clause</font></i><b><font color="#2c2cf0"> </font>
              </b>]<b><font color="#2c2cf0"> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                CHECK <big>(</big> </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0">
                  <big>)</big></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">conflict-clause</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ON CONFLICT </font></b><i><font color="#ff3434">conflict-algorithm</font></i><b><font
                color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        A CREATE TABLE statement is basically the keywords "CREATE TABLE" followed by the
        name of a new table and a parenthesized list of column definitions and constraints.
        The table name can be either an identifier or a string. Tables names that begin
        with "<b>sqlite_</b>" are reserved for use by the engine.</p>
      <p>
        Each column definition is the name of the column followed by the datatype for that
        column, then one or more optional column constraints. The datatype for the column
        does not restrict what data may be put in that column. See <a href="http://www.sqlite.org/datatype3.html">
          Datatypes In SQLite Version 3</a> for additional information. The UNIQUE constraint
        causes an index to be created on the specified columns. This index must contain
        unique keys. The COLLATE clause specifies what text <a href="http://www.sqlite.org/datatype3.html#collation">
          collating function</a> to use when comparing text entries for the column. The
        built-in BINARY collating function is used by default.
      </p>
      <p>
        The DEFAULT constraint specifies a default value to use when doing an INSERT. The
        value may be NULL, a string constant or a number. Starting with version 3.1.0, the
        default value may also be one of the special case-independant keywords CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP. If the value is NULL, a string constant or number,
        it is literally inserted into the column whenever an INSERT statement that does
        not specify a value for the column is executed. If the value is CURRENT_TIME, CURRENT_DATE
        or CURRENT_TIMESTAMP, then the current UTC date and/or time is inserted into the
        columns. For CURRENT_TIME, the format is HH:MM:SS. For CURRENT_DATE, YYYY-MM-DD.
        The format for CURRENT_TIMESTAMP is "YYYY-MM-DD HH:MM:SS".
      </p>
      <p>
        Specifying a PRIMARY KEY normally just creates a UNIQUE index on the corresponding
        columns. However, if primary key is on a single column that has datatype INTEGER,
        then that column is used internally as the actual key of the B-Tree for the table.
        This means that the column may only hold unique integer values. (Except for this
        one case, SQLite ignores the datatype specification of columns and allows any kind
        of data to be put in a column regardless of its declared datatype.) If a table does
        not have an INTEGER PRIMARY KEY column, then the B-Tree key will be a automatically
        generated integer. The B-Tree key for a row can always be accessed using one of
        the special names "<b>ROWID</b>", "<b>OID</b>", or "<b>_ROWID_</b>". This is true
        regardless of whether or not there is an INTEGER PRIMARY KEY. An INTEGER PRIMARY
        KEY column man also include the keyword AUTOINCREMENT. The AUTOINCREMENT keyword
        modified the way that B-Tree keys are automatically generated. Additional detail
        on automatic B-Tree key generation is available <a href="http://www.sqlite.org/autoinc.html">
          separately</a>.</p>
      <p>
        If the "TEMP" or "TEMPORARY" keyword occurs in between "CREATE" and "TABLE" then
        the table that is created is only visible within that same database connection and
        is automatically deleted when the database connection is closed. Any indices created
        on a temporary table are also temporary. Temporary tables and indices are stored
        in a separate file distinct from the main database file.</p>
      <p>
        If a &lt;database-name&gt; is specified, then the table is created in the named
        database. It is an error to specify both a &lt;database-name&gt; and the TEMP keyword,
        unless the &lt;database-name&gt; is "temp". If no database name is specified, and
        the TEMP keyword is not present, the table is created in the main database.</p>
      <p>
        The optional conflict-clause following each constraint allows the specification
        of an alternative default constraint conflict resolution algorithm for that constraint. The default is abort ABORT. Different constraints within the same table may have
        different default conflict resolution algorithms. If an COPY, INSERT, or UPDATE
        command specifies a different conflict resolution algorithm, then that algorithm
        is used in place of the default algorithm specified in the CREATE TABLE statement.
        See the section titled <a href="lang_conflict.html">ON CONFLICT</a> for additional
        information.</p>
      <p>
        CHECK constraints are supported as of version 3.3.0. Prior to version 3.3.0, CHECK
        constraints were parsed but not enforced.</p>
      <p>
        There are no arbitrary limits on the number of columns or on the number of constraints
        in a table. The total amount of data in a single row is limited to about 1 megabytes
        in version 2.8. In version 3.0 there is no arbitrary limit on the amount of data
        in a row.</p>
      <p>
        The CREATE TABLE AS form defines the table to be the result set of a query. The
        names of the table columns are the names of the columns in the result.</p>
      <p>
        The exact text of each CREATE TABLE statement is stored in the <b>sqlite_master</b>
        table. Every time the database is opened, all CREATE TABLE statements are read from
        the <b>sqlite_master</b> table and used to regenerate
        SQLite's internal representation
        of the table layout. If the original command was a CREATE TABLE AS then then an
        equivalent CREATE TABLE statement is synthesized and store in <b>sqlite_master</b>
        in place of the original command. The text of CREATE TEMPORARY TABLE statements
        are stored in the <b>sqlite_temp_master</b> table.
      </p>
      <p>
        If the optional IF NOT EXISTS clause is present and another table with the same
        name aleady exists, then this command becomes a no-op.</p>
      <p>
        Tables are removed using the <a href="lang_droptable.html">DROP TABLE</a> statement.
      </p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































Deleted Doc/Extra/lang_createtrigger.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>CREATE TABLE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">CREATE TRIGGER</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        CREATE TRIGGER</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">CREATE </font></b>[<b><font color="#2c2cf0">TEMP </font></b>
              <big>|</big><b><font color="#2c2cf0"> TEMPORARY</font></b>]<b><font color="#2c2cf0">
                TRIGGER </font></b><i><font color="#ff3434">trigger-name</font></i><b><font color="#2c2cf0">
                </font></b>[<b><font color="#2c2cf0"> BEFORE </font></b><big>|</big><b><font color="#2c2cf0">
                  AFTER </font></b>]<b><font color="#2c2cf0"><br />
                  </font></b><i><font color="#ff3434">database-event</font></i><b><font color="#2c2cf0">
                    ON </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                      color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0"><br />
              </font></b><i><font color="#ff3434">trigger-action</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">CREATE </font></b>[<b><font color="#2c2cf0">TEMP </font></b>
              <big>|</big><b><font color="#2c2cf0"> TEMPORARY</font></b>]<b><font color="#2c2cf0">
                TRIGGER </font></b><i><font color="#ff3434">trigger-name</font></i><b><font color="#2c2cf0">
                  INSTEAD OF<br />
                </font></b><i><font color="#ff3434">database-event</font></i><b><font color="#2c2cf0">
                  ON </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                    color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">view-name</font></i><b><font color="#2c2cf0"><br />
              </font></b><i><font color="#ff3434">trigger-action</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">database-event</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">DELETE </font></b><big>|</big><b><font color="#2c2cf0">
                <br />
                INSERT </font></b><big>|</big><b><font color="#2c2cf0">
                  <br />
                  UPDATE </font></b><big>|</big><b><font color="#2c2cf0">
                    <br />
                    UPDATE OF </font></b><i><font color="#ff3434">column-list</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">trigger-action</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b>[<b><font color="#2c2cf0"> FOR EACH ROW </font>
              </b><big>|</big><b><font color="#2c2cf0"> FOR EACH STATEMENT </font></b>]<b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"> WHEN </font></b><i><font color="#ff3434">
                  expression</font></i><b><font color="#2c2cf0"> </font></b>]<b><font color="#2c2cf0">
                    <br />
                    BEGIN
                    <br />
                    &nbsp; &nbsp; </font></b><i><font color="#ff3434">trigger-step</font></i><b><font
                      color="#2c2cf0"> ; </font></b>[<b><font color="#2c2cf0"> </font></b><i><font color="#ff3434">
                        trigger-step</font></i><b><font color="#2c2cf0"> ; </font></b>]<b><font color="#2c2cf0"></font></b><big>*</big><b><font
                          color="#2c2cf0"><br />
                          END</font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">trigger-step</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">update-statement</font></i><b><font
                color="#2c2cf0"> </font></b><big>|</big><b><font color="#2c2cf0"> </font></b><i><font
                  color="#ff3434">insert-statement</font></i><b><font color="#2c2cf0"> </font></b>
              <big>|</big><b><font color="#2c2cf0">
                <br />
              </font></b><i><font color="#ff3434">delete-statement</font></i><b><font color="#2c2cf0">
              </font></b><big>|</big><b><font color="#2c2cf0"> </font></b><i><font color="#ff3434">
                select-statement</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The CREATE TRIGGER statement is used to add triggers to the database schema. Triggers
        are database operations (the <i>trigger-action</i>) that are automatically performed
        when a specified database event (the <i>database-event</i>) occurs.
      </p>
      <p>
        A trigger may be specified to fire whenever a DELETE, INSERT or UPDATE of a particular
        database table occurs, or whenever an UPDATE of one or more specified columns of
        a table are updated.</p>
      <p>
        At this time SQLite supports only FOR EACH ROW triggers, not FOR EACH STATEMENT
        triggers. Hence explicitly specifying FOR EACH ROW is optional. FOR EACH ROW implies
        that the SQL statements specified as <i>trigger-steps</i> may be executed (depending
        on the WHEN clause) for each database row being inserted, updated or deleted by
        the statement causing the trigger to fire.</p>
      <p>
        Both the WHEN clause and the <i>trigger-steps</i> may access elements of the row
        being inserted, deleted or updated using references of the form "NEW.<i>column-name</i>"
        and "OLD.<i>column-name</i>", where <i>column-name</i> is the name of a column from the table that the trigger is associated with. OLD and NEW references may only be
        used in triggers on <i>trigger-event</i>s for which they are relevant, as follows:</p>
      <p>
        <table border="0" cellpadding="10">
          <tr>
            <td align="right" valign="top" width="120">
              <i>INSERT</i></td>
            <td valign="top">
              NEW references are valid</td>
          </tr>
          <tr>
            <td align="right" valign="top" width="120">
              <i>UPDATE</i></td>
            <td valign="top">
              NEW and OLD references are valid</td>
          </tr>
          <tr>
            <td align="right" valign="top" width="120">
              <i>DELETE</i></td>
            <td valign="top">
              OLD references are valid</td>
          </tr>
        </table>
      </p>
      <p>
      </p>
      <p>
        If a WHEN clause is supplied, the SQL statements specified as <i>trigger-steps</i>
        are only executed for
        rows for which the WHEN clause is true. If no WHEN clause
        is supplied, the SQL statements are executed for all rows.</p>
      <p>
        The specified <i>trigger-time</i> determines when the <i>trigger-steps</i> will
        be executed relative to the insertion, modification or removal of the associated
        row.</p>
      <p>
        An ON CONFLICT clause may be specified as part of an UPDATE or INSERT <i>trigger-step</i>.
        However if an ON CONFLICT clause is specified as part of the statement causing the
        trigger to fire, then this conflict handling policy is used instead.</p>
      <p>
        Triggers are automatically dropped when the table that they are associated with
        is dropped.</p>
      <p>
        Triggers may be created on views, as well as ordinary tables, by specifying INSTEAD
        OF in the CREATE TRIGGER statement. If one or more ON INSERT, ON DELETE or ON UPDATE
        triggers are defined on a view, then it is not an error to execute an INSERT, DELETE
        or UPDATE statement on the view, respectively. Thereafter, executing an INSERT,
        DELETE or UPDATE on the view causes the associated triggers to fire. The real tables
        underlying the view are not modified (except possibly explicitly, by a trigger program).</p>
      <p>
        <b>Example:</b></p>
      <p>
        Assuming that customer records are stored in the "customers" table, and that order
        records are stored in the "orders" table, the following trigger ensures that all
        associated orders are redirected when a customer changes his or her address:</p>
      <blockquote>
        <pre>
CREATE TRIGGER update_customer_address UPDATE OF address ON customers 
  BEGIN
    UPDATE orders SET address = new.address WHERE customer_name = old.name;
  END;
</pre>
      </blockquote>
      <p>
        With this trigger installed, executing the statement:</p>
      <blockquote>
        <pre>
UPDATE customers SET address = '1 Main St.' WHERE name = 'Jack Jones';
</pre>
      </blockquote>
      <p>
        causes the following to be automatically executed:</p>
      <blockquote>
        <pre>
UPDATE orders SET address = '1 Main St.' WHERE customer_name = 'Jack Jones';
</pre>
      </blockquote>
      <p>
        Note that currently, triggers may behave oddly when created on tables with INTEGER
        PRIMARY KEY fields. If a BEFORE trigger program modifies the INTEGER PRIMARY KEY
        field of a row that will be subsequently updated by the statement that causes the
        trigger to fire, then the update may not occur. The workaround is to declare the
        table with a PRIMARY KEY column instead of an INTEGER PRIMARY KEY column.</p>
      <p>
        A special SQL function RAISE() may be used within a trigger-program, with the following
        syntax</p>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">raise-function</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">RAISE <big>(</big> ABORT<big>,</big> </font></b><i><font
                color="#ff3434">error-message</font></i><b><font color="#2c2cf0"> <big>)</big> </font>
                </b><big>|</big><b><font color="#2c2cf0">
                  <br />
                  RAISE <big>(</big> FAIL<big>,</big> </font></b><i><font color="#ff3434">error-message</font></i><b><font
                    color="#2c2cf0"> <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0">
                      <br />
                      RAISE <big>(</big> ROLLBACK<big>,</big> </font></b><i><font color="#ff3434">error-message</font></i><b><font
                        color="#2c2cf0"> <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0">
                          <br />
                          RAISE <big>(</big> IGNORE <big>)</big></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        When one of the first three forms is called during trigger-program execution, the
        specified ON CONFLICT processing is performed (either ABORT, FAIL or ROLLBACK) and
        the current query terminates. An error code of SQLITE_CONSTRAINT is returned to
        the user, along with the specified error message.</p>
      <p>
        When RAISE(IGNORE) is called, the remainder of the current trigger program, the
        statement that caused the trigger program to execute and any subsequent trigger
        programs that would of been executed are abandoned. No database changes are rolled
        back. If the statement that caused the trigger program to execute is itself part
        of a trigger program, then that trigger program resumes execution at the beginning
        of the next step.
      </p>
      <p>
        Triggers are removed using the <a href="lang_droptrigger.html">DROP TRIGGER</a>
        statement.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































Deleted Doc/Extra/lang_createview.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>CREATE VIEW</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">CREATE VIEW</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        CREATE VIEW</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-command</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">CREATE </font></b>[<b><font color="#2c2cf0">TEMP </font></b>
              <big>|</big><b><font color="#2c2cf0"> TEMPORARY</font></b>]<b><font color="#2c2cf0">
                VIEW </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                  color="#2c2cf0"><big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">view-name</font></i><b><font color="#2c2cf0"> AS </font></b>
              <i><font color="#ff3434">select-statement</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The CREATE VIEW command assigns a name to a pre-packaged <a href="lang_select.html">
          SELECT</a> statement. Once the view is created, it can be used in the FROM clause
        of another SELECT in place of a table name. 
      </p>
      <p>
        If the "TEMP" or "TEMPORARY" keyword occurs in between "CREATE" and "VIEW" then
        the view that is created is only visible to the process that opened the database
        and is automatically deleted when the database is closed.</p>
      <p>
        If a &lt;database-name&gt; is specified, then the view is created in the named database.
        It is an error to specify both a &lt;database-name&gt; and the TEMP keyword, unless
        the &lt;database-name&gt; is "temp". If no database name is specified, and the TEMP
        keyword is not present, the table is created in the main database.</p>
      <p>
        You cannot COPY, DELETE, INSERT or UPDATE a view. Views are read-only in SQLite.
        However, in many cases you can use a <a href="lang_createtrigger.html">TRIGGER</a>
        on the view to accomplish the same thing. Views are removed with the <a href="lang_dropview.html">
          DROP VIEW</a> command.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































Deleted Doc/Extra/lang_createvtab.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>CREATE VIRTUAL TABLE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">CREATE VIRTUAL TABLE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        CREATE VIRTUAL TABLE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-command</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">CREATE VIRTUAL TABLE </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">database-name</font></i><b><font color="#2c2cf0"> <big>.</big></font></b>]<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">table-name</font></i><b><font
                    color="#2c2cf0"> USING </font></b><i><font color="#ff3434">module-name</font></i><b><font
                      color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"><big>(</big> </font></b>
              <i><font color="#ff3434">arguments</font></i><b><font color="#2c2cf0"> <big>)</big></font></b>]<b><font
                color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        A virtual table is an interface to an external storage or computation engine that
        appears to be a table but does not actually store information in the database file.</p>
      <p>
        In general, you can do anything with a virtual table that can be done with an ordinary
        table, except that you cannot create triggers on a virtual table. Some virtual table
        implementations might impose additional restrictions. For example, many virtual
        tables are read-only.</p>
      <p>
        The &lt;module-name&gt; is the
        name of an object that implements the virtual table.
        The &lt;module-name&gt; must be registered with the SQLite database connection using
        <a href="capi3ref.html#sqlite3_create_module">sqlite3_create_module</a> prior to
        issuing the CREATE VIRTUAL TABLE statement. The module takes zero or more comma-separated
        arguments. The arguments can be just about any text as long as it has balanced parentheses.
        The argument syntax is sufficiently general that the arguments can be made to appear
        as column definitions in a traditional <a href="lang_createtable.html">CREATE TABLE</a>
        statement. SQLite passes the module arguments directly to the module without any
        interpretation. It is the responsibility of the module implementation to parse and
        interpret its own arguments.</p>
      <p>
        A virtual table is destroyed using the ordinary <a href="lang_droptable.html">DROP
          TABLE</a> statement. There is no DROP VIRTUAL TABLE statement.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































Deleted Doc/Extra/lang_datetime.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>DateTime Functions</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">Date and Time Functions</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">Date and Time Functions</h1>
<p>Five date and time functions are available, as follows:

<p><ol>
<li>date( <i>timestring</i>, <i>modifier</i>, <i>modifier</i>, ...)
<li>time( <i>timestring</i>, <i>modifier</i>, <i>modifier</i>, ...)
<li>datetime( <i>timestring</i>, <i>modifier</i>, <i>modifier</i>, ...)
<li>julianday( <i>timestring</i>, <i>modifier</i>, <i>modifier</i>, ...)
<li>strftime( <i>format</i>, <i>timestring</i>, <i>modifier</i>, <i>modifier</i>, ...)
</ol>

<p>All five functions take a time string as an argument.  This
time string may be followed by zero or more modifiers.  The
<b>strftime()</b> function also takes a format string as its first
argument.

<p>The <b>date()</b> function returns the date in this format: YYYY-MM-DD.
The <b>time()</b> function returns the time as HH:MM:SS.  The <b>datetime()</b>
function returns &quot;YYYY-MM-DD HH:MM:SS&quot;.  The <b>julianday()</b> function
returns the number of days since noon in Greenwich on November 24, 4714 B.C.
The julian day number is the preferred internal representation of
dates.  The <b>strftime()</b> routine returns the date formatted according
to the format string specified as the first argument.  The format string
supports most, but not all, of the more common substitutions found in
the strftime() function from the standard C library:

<p><pre>
   %d  day of month
   %f  ** fractional seconds  SS.SSS
   %H  hour 00-24
   %j  day of year 001-366
   %J  ** Julian day number
   %m  month 01-12
   %M  minute 00-59
   %s  seconds since 1970-01-01
   %S  seconds 00-59
   %w  day of week 0-6  sunday==0
   %W  week of year 00-53
   %Y  year 0000-9999
   %%  %
</pre>

<p>The %f and %J conversions are new.  Notice that all of the other four
functions could be expressed in terms of <b>strftime()</b>.

<p><pre>
   date(...)      -&gt;  strftime(&quot;%Y-%m-%d&quot;, ...)
   time(...)      -&gt;  strftime(&quot;%H:%M:%S&quot;, ...)
   datetime(...)  -&gt;  strftime(&quot;%Y-%m-%d %H:%M:%S&quot;, ...)
   julianday(...) -&gt;  strftime(&quot;%J&quot;, ...)
</pre>

<p>The only reasons for providing functions other than <b>strftime()</b> is for
convenience and for efficiency.

<p><b>Time Strings</b>

<p>A time string can be in any of the following formats:

<p><ol>
<li>YYYY-MM-DD
<li>YYYY-MM-DD HH:MM
<li>YYYY-MM-DD HH:MM:SS
<li>YYYY-MM-DD HH:MM:SS.SSS
<li>YYYY-MM-DDTHH:MM
<li>YYYY-MM-DDTHH:MM:SS
<li>YYYY-MM-DDTHH:MM:SS.SSS
<li>HH:MM
<li>HH:MM:SS
<li>HH:MM:SS.SSS
<li>now
<li>DDDD.DDDD
</ol>

<p>In formats 5 through 7, the &quot;T&quot; is a literal character separating the date and the time, as required by the ISO-8601 standard. These formats are supported in SQLite 3.2.0 and later.
Formats 8 through 10 that specify only a time assume a date of 2000-01-01.
Format 11, the string 'now', is converted into the current date and time.
Universal Coordinated Time (UTC) is used.
Format 12 is the julian day number expressed as a floating point value.

<p><b>Modifiers</b>

<p>The time string can be followed by zero or more modifiers that alter the
date or alter the interpretation of the date.  The available modifiers
are as follows.

<p><ol>
<li>NNN days
<li>NNN hours
<li>NNN minutes
<li>NNN.NNNN seconds
<li>NNN months  (see <a href="tktview?tn=551">#551</a>
 and <a href="chngview?cn=1163">[1163]</a>
)
<li>NNN years  (see <a href="tktview?tn=551">#551</a>
 and <a href="chngview?cn=1163">[1163]</a>
)
<li>start of month
<li>start of year
<li>start of week  (withdrawn -- will not be implemented)
<li>start of day
<li>weekday N  (see <a href="tktview?tn=551">#551</a>
 and <a href="chngview?cn=1163">[1163]</a>
)
<li>unixepoch
<li>localtime
<li>utc
</ol>

<p>The first six modifiers (1 through 6) simply add the specified amount
of time to the date specified by the preceding timestring.

<p>The &quot;start of&quot; modifiers (7 through 10) shift the date backwards to
the beginning of the current month, year or day.

<p>The &quot;weekday&quot; modifier advances the date forward to the next date where
the weekday number is N.  Sunday is 0, Monday is 1, and so forth.

<p>The &quot;unixepoch&quot; modifier (12) only works if it immediately follows
a timestring in the DDDDDDDDDD format.  This modifier causes the DDDDDDDDDD
to be interpreted not as a julian day number as it normally would be, but
as the number of seconds since 1970.  This modifier allows unix-based times
to be converted to julian day numbers easily.

<p>The &quot;localtime&quot; modifier (13) adjusts the previous time string so that it
displays the correct local time.  &quot;utc&quot; undoes this.

<p><b>Examples</b>

<p>Compute the current date.

<p><pre>
  SELECT date('now');
</pre>

<p>Compute the last day of the current month.

<p><pre>
  SELECT date('now','start of month','+1 month','-1 day');
</pre>

<p>Compute the date and time given a unix timestamp 1092941466.

<p><pre>
  SELECT datetime(1092941466, 'unixepoch');
</pre>

<p>Compute the date and time given a unix timestamp 1092941466, and compensate for your local timezone.

<p><pre>
  SELECT datetime(1092941466, 'unixepoch', 'localtime');
</pre>

<p>Compute the current unix timestamp.

<p><pre>
  SELECT strftime('%s','now');
</pre>

<p>Compute the number of days since the battle of Hastings.

<p><pre>
  SELECT julianday('now') - julianday('1066-10-14','gregorian');
</pre>

<p>Compute the number of seconds between two dates:

<p><pre>
  SELECT julianday('now')*86400 - julianday('2004-01-01 02:34:56')*86400;
</pre>

<p>Compute the date of the first Tuesday in October (January + 9) for the current
year.

<p><pre>
  SELECT date('now','start of year','+9 months','weekday 2');
</pre>

<p><b>Caveats And Bugs</b>

<p>The computation of local time depends heavily on the whim of local
politicians and is thus difficult to get correct for all locales.  In
this implementation, the standard C library function localtime() is
used to assist in the calculation of local time.
Note that localtime() is not
threadsafe, so use of the &quot;localtime&quot; modifier is not threadsafe.
Also, the localtime() C function normally only works for years between
1970 and 2037.  For dates outside this range, SQLite attempts to
map the year into an equivalent year within this range, do the
calculation, then map the year back.

<p><i>Please surround uses of localtime() with sqliteOsEnterMutex() and sqliteOsLeaveMutex() so threads
using SQLite are protected, at least!
-- e</i>  It is so. --drh

<p><i>[Consider instead, using localtime_r which is reentrant and may be used
*without* expensive mutex locking. Although non-standard it's available
on most Unixes --hauk]</i> But it is not available on windows, as far as I
am aware. --drh On windows localtime() is thread-safe if the MT C runtime is used. The MT runtime uses thread-local storage for the static variables, the kind functions use.--gr <i>[What about using localtime_r, and on systems where it
is unavailable defining it as sqliteOsEnterMutext() ; locatime() ; sqliteOsLeaveMutex()
so that non-windows systems get the maximum advantage, with almost zero
code impact?]</i> The autoconfigury and patch for localtime_r is here: <font color="#a0a0a0">&curren;</font><a href="http://www.sqlite.org/cvstrac/tktview?tn=1906">http://www.sqlite.org/cvstrac/tktview?tn=1906</a> . I'm curious why this obvious fix is not applied. gmtime() also suffers from this same threadsafety problem.

<p>Date computations do not give correct results for dates before Julian
day number 0 (-4713-11-24 12:00:00).

<p>All internal computations assume the Gregorian calendar system.

<p><hr>
<i>An anonymous user adds:</i> <br>

For my use I added new functions and functionalities to the date functions that
come with the sqlite 3.3.0 (can be used in older versions as well with small effort).

<p>In main lines they are as follows:

<p><ol>
<li>NNN days
<li>NNN hours
<li>NNN minutes
<li>NNN.NNNN seconds
<li>NNN months  (see <a href="tktview?tn=551">#551</a>
 and <a href="chngview?cn=1163">[1163]</a>
)
<li>NNN years  (see <a href="tktview?tn=551">#551</a>
 and <a href="chngview?cn=1163">[1163]</a>
)
<li>start of month
<li>start of year
<li>start of week  (!!! implemented)
<li>start of day
<li>weekday N  (see <a href="tktview?tn=551">#551</a>
 and <a href="chngview?cn=1163">[1163]</a>
)
<li>unixepoch
<li>localtime
<li>utc
<li>julian  (not implemented as of 2004-01-05)
<li>gregorian  (not implemented as of 2004-01-05)
<li>start of minute
<li>start of hour
<li>end of minute
<li>end of hour
<li>end of day
<li>end of week
<li>end of month
<li>end of year
<li>group seconds by
<li>group minutes by
<li>group hours by
<li>group days by
<li>group weeks by
<li>group months by
<li>group years by
</ol>

<p>The &quot;start of&quot; modifiers (7 through 10 and 17 through 18) shift the date backwards to the beginning of the current minute, hour, week, month, year or day.

<p>The &quot;end of&quot; modifiers (19 through 24) shift the date forwards to
the end of the current minute, hour, week, month, year or day.

<p>The &quot;group * by&quot; modifiers (25 through 31) round the date to the closest backward multiple supplied, with some limitations, to the current seconds (1 through 30), minutes (1 through 30), hours (1 through 12), days (1 through 15), weeks (1 through 26), months (1 through 6), years (1 through 100), these limitations are due to dont complicate the calculations when a multiple can span beyound the unit modified.

<p>Ex:

<p>SELECT datetime('2006-02-04 20:09:23','group hours by 3'); =&gt; '2006-02-04 18:00:00'

<p>SELECT datetime('2006-02-05 20:09:23','group days by 3'); =&gt; '2006-02-04 00:00:00'

<p>New functions &quot;week_number(date)&quot; returns the week number of the year on the supplied date parameter, &quot;datetime2seconds(datetime)&quot; return the number of seconds from the supplied datetime parameter.
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































Deleted Doc/Extra/lang_delete.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>DELETE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">DELETE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        DELETE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">DELETE FROM </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">database-name</font></i><b><font color="#2c2cf0"> <big>.</big></font></b>]<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">table-name</font></i><b><font
                    color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0">WHERE </font></b><i><font color="#ff3434">
                      expr</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The DELETE command is used to remove records from a table. The command consists
        of the "DELETE FROM" keywords followed by the
        name of the table from which records
        are to be removed.
      </p>
      <p>
        Without a WHERE clause, all rows of the table are removed. If a WHERE clause is
        supplied, then only those rows that match the expression are removed.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted Doc/Extra/lang_detach.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>DETACH</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">DETACH</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        DETACH</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-command</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">DETACH </font></b>[<b><font color="#2c2cf0">DATABASE</font></b>]<b><font
                color="#2c2cf0"> </font></b><i><font color="#ff3434">database-name</font></i><b><font
                  color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        This statement detaches an additional database connection previously attached using
        the <a href="lang_attach.html">ATTACH DATABASE</a> statement. It is possible to have the same database file attached multiple times using different names, and detaching
        one connection to a file will leave the others intact.</p>
      <p>
        This statement will fail if SQLite is in the middle of a transaction.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































Deleted Doc/Extra/lang_dropindex.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>DROP INDEX</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">DROP INDEX</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        DROP INDEX</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-command</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">DROP INDEX </font></b>[<b><font color="#2c2cf0">IF EXISTS</font></b>]<b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                  color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">index-name</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The DROP INDEX statement removes an index added with the <a href="lang_createindex.html">
          CREATE INDEX</a> statement. The index named is completely removed from the disk.
        The only way to recover the index is to reenter the appropriate CREATE INDEX command.</p>
      <p>
        The DROP INDEX statement does not reduce the size of the database file in the default
        mode. Empty space in the database is retained for later INSERTs. To remove free
        space in the database, use the <a href="lang_vacuum.html">
          VACUUM</a> command. If
        AUTOVACUUM mode is enabled for a database then space will be freed automatically by DROP INDEX.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted Doc/Extra/lang_droptable.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>DROP TABLE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">DROP TABLE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        DROP TABLE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-command</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">DROP TABLE </font></b>[<b><font color="#2c2cf0">IF EXISTS</font></b>]<b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                  color="#2c2cf0"><big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The DROP TABLE statement removes a table added with the <a href="#createtable">CREATE TABLE</a> statement. The
        name specified is the table name. It is completely removed
        from the database schema and the disk file. The table can not be recovered. All
        indices associated with the table are also deleted.</p>
      <p>
        The DROP TABLE statement does not reduce the size of the database file in the default
        mode. Empty space in the database is retained for later INSERTs. To remove free
        space in the database, use the <a href="lang_vacuum.html">
          VACUUM</a> command. If
        AUTOVACUUM mode is enabled for a database then space will be freed automatically by DROP TABLE.</p>
      <p>
        The optional IF EXISTS clause suppresses the error that would normally result if the table does not exist.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































Deleted Doc/Extra/lang_droptrigger.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>DROP TRIGGER</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">DROP TRIGGER</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        DROP TRIGGER</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">DROP TRIGGER </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">database-name</font></i><b><font color="#2c2cf0"> <big>.</big></font></b>]<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">trigger-name</font></i><b><font
                    color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The DROP TRIGGER statement removes a trigger created by the <a href="lang_createtrigger.html">
          CREATE TRIGGER</a> statement. The trigger is deleted from the database schema.
        Note that triggers are automatically dropped when the associated table is dropped.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































Deleted Doc/Extra/lang_dropview.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>DROP VIEW</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">DROP VIEW</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        DROP VIEW</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-command</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">DROP VIEW </font></b><i><font color="#ff3434">view-name</font></i><b><font
                color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The DROP VIEW statement removes a view created by the <a href="#createview">CREATE VIEW</a> statement. The
        name specified is the view name. It is removed from the
        database schema, but no actual data
        in the underlying base tables is modified.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































Deleted Doc/Extra/lang_explain.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>EXPLAIN</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">EXPLAIN</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        EXPLAIN</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">EXPLAIN </font></b><i><font color="#ff3434">sql-statement</font></i><b><font
                color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The EXPLAIN command modifier is a non-standard extension. The idea comes from a similar command found in PostgreSQL, but the operation is completely different.</p>
      <p>
        If the EXPLAIN keyword appears before any
          other SQLite SQL command then instead
        of actually executing the command, the SQLite library will report back the sequence
        of virtual machine instructions it would have used to execute the command had the
        EXPLAIN keyword not been present. For additional information about virtual machine
        instructions see the <a href="http://www.sqlite.org/arch.html">architecture description</a>
        or the documentation on <a href="http://www.sqlite.org/opcode.html">available opcodes</a>
        for the virtual machine.</p>
      <p>
        &nbsp;</p>
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































Deleted Doc/Extra/lang_expr.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>expression</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
    <style type="text/css">
      .style1
      {
        height: 70px;
      }
    </style>
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">expression</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        expression</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">expr</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">expr</font></i><b><font
                color="#2c2cf0"> </font></b><i><font color="#ff3434">binary-op</font></i><b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0">
                  </font></b><big>|</big><b><font color="#2c2cf0"><br />
                  </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font>
                  </b>[<b><font color="#2c2cf0">NOT</font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">like-op</font></i><b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font></b>[<b><font
                color="#2c2cf0">ESCAPE </font></b><i><font color="#ff3434">expr</font></i><b><font
                  color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"> </font></b><big>|</big><b><font
                    color="#2c2cf0"><br />
                  </font></b><i><font color="#ff3434">unary-op</font></i><b><font color="#2c2cf0"> </font>
                  </b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font></b>
              <big>|</big><b><font color="#2c2cf0"><br />
                <big>(</big> </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0">
                  <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                  </font></b><i><font color="#ff3434">column-name</font></i><b><font color="#2c2cf0">
                  </font></b><big>|</big><b><font color="#2c2cf0"><br />
                  </font></b><i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0">
                    <big>.</big> </font></b><i><font color="#ff3434">column-name</font></i><b><font color="#2c2cf0">
                    </font></b><big>|</big><b><font color="#2c2cf0"><br />
                    </font></b><i><font color="#ff3434">database-name</font></i><b><font color="#2c2cf0">
                      <big>.</big> </font></b><i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0">
                        <big>.</big> </font></b><i><font color="#ff3434">column-name</font></i><b><font color="#2c2cf0">
                        </font></b><big>|</big><b><font color="#2c2cf0"><br />
                        </font></b><i><font color="#ff3434">literal-value</font></i><b><font color="#2c2cf0">
                        </font></b><big>|</big><b><font color="#2c2cf0"><br />
                        </font></b><i><font color="#ff3434">parameter</font></i><b><font color="#2c2cf0">
                        </font></b><big>|</big><b><font color="#2c2cf0"><br />
                        </font></b><i><font color="#ff3434">function-name</font></i><b><font color="#2c2cf0">
                          <big>(</big> </font></b><i><font color="#ff3434">expr-list</font></i><b><font color="#2c2cf0">
                          </font></b><big>|</big><b><font color="#2c2cf0"> <big>*</big> <big>)</big> </font>
                          </b><big>|</big><b><font color="#2c2cf0"><br />
                          </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> ISNULL
                          </font></b><big>|</big><b><font color="#2c2cf0"><br />
                          </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> NOTNULL
                          </font></b><big>|</big><b><font color="#2c2cf0"><br />
                          </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font>
                          </b>[<b><font color="#2c2cf0">NOT</font></b>]<b><font color="#2c2cf0"> BETWEEN </font>
                          </b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> AND </font></b>
              <i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font></b><big>
                |</big><b><font color="#2c2cf0"><br />
                </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font>
                </b>[<b><font color="#2c2cf0">NOT</font></b>]<b><font color="#2c2cf0"> IN <big>(</big>
                </font></b><i><font color="#ff3434">value-list</font></i><b><font color="#2c2cf0">
                  <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                  </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font>
                  </b>[<b><font color="#2c2cf0">NOT</font></b>]<b><font color="#2c2cf0"> IN <big>(</big>
                  </font></b><i><font color="#ff3434">select-statement</font></i><b><font color="#2c2cf0">
                    <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                    </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font>
                    </b>[<b><font color="#2c2cf0">NOT</font></b>]<b><font color="#2c2cf0"> IN </font></b>
              [<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0"> </font></b>
              <big>|</big><b><font color="#2c2cf0"><br />
              </font></b>[<b><font color="#2c2cf0">EXISTS</font></b>]<b><font color="#2c2cf0"> <big>
                (</big> </font></b><i><font color="#ff3434">select-statement</font></i><b><font color="#2c2cf0">
                  <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                    CASE </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">expr</font></i><b><font
                      color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"> </font></b>(<b><font color="#2c2cf0">
                        WHEN </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0">
                          THEN </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0">
                          </font></b>)+<b><font color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0">ELSE </font>
                          </b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"></font></b>]<b><font
                            color="#2c2cf0"> END </font></b><big>|</big><b><font color="#2c2cf0"><br />
                              CAST <big>(</big> </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0">
                                AS </font></b><i><font color="#ff3434">type</font></i><b><font color="#2c2cf0"> <big>
                                  )</big></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">like-op</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">LIKE </font></b><big>|</big><b><font color="#2c2cf0"> GLOB
              </font></b><big>|</big><b><font color="#2c2cf0"> REGEXP </font></b><big>|</big><b><font
                color="#2c2cf0"> MATCH</font></b></td>
          </tr>
        </table>
      </p>
      <p>
        This section is different from the others. Most other sections of this document
        talks about a particular SQL command. This section does not talk about a standalone
        command but about "expressions" which are subcomponents of most other commands.</p>
      <p>
        SQLite understands the following binary operators, in order from highest to lowest
        precedence:</p>
      <blockquote>
        <pre><font color="#2c2cf0"><big>|| * / % + - &lt;&lt; &gt;&gt; &amp; | &lt; &lt;= &gt;
  &gt;= = == != &lt;&gt; </big>IN AND OR</font>
</pre>
      </blockquote>
      <p>
        Supported unary operators are these:</p>
      <blockquote>
        <pre><font color="#2c2cf0"><big>- + ! ~ NOT</big></font>
</pre>
      </blockquote>
      <p>
        The unary operator [Operator +] is a no-op. It can be applied to strings, numbers,
        or blobs and it always gives as its result the value of the operand.</p>
      <p>
        Note that there are two variations of the equals and not equals operators. Equals
        can be either <font color="#2c2cf0"><big>=</big></font> or <font color="#2c2cf0"><big>
          ==</big></font>. The non-equals operator can be either <font color="#2c2cf0"><big>
            !=</big></font> or <font color="#2c2cf0"><big>&lt;&gt;</big></font>. The <font color="#2c2cf0">
              <big>||</big></font> operator is "concatenate" - it joins together the two
        strings of its operands. The operator <font color="#2c2cf0"><big>%</big></font>
        outputs the remainder of its left operand modulo its right operand.</p>
      <p>
        The result of any binary operator is a numeric value, except for the <font color="#2c2cf0">
          <big>||</big></font> concatenation operator which gives a string result.</p>
      <a name="literal_value"></a>
      <p>
        A literal value is an integer number or a floating point number. Scientific notation
        is supported. The "." character is always used as the decimal point even if the
        locale setting specifies "," for this role - the use of "," for the decimal point
        would result in syntactic ambiguity. A string constant is formed by enclosing the
        string in single quotes ('). A single quote within the string can be encoded by
        putting two single quotes in a row - as in Pascal. C-style escapes using the backslash
        character are not supported because they are not standard SQL. BLOB literals are
        string literals containing hexadecimal data and preceded by a single "x" or "X"
        character. For example:</p>
      <blockquote>
        <pre>X'53514697465'
</pre>
      </blockquote>
      <p>
        A literal value can also be the token "NULL".
      </p>
      <p>
        A parameter specifies a placeholder in the expression for a literal value that is
        filled in at runtime using the <a href="capi3ref.html#sqlite3_bind_int">sqlite3_bind</a>
        API. Parameters can take several forms:
      </p>
      <p>
        <table>
          <tr>
            <td align="right" width="1%" nowrap>
              <b>?</b><i>NNN</i></td>
            <td width="20">
            </td>
            <td>
              A question mark followed by a number <i>NNN</i> holds a spot for the NNN-th parameter.
              NNN must be between 1 and 999.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <b>?</b></td>
            <td width="20">
            </td>
            <td>
              A question mark that is not followed by a number holds a spot for the next unused
              parameter.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <b>:</b><i>AAAA</i></td>
            <td width="20">
            </td>
            <td>
              A colon followed by an identifier name holds a spot for a named parameter with the
              name AAAA. Named parameters are also numbered. The number assigned is the next unused
              number. To avoid confusion, it is best to avoid mixing named and numbered parameters.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <b>@</b><i>AAAA</i></td>
            <td width="20">
            </td>
            <td>
              An "at" sign works exactly like a colon.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <b>$</b><i>AAAA</i></td>
            <td width="20">
            </td>
            <td>
              A dollar-sign followed by an identifier name also holds a spot for a named parameter
              with the name AAAA. The identifier name in this case can include one or more occurances
              of "::" and a suffix enclosed in "(...)" containing any text at all. This syntax
              is the form of a variable name in the Tcl programming language.</td>
          </tr>
        </table>
      </p>
      <blockquote>
      </blockquote>
      <p>
        Parameters that are not assigned values using <a href="capi3ref.html#sqlite3_bind_int">
          sqlite3_bind</a> are treated as NULL.</p>
      <a name="like"></a>
      <p>
        The LIKE operator does a pattern matching comparison. The operand to the right contains
        the pattern, the left hand operand contains the string to match against the pattern.
        A percent symbol <font color="#2c2cf0"><big>%</big></font> in the pattern matches
        any sequence of zero or more characters in the string. An underscore <font color="#2c2cf0">
          <big>_</big></font> in the pattern matches any single character in the string.
        Any other character matches itself or it's lower/upper case equivalent (i.e. case-insensitive
        matching). (A bug: SQLite only understands upper/lower case for 7-bit Latin characters.
        Hence the LIKE operator is case sensitive for 8-bit iso8859 characters or UTF-8
        characters. For example, the expression <b>'a' LIKE 'A'</b> is TRUE but <b>'æ' LIKE
          'Æ'</b> is FALSE.).</p>
      <p>
        If the optional ESCAPE clause is present, then the expression following the ESCAPE
        keyword must evaluate to a string consisting of a single character. This character
        may be used in the LIKE pattern to include literal percent or underscore characters.
        The escape character followed by a percent symbol, underscore or itself matches
        a literal percent symbol, underscore or escape character in the string, respectively.
        The infix LIKE operator is implemented by calling the user function <a href="#likeFunc">
          like(<i>X</i>,<i>Y</i>)</a>.</p>
      <p>
        The LIKE operator is not case sensitive and will match upper case characters on
        one side against lower case characters on the other. (A bug: SQLite only understands
        upper/lower case for 7-bit Latin characters. Hence the LIKE operator is case sensitive
        for 8-bit iso8859 characters or UTF-8 characters. For example, the expression <b>'a'
          LIKE 'A'</b> is TRUE but <b>'æ' LIKE 'Æ'</b> is FALSE.).
      </p>
      <p>
      </p>
      <p>
        The infix LIKE operator is implemented by calling the user function <a href="#likeFunc">
          like(<i>X</i>,<i>Y</i>)</a>. If an ESCAPE clause is present, it adds a third parameter
        to the function call. If the functionality of LIKE can be overridden by defining
        an alternative implementation of the like() SQL function.</p>
      <p>
      </p>
      <a name="glob"></a>
      <p>
        The GLOB operator is similar to LIKE but uses the Unix file globbing syntax for
        its wildcards. Also, GLOB is case sensitive, unlike LIKE. Both GLOB and LIKE may
        be preceded by the NOT keyword to invert the sense of the test. The infix GLOB operator
        is implemented by calling the user function <a href="#globFunc">glob(<i>X</i>,<i>Y</i>)</a>
        and can be modified by overriding that function.</p>
      <a name="regexp"></a>
      <p>
        The REGEXP operator is a special syntax for the regexp() user function. No regexp()
        user function is defined by default and so use of the REGEXP operator will normally
        result in an error message. If a user-defined function named "regexp" is added at
        run-time, that function will be called in order to implement the REGEXP operator.</p>
      <a name="match"></a>
      <p>
        The MATCH operator is a special syntax for the match() user function. The default
        match() function implementation raises and exception and is not really useful for
        anything. But extensions can override the match() function with more helpful logic.</p>
      <p>
        A column name can be any of the names defined in the CREATE TABLE statement or one
        of the following special identifiers: "<b>ROWID</b>", "<b>OID</b>", or "<b>_ROWID_</b>".
        These special identifiers all describe the unique random integer key (the "row key")
        associated with every row of every table. The special identifiers only refer to
        the row key if the CREATE TABLE statement does not define a real column with the
        same name. Row keys act like read-only columns. A row key can be used anywhere a
        regular column can be used, except that you cannot change the value of a row key
        in an UPDATE or INSERT statement. "SELECT * ..." does not return the row key.</p>
      <p>
        SELECT statements can appear in expressions as either the right-hand operand of
        the IN operator, as a scalar quantity, or as the operand of an EXISTS operator.
        As a scalar quantity or the operand of an IN operator, the SELECT should have only
        a single column in its result. Compound SELECTs (connected with keywords like UNION
        or EXCEPT) are allowed. With the EXISTS operator, the columns in the result set
        of the SELECT are ignored and the expression returns TRUE if one or more rows exist
        and FALSE if the result set is empty. If no terms in the SELECT expression refer
        to value in the containing query, then the expression is evaluated once prior to
        any other processing and the result is reused as necessary. If the SELECT expression
        does contain variables from the outer query, then the SELECT is reevaluated every
        time it is needed.</p>
      <p>
        When a SELECT is the right operand of the IN operator, the IN operator returns TRUE
        if the result of the left operand is any of the values generated by the select.
        The IN operator may be preceded by the NOT keyword to invert the sense of the test.</p>
      <p>
        When a SELECT appears within an expression but is not the right operand of an IN
        operator, then the first row of the result of the SELECT becomes the value used
        in the expression. If the SELECT yields more than one result row, all rows after the first are ignored. If the SELECT yields no rows, then the value of the SELECT
        is NULL.</p>
      <p>
        A CAST expression changes the datatype of the
        <expr>
</expr>
        into the type specified by &lt;type&gt;. &lt;type&gt; can be any non-empty type
        name that is valid for the type in a column definition of a CREATE TABLE statement.</p>
      <p>
        Both simple and aggregate functions are supported. A simple function can be used
        in any expression. Simple functions return a result immediately based on their inputs.
        Aggregate functions may only be used in a SELECT statement. Aggregate functions
        compute their result across all rows of the result set.</p>
      <p>
        <a name="corefunctions"></a><b>Core Functions</b>
      </p>
      <p>
        The core functions shown below are available by default. Additional functions may
        be written in C and added to the database engine using the <a href="capi3ref.html#cfunc">
          sqlite3_create_function()</a> API.</p>
      <p>
        <table border="0" cellpadding="10">
          <tr>
            <td align="right" valign="top" width="1%" nowrap>
              abs(<i>X</i>)</td>
            <td valign="top">
              Return the absolute value of argument <i>X</i>.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              acos(<i>X</i>)</td>
            <td valign="top">
              A mathematical function that returns the angle, in radians, whose cosine is the 
              specified <b>double</b> expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              acosh(<i>X</i>)</td>
            <td valign="top">
              Inverse hyperbolic cosine</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              asin(<i>X</i>)</td>
            <td valign="top">
              Returns the angle, in radians, whose sine is the specified <b>double</b> 
              expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              asinh(<i>X</i>)</td>
            <td valign="top">
              Inverse hyperbolic sine</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              atan(<i>X</i>)</td>
            <td valign="top">
              Returns the angle in radians whose tangent is a specified <b>double</b> 
              expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              atanh(<i>X</i>)</td>
            <td valign="top">
              Inverse hyperbolic tangent</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap class="style1">
              atn2(<i>X</i>,<i>Y</i>)<br />
              atan2(<i>X</i>,<i>Y</i>)</td>
            <td valign="top" class="style1">
              Returns the angle, in radians, between the positive x-axis and the ray from the 
              origin to the point (y, x), where x and y are the values of the two specified 
              double expressions</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              ceil(<i>X</i>)<br />
              ceiling(<i>X</i>)</td>
            <td valign="top">
              Returns the smallest integer greater than, or equal to, the specified numeric 
              expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              charindex(<i>X</i>,<i>Y</i>[,<i>Z</i>])</td>
            <td valign="top">
              Returns the 1-based position of the string <i>X</i> inside the string <i>Y</i> 
              starting at position <i>Z</i>.&nbsp; Returns 0 if not <i>X</i> is not found 
              within <i>Y</i>.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              coalesce(<i>X</i>,<i>Y</i>,...)</td>
            <td valign="top">
              Return a copy of the first non-NULL argument. If all arguments are NULL then NULL
              is returned. There must be at least 2 arguments.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              cos(<i>X</i>)</td>
            <td valign="top">
              a mathematical function that returns the trigonometric cosine of the specified 
              angle, in radians, in the specified expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              cosh(<i>X</i>)</td>
            <td valign="top">
              Hyperbolic cosine</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              cot(<i>X</i>)</td>
            <td valign="top">
              A mathematical function that returns the trigonometric cotangent of the 
              specified angle, in radians, in the specified <b>double</b> expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              coth(<i>X</i>)</td>
            <td valign="top">
              <span class="h1purpose">Hyperbolic cotangent</span></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              difference(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Returns an integer value that indicates the difference between the SOUNDEX 
              values of two character expressions</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              degrees(<i>X</i>)</td>
            <td valign="top">
              Converts radians to degrees</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              exp(<i>X</i>)</td>
            <td valign="top">
              Returns the exponential value of the specified expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              floor(<i>X</i>)</td>
            <td valign="top">
              Returns the largest integer less than or equal to the specified numeric 
              expression</td>
          </tr>
          <tr>
            <a name="globFunc"></a>
            <td align="right" width="1%" nowrap>
              glob(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              This function is used to implement the "<b>X GLOB Y</b>" syntax of SQLite. The <a
                href="capi3ref.html#sqlite3_create_function">sqlite3_create_function()</a> interface
              can be used to override this function and thereby change the operation of the <a
                href="#globFunc">GLOB</a> operator.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              ifnull(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Return a copy of the first non-NULL argument. If both arguments are NULL then NULL
              is returned. This behaves the same as <b>coalesce()</b> above.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              last_insert_rowid()</td>
            <td valign="top">
              Return the ROWID of the last row insert from this connection to the database. This
              is the same value that would be returned from the <b>sqlite_last_insert_rowid()</b>
              API function.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              last_rows_affected()</td>
            <td valign="top">
              Returns the number of rows affected by the last insert/update operation</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              leftstr(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Returns the leftmost <i>Y</i> characters in string <i>X</i>.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              length(<i>X</i>)</td>
            <td valign="top">
              Return the string length of <i>X</i> in characters. If SQLite is configured to support
              UTF-8, then the number of UTF-8 characters is returned, not the number of bytes.</td>
          </tr>
          <tr>
            <a name="likeFunc"></a>
            <td align="right" width="1%" nowrap>
              like(<i>X</i>,<i>Y</i> [,<i>Z</i>])</td>
            <td valign="top">
              This function is used to implement the "<b>X LIKE Y [ESCAPE Z]</b>" syntax of SQL.
              If the optional ESCAPE clause is present, then the user-function is invoked with
              three arguments. Otherwise, it is invoked with two arguments only. The <a href="capi3ref.html#sqlite3_create_function">
                sqlite_create_function()</a> interface can be used to override this function and
              thereby change the operation of the <a href="#like">LIKE</a> operator. When doing
              this, it may be important to override both the two and three argument versions of
              the like() function. Otherwise, different code may be called to implement the LIKE
              operator depending on whether or not an ESCAPE clause was specified.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              load_extension(<i>X</i>)<br />
              load_extension(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Load SQLite extensions out of the shared library file named <i>X</i> using the entry
              point <i>Y</i>. The result is a NULL. If <i>Y</i> is omitted then the default entry
              point of <b>sqlite3_extension_init</b> is used. This function raises an exception
              if the extension fails to load or initialize correctly.
            </td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              log(<i>X</i>)</td>
            <td valign="top">
              Returns the natural logarithm of the specified <b>double</b> expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              log10(<i>X</i>)</td>
            <td valign="top">
              Returns the base-10 logarithm of the specified <b>double</b> expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              lower(<i>X</i>)</td>
            <td valign="top">
              Return a copy of string <i>X</i> will all characters converted to lower case. The
              C library <b>tolower()</b> routine is used for the conversion, which means that
              this function might not work correctly on UTF-8 characters.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              max(<i>X</i>,<i>Y</i>,...)</td>
            <td valign="top">
              Return the argument with the maximum value. Arguments may be strings in addition
              to numbers. The maximum value is determined by the usual sort order. Note that <b>
                max()</b> is a simple function when it has 2 or more arguments but converts to
              an aggregate function if given only a single argument.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              min(<i>X</i>,<i>Y</i>,...)</td>
            <td valign="top">
              Return the argument with the minimum value. Arguments may be strings in addition
              to numbers. The minimum value is determined by the usual sort order. Note that <b>
                min()</b> is a simple function when it has 2 or more arguments but converts to
              an aggregate function if given only a single argument.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              nullif(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Return the first argument if the arguments are different, otherwise return NULL.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              padc(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Pads the given string <i>X</i> on the left and the right with spaces until it is 
              the specified length <i>Y</i></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              padl(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Pads the given string <i>X</i> on the left with spaces until it is the specified 
              length <i>Y</i></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              padr(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Pads the given string <i>X</i> on the right with spaces until it is the 
              specified length <i>Y</i></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              pi</td>
            <td valign="top">
              Returns the value of pi</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              power(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Returns the value of the specified expression <i>X</i> to the specified power <i>
              Y</i></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              proper(<i>X</i>)</td>
            <td valign="top">
              Proper-case the given string <i>X</i></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              quote(<i>X</i>)</td>
            <td valign="top">
              This routine returns a string which is the value of its argument suitable for inclusion
              into another SQL statement. Strings are surrounded by single-quotes with escapes
              on interior quotes as needed. BLOBs are encoded as hexadecimal literals. The current
              implementation of
          VACUUM uses this function. The function is also useful when writing
              triggers to implement undo/redo functionality.
            </td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              radians(<i>X</i>)</td>
            <td valign="top">
              Converts degrees to radians</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              random(*)</td>
            <td valign="top">
              Return a pseudo-random integer between -9223372036854775808 and +9223372036854775807.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              replace(<i>X</i>,<i>Y</i>,<i>Z</i>)</td>
            <td valign="top">
              Replace all occurances of <i>Y</i> inside string <i>X</i> with the replacement 
              text <i>Z</i>.&nbsp; Case-sensitive.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              replicate(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Return the concatenation of string <i>X</i> repeated <i>Y</i> times</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              reverse(<i>X</i>)</td>
            <td valign="top">
              Returns the string <i>X</i> reversed</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              rightstr(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Returns the right-most <i>Y</i> characters in string <i>X</i>.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              round(<i>X</i>)<br />
              round(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Round off the number <i>X</i> to <i>Y</i> digits to the right of the decimal point.
              If the <i>Y</i> argument is omitted, 0 is assumed.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              sign(<i>X</i>)</td>
            <td valign="top">
              Returns the positive (+1), zero (0), or negative (-1) sign of the specified 
              expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              sin(<i>X</i>)</td>
            <td valign="top">
              Returns the trigonometric sine of the specified angle, in radians, and in an 
              approximate numeric, <b>double</b>, expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              soundex(<i>X</i>)</td>
            <td valign="top">
              Compute the soundex encoding of the string <i>X</i>. The string &quot;?000&quot; is 
              returned if the argument is NULL.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              sqlite_version(*)</td>
            <td valign="top">
              Return the version string for the SQLite library that is running. Example: "3.6.0"</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              sqrt(<i>X</i>)</td>
            <td valign="top">
              Returns the square root of the specified value</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              square(X)</td>
            <td valign="top">
              Returns the square of the specified value</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              strfilter(<i>X</i>,<i>Y</i>)</td>
            <td valign="top">
              Given a source string <i>X</i> and the characters to filter <i>Y</i>, returns <i>
              X</i> with all characters not found in <i>Y</i> removed.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              substr(<i>X</i>,<i>Y</i>,<i>Z</i>)</td>
            <td valign="top">
              Return a substring of input string <i>X</i> that begins with the <i>Y</i>-th character
              and which is <i>Z</i> characters long. The left-most character of <i>X</i> is number
              1. If <i>Y</i> is negative the the first character of the substring is found by
              counting from the right rather than the left. If SQLite is configured to support
              UTF-8, then characters indices refer to actual UTF-8 characters, not bytes.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              tan(<i>X</i>)</td>
            <td valign="top">
              Returns the tangent of the input expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              tanh(<i>X</i>)</td>
            <td valign="top">
              Hyperbolic tangent</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              typeof(<i>X</i>)</td>
            <td valign="top">
              Return the type of the expression <i>X</i>. The only return values are "null", "integer",
              "real", "text", and "blob".
        SQLite's type handling is explained in <a href="http://www.sqlite.org/datatype3.html">
                Datatypes in SQLite Version 3</a>.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              upper(<i>X</i>)</td>
            <td valign="top">
              Return a copy of input string <i>X</i> converted to all upper-case letters. The
              implementation of this function uses the C library routine <b>toupper()</b> which
              means it may not work correctly on UTF-8 strings.</td>
          </tr>
        </table>
      </p>
      <p>
        <a name="aggregatefunctions"></a><b>Aggregate Functions</b>
      </p>
      <p>
        The aggregate functions shown below are available by default. Additional aggregate
        functions written in C may be added using the <a href="capi3ref.html#sqlite3_create_function">
          sqlite3_create_function()</a> API.</p>
      <p>
        In any aggregate function that takes a single argument, that argument can be preceeded
        by the keyword DISTINCT. In such cases, duplicate elements are filtered before being
        passed into the aggregate function. For example, the function "count(distinct X)"
        will return the number of distinct values of column X instead of the total number
        of non-null values in column X.
      </p>
      <p>
        <table border="0" cellpadding="10">
          <tr>
            <td align="right" valign="top" width="120">
              avg(<i>X</i>)</td>
            <td valign="top">
              Return the average value of all non-NULL <i>X</i> within a group. String and BLOB
              values that do not look like numbers are interpreted as 0. The result of avg() is
              always a floating point value even if all inputs are integers.
              <p>
              </p>
            </td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              count(<i>X</i>)<br />
              count(*)</td>
            <td valign="top">
              The first form return a count of the number of times that <i>X</i> is not NULL in
              a group. The second form (with no argument) returns the total number of rows in
              the group.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              lower_quartile(<i>X</i>)</td>
            <td valign="top">
              Returns the lower quartile of the given numbers in the set</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              max(<i>X</i>)</td>
            <td valign="top">
              Return the maximum value of all values in the group. The usual sort order is used
              to determine the maximum.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              median(<i>X</i>)</td>
            <td valign="top">
              Returns the middle value in a set of ordered numbers. (The medial value is 
              unlike the mean value, which is the sum of a set of numbers divided by the count 
              of numbers in the set). The median value is determined by choosing the smallest 
              value such that at least half of the values in the set are no greater than the 
              chosen value. If the number of values within the set is odd, the median value 
              corresponds to a single value. If the number of values within the set is even, 
              the median value corresponds to the sum of the two middle values divided by two.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              min(<i>X</i>)</td>
            <td valign="top">
              Return the minimum non-NULL value of all values in the group. The usual sort order
              is used to determine the minimum. NULL is only returned if all values in the group
              are NULL.</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              mode(<i>X</i>)</td>
            <td valign="top">
              Computes the most frequently occurring value in a sample set</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              stdev(<i>X</i>)</td>
            <td valign="top">
              Returns the statistical standard deviation of all values in the specified 
              expression</td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              sum(<i>X</i>)<br />
              total(<i>X</i>)</td>
            <td valign="top">
              Return the numeric sum of all non-NULL values in the group. If there are no non-NULL
              input rows then sum() returns NULL but total() returns 0.0. NULL is not normally
              a helpful result for the sum of no rows but the SQL standard requires it and most
              other SQL database engines implement sum() that way so SQLite does it in the same
              way in order to be compatible. The non-standard total() function is provided as
              a convenient way to work around this design problem in the SQL language.
              <p>
              </p>
              <p>
                The result of total() is always a floating point value. The result of sum() is an
                integer value if all non-NULL inputs are integers. If any input to sum() is neither
                an integer or a NULL then sum() returns a floating point value which might be an
                approximation to the true sum.</p>
              <p>
                Sum() will throw an "integer overflow" exception if all inputs are integers or NULL
                and an integer overflow occurs at any point during the computation. Total() never
                throws an exception.</p>
            </td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              upper_quartile(<i>X</i>)</td>
            <td valign="top">
              Returns the upper quartile of the numbers in the given set</td>
          </tr>
        </table>
      </p>
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Doc/Extra/lang_insert.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>INSERT</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">INSERT</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        INSERT</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">INSERT </font></b>[<b><font color="#2c2cf0">OR </font></b>
              <i><font color="#ff3434">conflict-algorithm</font></i><b><font color="#2c2cf0"></font></b>]<b><font
                color="#2c2cf0"> INTO </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                  color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0"> </font></b>
              [<b><font color="#2c2cf0"><big>(</big></font></b><i><font color="#ff3434">column-list</font></i><b><font
                color="#2c2cf0"><big>)</big></font></b>]<b><font color="#2c2cf0"> VALUES<big>(</big></font></b><i><font
                  color="#ff3434">value-list</font></i><b><font color="#2c2cf0"><big>)</big> </font>
                  </b><big>|</big><b><font color="#2c2cf0"><br />
                    INSERT </font></b>[<b><font color="#2c2cf0">OR </font></b><i><font color="#ff3434">
                      conflict-algorithm</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0">
                        INTO </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                          color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0"> </font></b>
              [<b><font color="#2c2cf0"><big>(</big></font></b><i><font color="#ff3434">column-list</font></i><b><font
                color="#2c2cf0"><big>)</big></font></b>]<b><font color="#2c2cf0"> </font></b><i><font
                  color="#ff3434">select-statement</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The INSERT statement comes in two basic forms. The first form (with the "VALUES"
        keyword) creates a single new row in an existing table. If no column-list is specified
        then the number of values must be the same as the number of columns in the table.
        If a column-list is specified, then the number of values must match the number of
        specified columns. Columns of the table that do not appear in the column list are
        filled with the default value, or with NULL if not default value is specified.
      </p>
      <p>
        The second form of the INSERT statement takes it data
        from a SELECT statement. The
        number of columns in the result of the SELECT must exactly match the number of columns
        in the table if no column list is specified, or it must match the number of columns
        name in the column list. A new entry is made in the table for every row of the SELECT
        result. The SELECT may be simple or compound. If the SELECT statement has an ORDER
        BY clause, the ORDER BY is ignored.</p>
      <p>
        The optional conflict-clause allows the specification of an alternative constraint conflict resolution algorithm to use during this one command. See the section titled
        <a href="lang_conflict.html">ON CONFLICT</a> for additional information. For compatibility
        with MySQL, the parser allows the use of the single keyword <a href="lang_replace.html">
          REPLACE</a> as an alias for "INSERT OR REPLACE".
      </p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































Deleted Doc/Extra/lang_reindex.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>REINDEX</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">REINDEX</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        REINDEX</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">REINDEX </font></b><i><font color="#ff3434">collation
        name</font></i><b><font
                color="#2c2cf0"></font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">REINDEX </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">database-name</font></i><b><font color="#2c2cf0"> <big>.</big></font></b>]<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">table/index-name</font></i><b><font
                    color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The REINDEX command is used to delete and recreate indices from scratch. This is
        useful when the definition of a collation sequence has changed.
      </p>
      <p>
        In the first form, all indices in all attached databases that use the named collation
        sequence are recreated. In the second form, if <i>[database-name.]table/index-name</i>
        identifies a table, then all indices associated with the table are rebuilt. If an
        index is identified, then only this specific index is deleted and recreated.
      </p>
      <p>
        If no <i>database-name</i> is specified and there exists both a table or index and
        a collation sequence of the specified name, then indices associated with the collation
        sequence only are reconstructed. This ambiguity may be dispelled by always specifying
        a <i>database-name</i> when reindexing a specific table or index.
      </p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































Deleted Doc/Extra/lang_replace.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>REPLACE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">REPLACE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        REPLACE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">REPLACE INTO </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">database-name</font></i><b><font color="#2c2cf0"> <big>.</big></font></b>]<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">table-name</font></i><b><font
                    color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"><big>(</big> </font></b>
              <i><font color="#ff3434">column-list</font></i><b><font color="#2c2cf0"> <big>)</big></font></b>]<b><font
                color="#2c2cf0"> VALUES <big>(</big> </font></b><i><font color="#ff3434">value-list</font></i><b><font
                  color="#2c2cf0"> <big>)</big> </font></b><big>|</big><b><font color="#2c2cf0"><br />
                    REPLACE INTO </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">database-name</font></i><b><font
                      color="#2c2cf0"> <big>.</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0"> </font></b>
              [<b><font color="#2c2cf0"><big>(</big> </font></b><i><font color="#ff3434">column-list</font></i><b><font
                color="#2c2cf0"> <big>)</big></font></b>]<b><font color="#2c2cf0"> </font></b>
              <i><font color="#ff3434">select-statement</font></i><b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The REPLACE command is an alias for the "INSERT OR REPLACE" variant of the <a href="lang_insert.html">
          INSERT</a> command. This alias is provided for compatibility with MySQL. See the
        <a href="lang_insert.html">INSERT</a> command documentation for additional information.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































Deleted Doc/Extra/lang_select.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>SELECT</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">SELECT</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        SELECT</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">SELECT </font></b>[<b><font color="#2c2cf0">ALL </font></b>
              <big>|</big><b><font color="#2c2cf0"> DISTINCT</font></b>]<b><font color="#2c2cf0">
              </font></b><i><font color="#ff3434">result</font></i><b><font color="#2c2cf0"> </font>
              </b>[<b><font color="#2c2cf0">FROM </font></b><i><font color="#ff3434">table-list</font></i><b><font
                color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"><br />
                </font></b>[<b><font color="#2c2cf0">WHERE </font></b><i><font color="#ff3434">expr</font></i><b><font
                  color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"><br />
                  </font></b>[<b><font color="#2c2cf0">GROUP BY </font></b><i><font color="#ff3434">
                    expr-list</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"><br />
                    </font></b>[<b><font color="#2c2cf0">HAVING </font></b><i><font color="#ff3434">expr</font></i><b><font
                      color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"><br />
                      </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">compound-op</font></i><b><font
                        color="#2c2cf0"> </font></b><i><font color="#ff3434">select</font></i><b><font color="#2c2cf0"></font></b>]<b><font
                          color="#2c2cf0"></font></b><big>*</big><b><font color="#2c2cf0"><br />
                          </font></b>[<b><font color="#2c2cf0">ORDER BY </font></b><i><font color="#ff3434">
                            sort-expr-list</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"><br />
                            </font></b>[<b><font color="#2c2cf0">LIMIT </font></b><i><font color="#ff3434">integer</font></i><b><font
                              color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b>(<b><font color="#2c2cf0">
                                OFFSET </font></b><big>|</big><b><font color="#2c2cf0"> <big>,</big> </font></b>
              )<b><font color="#2c2cf0"> </font></b><i><font color="#ff3434">integer</font></i><b><font
                color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">result</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">result-column</font></i><b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"><big>,</big> </font></b>
              <i><font color="#ff3434">result-column</font></i><b><font color="#2c2cf0"></font></b>]<b><font
                color="#2c2cf0"></font></b><big>*</big><b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">result-column</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"><big>*</big> </font></b><big>|</big><b><font color="#2c2cf0">
              </font></b><i><font color="#ff3434">table-name</font></i><b><font color="#2c2cf0">
                <big>.</big> <big>*</big> </font></b><big>|</big><b><font color="#2c2cf0"> </font>
                </b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font></b>
              [<b><font color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0">AS</font></b>]<b><font
                color="#2c2cf0"> </font></b><i><font color="#ff3434">string</font></i><b><font color="#2c2cf0">
                </font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">table-list</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">table</font></i><b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">join-op</font></i><b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">table</font></i><b><font color="#2c2cf0">
                  </font></b><i><font color="#ff3434">join-args</font></i><b><font color="#2c2cf0"></font></b>]<b><font
                    color="#2c2cf0"></font></b><big>*</big><b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">table</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">table-name</font></i><b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0">AS </font></b><i><font color="#ff3434">
                  alias</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"> </font>
                  </b><big>|</big><b><font color="#2c2cf0"><br />
                    <big>(</big> </font></b><i><font color="#ff3434">select</font></i><b><font color="#2c2cf0">
                      <big>)</big> </font></b>[<b><font color="#2c2cf0">AS </font></b><i><font color="#ff3434">
                        alias</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">join-op</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"><big>,</big> </font></b><big>|</big><b><font color="#2c2cf0">
              </font></b>[<b><font color="#2c2cf0">NATURAL</font></b>]<b><font color="#2c2cf0">
              </font></b>[<b><font color="#2c2cf0">LEFT </font></b><big>|</big><b><font color="#2c2cf0">
                RIGHT </font></b><big>|</big><b><font color="#2c2cf0"> FULL</font></b>]<b><font color="#2c2cf0">
                </font></b>[<b><font color="#2c2cf0">OUTER </font></b><big>|</big><b><font color="#2c2cf0">
                  INNER </font></b><big>|</big><b><font color="#2c2cf0"> CROSS</font></b>]<b><font
                    color="#2c2cf0"> JOIN</font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">join-args</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b>[<b><font color="#2c2cf0">ON </font></b><i><font
                color="#ff3434">expr</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0">
                </font></b>[<b><font color="#2c2cf0">USING <big>(</big> </font></b><i><font color="#ff3434">
                  id-list</font></i><b><font color="#2c2cf0"> <big>)</big></font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sort-expr-list</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">expr</font></i><b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">sort-order</font></i><b><font
                  color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"><big>,</big>
                  </font></b><i><font color="#ff3434">expr</font></i><b><font color="#2c2cf0"> </font>
                  </b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">sort-order</font></i><b><font
                    color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b><big>*</big><b><font
                      color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sort-order</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b>[<b><font color="#2c2cf0"> COLLATE </font></b>
              <i><font color="#ff3434">collation-name</font></i><b><font color="#2c2cf0"> </font>
              </b>]<b><font color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"> ASC </font></b>
              <big>|</big><b><font color="#2c2cf0"> DESC </font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">compound_op</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">UNION </font></b><big>|</big><b><font color="#2c2cf0"> UNION
                ALL </font></b><big>|</big><b><font color="#2c2cf0"> INTERSECT </font></b><big>|</big><b><font
                  color="#2c2cf0"> EXCEPT</font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The SELECT statement is used to query the database. The result of a SELECT is zero
        or more rows of data where each row has a fixed number of columns. The number of
        columns in the result is specified by the expression list in between the SELECT
        and FROM keywords. Any arbitrary expression can be used as a result. If a result
        expression is <font color="#2c2cf0"><big>*</big></font> then all columns of all
        tables are substituted for that one expression. If the expression is the name of
        a table followed by <font color="#2c2cf0"><big>.*</big></font> then the result is
        all columns in that one table.</p>
      <p>
        The DISTINCT keyword causes a subset of result rows to be returned, in which each
        result row is different. NULL values are not treated as distinct from each other.
        The default behavior is that all result rows be returned, which can be made explicit
        with the keyword ALL.</p>
      <p>
        The query is executed against one or more tables specified after the FROM keyword.
        If multiple tables names are separated by commas, then the query is against the
        cross join of the various tables. The full SQL-92 join syntax can also be used to
        specify joins. A sub-query in parentheses may be substituted for any table name
        in the FROM clause. The entire FROM clause may be omitted, in which case the result
        is a single row consisting of the values of the expression list.
      </p>
      <p>
        The WHERE clause can be used to limit the number of rows over which the query operates.</p>
      <p>
        The GROUP BY clauses causes one or more rows of the result to be combined into a
        single row of output. This is especially useful when the result contains aggregate
        functions. The expressions in the GROUP BY clause do <em>not</em> have to be expressions
        that appear in the result. The HAVING clause is similar to WHERE except that HAVING
        applies after grouping has occurred. The HAVING expression may refer to values,
        even aggregate functions, that are not in the result.</p>
      <p>
        The ORDER BY clause causes the output rows to be sorted. The argument to ORDER BY
        is a list of expressions that are used as the key for the sort. The expressions
        do not have to be part of the result for a simple SELECT, but in a compound SELECT
        each sort expression must exactly match one of the result columns. Each sort expression
        may be optionally followed by a COLLATE keyword and the name of a collating function
        used for ordering text and/or keywords ASC or DESC to specify the sort order.</p>
      <p>
        The LIMIT clause places an upper bound on the number of rows returned in the result.
        A negative LIMIT indicates no upper bound. The optional OFFSET following LIMIT specifies
        how many rows to skip at the beginning of the result set. In a compound query, the
        LIMIT clause may only appear on the final SELECT statement. The limit is applied
        to the entire query not to the individual SELECT statement to which it is attached.
        Note that if the OFFSET keyword is used in the LIMIT clause, then the limit is the
        first number and the offset is the second number. If a comma is used instead of
        the OFFSET keyword, then the offset is the first number and the limit is the second
        number. This seeming contradition is intentional - it maximizes compatibility with
        legacy SQL database systems.
      </p>
      <p>
        A compound SELECT is formed from two or more simple SELECTs connected by one of
        the operators UNION, UNION ALL, INTERSECT, or EXCEPT. In a compound SELECT, all
        the constituent SELECTs must specify the same number of result columns. There may
        be only a single ORDER BY clause at the end of the compound SELECT. The UNION and
        UNION ALL operators combine the results of the SELECTs to the right and left into
        a single big table. The difference is that in UNION all result rows are distinct
        where in UNION ALL there may be duplicates. The INTERSECT operator takes the intersection
        of the results of the left and right SELECTs. EXCEPT takes the result of left SELECT
        after removing the results of the right SELECT. When three or more SELECTs are connected
        into a compound, they group from left to right.</p>
      <p>
        &nbsp;</p>
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































Deleted Doc/Extra/lang_transaction.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>TRANSACTIONS</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">BEGIN TRANSACTION</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        BEGIN TRANSACTION</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">BEGIN </font></b>[<b><font color="#2c2cf0"> DEFERRED </font>
              </b><big>|</big><b><font color="#2c2cf0"> IMMEDIATE </font></b><big>|</big><b><font
                color="#2c2cf0"> EXCLUSIVE </font></b>]<b><font color="#2c2cf0"> </font></b>[<b><font
                  color="#2c2cf0">TRANSACTION </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                    color="#ff3434">name</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b>]<b><font
                      color="#2c2cf0"></font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">END </font></b>[<b><font color="#2c2cf0">TRANSACTION </font>
              </b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">name</font></i><b><font
                color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">COMMIT </font></b>[<b><font color="#2c2cf0">TRANSACTION </font>
              </b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">name</font></i><b><font
                color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">ROLLBACK </font></b>[<b><font color="#2c2cf0">TRANSACTION
              </font></b>[<b><font color="#2c2cf0"></font></b><i><font color="#ff3434">name</font></i><b><font
                color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        Beginning in version 2.0, SQLite supports transactions with rollback and atomic
        commit.</p>
      <p>
        The optional transaction name is ignored. SQLite currently does not allow nested
        transactions.</p>
      <p>
        No changes can be made to the database except within a transaction. Any command
        that changes the database (basically, any SQL command
          other than SELECT) will automatically start a transaction if one is not already in effect. Automatically started transactions
        are committed at the conclusion of the command.
      </p>
      <p>
        Transactions can be started manually using the BEGIN command. Such transactions
        usually persist until the next COMMIT or ROLLBACK command. But a transaction will
        also ROLLBACK if the database is closed or if an error occurs and the ROLLBACK conflict
        resolution algorithm is specified. See the documentation on the <a href="lang_conflict.html">
          ON CONFLICT</a> clause for additional information about the ROLLBACK conflict
        resolution algorithm.
      </p>
      <p>
        In SQLite version 3.0.8 and later, transactions can be deferred, immediate, or exclusive.
        Deferred means that no locks are acquired on the database until the database is
        first accessed. Thus with a deferred transaction, the BEGIN statement itself does
        nothing. Locks are not acquired until the first read or write operation. The first
        read operation against a database creates a SHARED lock and the first write operation
        creates a RESERVED lock. Because the acquisition of locks is deferred until they
        are needed, it is possible that another thread or process could create a separate
        transaction and write to the database after the BEGIN on the current thread has
        executed. If the transaction is immediate, then RESERVED locks are acquired on all
        databases as soon as the BEGIN command is executed, without waiting for the database
        to be used. After a BEGIN IMMEDIATE, you are guaranteed that no other thread or
        process will be able to write to the database or do a BEGIN IMMEDIATE or BEGIN EXCLUSIVE.
        Other processes can continue to read from the database, however. An exclusive transaction
        causes EXCLUSIVE locks to be acquired on all databases. After a BEGIN EXCLUSIVE,
        you are guaranteed that no other thread or process will be able to read or write
        the database until the transaction is complete.
      </p>
      <p>
        A description of the meaning of SHARED, RESERVED, and EXCLUSIVE locks is available
        <a href="lockingv3.html">separately</a>.
      </p>
      <p>
        The default behavior for SQLite version 3.0.8 is a deferred transaction. For SQLite
        version 3.0.0 through 3.0.7, deferred is the only kind of transaction available.
        For SQLite version 2.8 and earlier, all transactions are exclusive.
      </p>
      <p>
        The COMMIT command does not actually perform a commit until all pending SQL commands
        finish. Thus if two or more SELECT statements are in the middle of processing and
        a COMMIT is executed, the commit will not actually occur until all SELECT statements
        finish.
      </p>
      <p>
        An attempt to execute COMMIT might result in an SQLITE_BUSY return code. This indicates
        that another thread or process had a read lock on the database that prevented the
        database from being updated. When COMMIT fails in this way, the transaction remains
        active and the COMMIT can be retried later after the reader has had a chance to
        clear.
      </p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































Deleted Doc/Extra/lang_types.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>TYPES</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">TYPES</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite (sortof)</h1>
      <h4>
        TYPES</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">TYPES </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">datatype name</font></i><b><font color="#2c2cf0"></font></b>][,<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">datatype name</font></i><b><font color="#2c2cf0"></font></b>][,<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">datatype
                      name</font></i><b><font color="#2c2cf0"></font></b>][,<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">...</font></i>] ; <em><span style="color: #ff3434">select-stmt</span></em></td>            
          </tr>
          <tr>
          <td align="right" width="1%" nowrap>
          <i><font color="#ff3434">select-stmt</font></i> ::=</td>
          <td>
            see <a href="lang_select.html">SELECT</a></td>
          </tr>
        </table>
      </p>
      <p>
        Use the TYPES keyword before a SELECT statement to provide the SQLite ADO.NET provider
        a list of return datatypes to expect from the subsequent SELECT statement.&nbsp;
      </p>
      <p>
        This is a language extension (aka <strong>hack</strong>) to SQLite specifically for the ADO.NET data
        provider.&nbsp; It is a pseudo-statement, meaning only the ADO.NET provider understands
        it.</p>
      <h3>
        Background</h3>
      <p>
        Due to SQLite's typeless nature, there are certain kinds of queries for which the
        ADO.NET provider cannot determine the proper return data type.&nbsp; Scalar and
        aggregate functions pose a particular problem because
        there is no requirement for a given scalar or aggregate function to return any particular
        datatype.&nbsp; As a matter of fact, scalar functions could theoretically return
        a different datatype for every row or column in a query and this is perfectly legal
        from SQLite's point of view.</p>
      <p>
        Since ADO.NET is designed around a typed system and we're shoe-horning SQLite into
        it, this keyword helps the provider out in cases where the return type cannot be easily determined.</p>
      <p>
        This command must be used in conjunction with a SELECT statement.&nbsp; It only
        works when both the TYPES keyword and its value(s) are passed along with a SELECT
        statement as a single semi-colon separated unit.</p>
      <h3>
        Examples</h3>
      <p>
        <strong><span style="color: #2c2cf0">TYPES</span> [bigint], [int], [smallint], [tinyint];<br />
          <span style="color: #2c2cf0">SELECT</span> 1, 2, 3, 4;</strong></p>
      <p>
        The above query would return the columns as types System.Int64, System.Int32, System.Int16
        and System.Byte respectively.</p>
      <p>
        <strong><span style="color: #2c2cf0">TYPES</span> [bigint], [int], , [tinyint];<br />
          <span style="color: #2c2cf0">SELECT</span> 1, 2, 3, 4;</strong></p>
      <p>
        In this sample, only columns 1, 2 and 4 would have explicit typing.&nbsp; Column
        3's datatype would pass though the system and be discovered normally.</p>
      <p>
        <strong><span style="color: #2c2cf0">TYPES</span> real;<br />
          <span style="color: #2c2cf0">SELECT</span> SUM(Cost) FROM [Products];</strong></p>
      <p>
        The above query explicitly tells the provider that the SUM aggregate function returns
        a System.Double.</p>
      <h3>
        Usage Notes</h3>
      <ul>
        <li>You cannot use parameters in the TYPES statement.</li>
        <li>The TYPES statement must be immediately followed by a SELECT statement.</li>
        <li>It is legal to pass multiple TYPES and SELECT statements in a multi-statement
          command.</li>
        <li>You may enclose datatypes in quotes <strong>""</strong> or brackets <strong>[]</strong>
          or those <strong>``</strong> thingies if you want.<br />
        </li>
      </ul>
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































Deleted Doc/Extra/lang_update.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>UPDATE</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">UPDATE</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        UPDATE</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">UPDATE </font></b>[<b><font color="#2c2cf0"> OR </font></b>
              <i><font color="#ff3434">conflict-algorithm</font></i><b><font color="#2c2cf0"> </font>
              </b>]<b><font color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">database-name</font></i><b><font color="#2c2cf0"> <big>.</big></font></b>]<b><font
                  color="#2c2cf0"> </font></b><i><font color="#ff3434">table-name</font></i><b><font
                    color="#2c2cf0"><br />
                    SET </font></b><i><font color="#ff3434">assignment</font></i><b><font color="#2c2cf0">
                    </font></b>[<b><font color="#2c2cf0"><big>,</big> </font></b><i><font color="#ff3434">
                      assignment</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b><big>*</big><b><font
                        color="#2c2cf0"><br />
                      </font></b>[<b><font color="#2c2cf0">WHERE </font></b><i><font color="#ff3434">expr</font></i><b><font
                        color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"></font></b></td>
          </tr>
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">assignment</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0"></font></b><i><font color="#ff3434">column-name</font></i><b><font
                color="#2c2cf0"> <big>=</big> </font></b><i><font color="#ff3434">expr</font></i><b><font
                  color="#2c2cf0"></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The UPDATE statement is used to change the value of columns in selected rows of
        a table. Each assignment in an UPDATE specifies a column
        name to the left of the
        equals sign and an arbitrary expression to the right. The expressions may use the
        values of
          other columns. All expressions are evaluated before any assignments are
        made. A WHERE clause can be used to restrict which rows are updated.</p>
      <p>
        The optional conflict-clause allows the specification of an alternative constraint conflict resolution algorithm to use during this one command. See the section titled
        <a href="lang_conflict.html">ON CONFLICT</a> for additional information.</p>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































Deleted Doc/Extra/lang_vacuum.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>TYPES</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">VACUUM</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        VACUUM</h4>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">VACUUM </font></b>[<b><font color="#2c2cf0"></font></b><i><font
                color="#ff3434">index-or-tablename</font></i>]</td>
          </tr>
        </table>
      </p>
      <p>
        The VACUUM command is an SQLite extension modeled after a similar command found
        in PostgreSQL. If VACUUM is invoked with the name of a table or index then it is
        suppose to clean up the named table or index. In version 1.0 of SQLite, the VACUUM
        command would invoke <b>gdbm_reorganize()</b> to clean up the backend database file.</p>
      <p>
        VACUUM became a no-op when the GDBM backend was removed from SQLITE in version 2.0.0.
        VACUUM was reimplemented in version 2.8.1. The index or table name argument is now
        ignored.
      </p>
      <p>
        When an object (table, index, or trigger) is dropped from the database, it leaves
        behind empty space. This makes the database file larger than it needs to be, but
        can speed up inserts. In time inserts and deletes can leave the database file structure
        fragmented, which slows down disk access to the database contents. The VACUUM command
        cleans the main database by copying its contents to a temporary database file and
        reloading the original database file from the copy. This eliminates free pages,
        aligns table data to be contiguous, and otherwise cleans up the database file structure.
        It is not possible to perform the same process on an attached database file.</p>
      <p>
        This command will fail if there is an active transaction. This command has no effect
        on an in-memory database.</p>
      <p>
        As of SQLite version 3.1, an alternative to using the VACUUM command is auto-vacuum
        mode, enabled using the <a href="pragma.html#pragma_auto_vacuum">auto_vacuum pragma</a>.</p>
      <p>
        &nbsp;</p>
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































Deleted Doc/Extra/limitations.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>Provider Limitations</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">Provider Limitations</span>
          </td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite.NET Class Library Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">Limitations of this ADO.NET SQLite Data Provider</h1>
      <p>As providers go, this one doesn't have many restrictions. SQLite has no 
        support for row-level or table-level locks. When a connection locks the database for writing, no other connection or process may read or write to the database until the write operation is complete.  The SQLite.NET provider attempts to retry 
        internally if a database is locked, up to the CommandTimeout property of the 
        command in question.</p>
      <p>SQLite is inherently type-less, and only understands a few basic datatypes 
        natively. They are (in .NET-speak) Int64, Double, String and Blob. The 
        SQLite.NET provider will use the database schema information it can glean to 
        enforce type-ness, but it is an inexact science.</p>
      <p>
        Hierarchical DataReaders are not supported. In the 
        case of transactions, any SQLiteCommand created on a connection will (when 
        executed) automatically join a transaction in progress, regardless of whether 
        that transaction was created before or after the command.</p>
      <p>A SQLiteCommand object <b>can</b> be re-assigned a new SQLiteConnection object 
        as long as no DataReaders are active on the command.</p>
      <p>Opening a transaction is considered a write operation, so only use them when 
        you want to write to the database! If you hold open a transaction, all readers on other
        connections
        will be blocked until the transaction is closed!</p>
      <p></p>
      <h4 class="subHeading">Thread Safety</h4>
      <p>Multi-threading in SQLite must be done carefully. Here are the restrictions:</p>
      <ul>
        <li>
          <b>You May</b>
        Clone() a SQLiteConnection object in one thread and pass the cloned object to 
        another thread. Once passed, the other thread becomes the new owner of the 
        cloned connection, and the original thread must not keep a reference to the 
        clone or call any methods on the clone.
        <LI>
          <STRONG>You May</STRONG>
        create multiple threads, and those threads can create their own 
        SQLiteConnection and subsequent objects for accessing a database.&nbsp; 
        Multiple connections on multiple threads to the same database file are 
        perfectly&nbsp;acceptable&nbsp;and will behave predictably.&nbsp;
        <li>
          <b>You May NOT</b>
        call methods or properties or otherwise reference any SQLite provider classes 
        that belong to another thread.
        <li>
          <b>You May NOT</b> pass a SQLiteCommand, SQLiteDataReader, SQLiteDataAdapter or 
          any other SQLite provider class except a cloned SQLiteConnection to another 
          thread.</li>
      </ul>
      <p>Understand again that SQLite has no fine-grained locking mechanisms. It is 
        therefore your own responsibility in a multi-threaded environment to handle 
        potential timeouts that may occur if a long-running query in one thread 
        prevents a query in another thread from executing. These timeouts will only 
        occur if one thread is attempting to read while another thread is attempting to 
        write. Whichever thread got its lock first will be the one to execute, and the 
        other thread will block until the CommandTimeout value elapses or the other 
        thread finishes.</p>
      <hr/>
      <div id="footer">
        <p>
          <a href="mailto:sqlite-users@sqlite.org?subject=SQLite.NET%20Class%20Library%20Documentation%20Feedback:%20Limitations">
            Send comments on this topic.</a>
        </p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































Deleted Doc/Extra/ndoc.css.
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
.userDataStyle
{
	behavior:	url(#default#userData);
}

@media all
{
	tool\:tip{behavior: url(tooltip.htc)}
}

body
{
	background: #FFFFFF;
	color: #000000;
	font-family: Verdana;
	font-size: medium;
	font-style: normal;
	font-weight: normal;
	margin: 0px;
	width: 100%;
}

a
{
	color: #0000FF;
}

a:visited
{
	color: #0000FF;
}

a:hover
{
	color: #3366FF;
}

div#mainSection
{
	font-size: 70%;
	width: 100%;
}

div#mainBody
{
	font-size: 90%;
	margin-left: 15px;
	margin-top: 10px;
	padding-bottom: 20px;
}
div#mainBody p, div#mainBody ol, div#mainBody ul, div#mainBody dl
{
	padding-right: 5;
}

div#header
{
	background-color: #D4DFFF;
	padding: 0px;
	width: 100%;
}

div#header table
{
	border-bottom: solid 1px #C8CDDE;
	width: 100%;
}

span#runningHeaderText
{
	color: #003399;
	font-size: 90%;
	padding-left: 13px;
}


span#nsrTitle
{
	color: #003399;
	font-size: 120%;
	font-weight: bold;
	padding-left: 13px;
}

div#header table td
{
	color: #0000FF;
	font-size: 70%;
	margin-top: 0px;
	margin-bottom: 0px;
	padding-right: 20px;
}

div#header table tr#headerTableRow3 td
{
	padding-bottom: 2px;
	padding-top: 5px;
	padding-left: 15px;
}

div#header table#bottomTable
{
	border-top: solid 1px #FFFFFF;
	text-align: left;
	padding-left: 15px;
}

div#footer
{
	font-size: 90%;
	margin: 0px;
	padding: 2px;
	width: 100%;
}

hr#footerHR
{
	border-bottom: solid 1px #EEEEFF;
	border-top: solid 1px #C8CDDE;
	height: 3px;
	color: #D4DFFF;
}
/*
div.saveHistory
{
	behavior:url(#default#saveHistory);
}
*/
div.section
{
	padding-top: 2px;
	padding-bottom: 2px;
	padding-left: 16px;
	padding-right: 15px;
	width: 100%;
}

.heading
{
	font-weight: bold;
	margin-top: 18px;
	margin-bottom: 8px;
}

h1.heading
{
	color: #003399;
	font-size: 130%;
}

.subHeading
{
	font-weight: bold;
	margin-bottom: 4px;
}

h3.subHeading
{
	color: #000000;
	font-size: 120%;
	font-weight: normal;
}

h4.subHeading
{
	color: #000000;
	font-size: 100%;
}

img.toggle
{
	border: none;
	margin-right: 5px;
}

img.copyCodeImage
{
	border: none;
	margin: 1px;
	margin-right: 3px;
}

img.downloadCodeImage
{
	border: none;
	margin-right: 3px;
}

img.viewCodeImage
{
	border: none;
	margin-right: 3px;
}

img.note
{
	border: none;
	margin-right: 3px;
}

img#languageFilterImage
{
	border: none;
	margin-left: 10px;
	vertical-align: middle;
}

img#membersOptionsFilterImage
{
	border: none;
	margin-left: 10px;
	vertical-align: middle;
}

img#toggleAllImage
{
	margin-left: 4px;
	vertical-align: middle;
}

div#mainSection table
{
	border: none;
	font-size: 100%;
	width: 100%;
	margin-top: 5px;
	margin-bottom: 5px;
}

div#mainSection table tr
{
	vertical-align: top;
}

div#mainSection table th
{
	background-color: #EFEFF7;
	border-bottom: solid 1px #C8CDDE;
	color: #000066;
	padding-left: 5px;
	padding-right: 5px;
	text-align: left;
}

div#mainSection table td
{
	background-color: #F7F7FF;
	border-bottom: solid 1px #D5D5D3;
	/*border-left: solid 1px #D5D5D3;*/
	padding-left: 5px;
	padding-right: 5px;
	margin: 1px;
}

div#mainSection table td.imageCell
{
	white-space: nowrap;
	/*width: 1%;*/
}

div#mainSection table td.nameCell
{
	white-space: nowrap;
}

div.code table
{
	border: none;
	font-size: 95%;
	margin-bottom: 5px;
	margin-top:-.4em;
	width: 100%;
}

div.code table th
{
	background: #EFEFF7;
	border-bottom: solid 1px #C8CDDE;
	color: #000066;
	font-weight: bold;
	padding-left: 5px;
	padding-right: 5px;
}

div.code table td
{
	background: #F7F7FF;
	border-top: solid 1px #FFFFFF;
	padding-left: 5px;
	padding-right: 5px;
	padding-top: 5px;
	padding-bottom: 15px;
}

div.code table td.syntax
{
	font-family:	Monospace, Courier New, Courier;
	font-size: 105%;
	color:	#000066;
	white-space: nowrap;
}

div.code table td.message
{
}

div.alert table
{
	border: none;
	font-size: 100%;
	width: 100%;
}

div.alert table th
{
	background: #EFEFF7;
	border-bottom-width: 0px;
	color: #000066;
	padding-left: 5px;
	padding-right: 5px;
}

div.alert table td
{
	background: #F7F7FF;
	border-top: solid 1px #FFFFFF;
	padding-left: 5px;
	padding-right: 5px;
}

span.copyCode
{
	color: #0000ff;
	font-size: 90%;
	font-weight: normal;
	cursor: hand;
	float: right;
	display: inline;
	text-align: right;
}

.downloadCode
{
	color: #0000ff;
	font-size: 90%;
	font-weight: normal;
	cursor: hand;
}

.viewCode
{
	color: #0000ff;
	font-size: 90%;
	font-weight: normal;
	cursor: hand;
}

code
{
	font-family: Monospace, Courier New, Courier;
	font-size: 105%;
	color: #000066;
}

dl
{
	margin-top: 0px;
	padding-left: 1px;
}

dt
{
	font-style: italic;
}

dd
{
	margin-bottom: 0px;
	margin-left: 0px;
}

ul
{
	margin-top:0px;
	margin-bottom:0px;
	margin-left: 17px;
	list-style-type: disc;
}

ul ul
{
	margin-bottom: 4px;
	margin-left: 17px;
	margin-top: 3px;
	list-style-type: disc;
}

ol
{
	margin-top:0px;
	margin-bottom:0px;
	margin-left: 28px;
	list-style-type: decimal;
}

ol ol
{
	margin-bottom: 4px;
	margin-left: 24px;
	margin-top: 3px;
	list-style-type: lower-alpha;
}

li
{
	margin-top:-2px;
	margin-bottom: 3px;
}

p
{
	margin-top: 10px;
	margin-bottom: 5px;
}

.tip
{
	color: #0000FF;
	font-style: italic;
	cursor: hand;
	text-decoration: underline;
}

.languageFilter
{
	color: #0000FF;
	cursor: hand;
	text-decoration: underline;
	padding-bottom: 4px;
}

.math
{
	font-family: Times New Roman;
	font-size: 125%;
}

.sourceCodeList
{
	font-family: Verdana;
	font-size: 90%;
}

pre.viewCode
{
	width: 100%;
	overflow: auto;
}

MSHelp\:link
{
	text-decoration: underline;
	color: #0000ff; 
	hoverColor: #3366ff;
	filterString: ;
}


/*----------------------------------------------*/
/*
.attribute a:link
{
	color: #000088;
	text-decoration: none;
}
.attribute a:visited
{
	color: #000088;
	text-decoration: none;
}
.attribute a:hover
{
	color: #3366ff;
}

.attribute MSHelp\:link
	{
	text-decoration: underline; 
	color: #0000ff; 
	hoverColor: #3366ff;
	filterString: ;
	}
*/
.missing
{
	color: Red;
	font-weight: bold;
}
div.hier
{
	margin-top: 0.5em;
	margin-right: 0.0em;
	margin-bottom: 0.5em;
	margin-left: 1.0em;
}
div#mainSection table.hier
{
	border: none;
	font-size: 100%;
	padding: 0px;
	margin: 0px;
	border-collapse: collapse;
	width: auto;
}
div#mainSection table.hier tr
{
	padding: 0px;
	margin: 0px;
}
div#mainSection table.hier td
{
	border: none;
	vertical-align: top;
	padding: 0px;
	margin: 50px;
	background-color: transparent;
}

div.code table td span.attribute
{
	padding: 0px;
	margin: 0px;
}

p.inheritDoc
{
	padding: 2px;
	margin: 0px;
	background-color: #FFFFE0;
	border-top: solid 1px #E0E0C0;
}
p.inheritSource
{
	padding: 0px 2px;
	margin: 0px;
	font-size: 85%;
	background-color: #F0F0D0;
	color: #606050;
}
span.autoText
{
	padding: 2px;
	margin: 0px;
	background-color: #E0FFE0;
	color: #206020;
}

p.missing
{
	padding: 2px;
	margin: 0px;
	font-size: 85%;
	background-color: #FFE0E0;
	color: #800000;
	font-weight: bold;
}

.topicstatus /* Topic Status Boilerplate class */
	{
	display: block;
	color: red;
	}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Doc/Extra/optimizing.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>Optimizing Your Queries</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">Optimizing for SQLite</span>
          </td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite.NET Class Library Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">Tips on Optimizing Your Queries</h1>
      <p>The next few paragraphs will attempt to give you a few rudimentary rules for 
        speeding up your queries in general, and especially how SQLite is adversely 
        affected by the kinds of SQL behaviors you may have taken for granted in other 
        providers. It is by no means a complete optimization guide. For even more 
        details on optimizing your queries, visit <a href="http://www.sqlite.org">sqlite.org</a>.</p>
      <h4 class="subHeading">The Importance of Transactions</h4>
      <p>If you are inserting data in SQLite without first starting a transaction: <b>DO 
          NOT PASS GO! Call BeginTransaction() right now, and finish with Commit()!</b> 
        If you think I'm kidding, think again. SQLite's A.C.I.D. design means that 
        every single time you insert any data outside a transaction, an implicit 
        transaction is constructed, the insert made, and the transaction destructed. <b>EVERY 
          TIME.</b> If you're wondering why in the world your inserts are taking 100x 
        longer than you think they should, look no further.</p>
      <h4 class="subHeading">Prepared Statements</h4>
      <p>Lets have a quick look at the following code and evaluate its performance:</p>
      <div class="syntax">
        <pre>
      using (SQLiteCommand mycommand = new SQLiteCommand(myconnection))
      {
        int n;
        
        for (n = 0; n < 100000; n ++)
        {
          mycommand.CommandText = String.Format("INSERT INTO [MyTable] ([MyId]) VALUES({0})", n + 1);
          mycommand.ExecuteNonQuery();
        }
      }</pre>
      </div>
      <p>This code seems pretty tight, but if you think it performs well, you're dead 
        wrong. Here's what's wrong with it:</p>
      <ul>
        <li>
          I didn't start a transaction first! This insert is dog slow!</li>
        <li>
          The CLR is calling "new" implicitly 100,000 times because I am formatting a 
          string in the loop for every insert</li>
        <li>
          Since SQLite precompiles SQL statements, the engine is constructing and 
          deconstructing 100,000 SQL statements and allocating/deallocating their memory</li>
        <li>
          All this construction and destruction is involving about 300,000 more native to 
          managed interop calls than an optimized insert</li>
      </ul>
      <p>So lets rewrite that code slightly:</p>
      <div class="syntax">
        <pre>
      using (SQLiteTransaction mytransaction = myconnection.BeginTransaction())
      {
        using (SQLiteCommand mycommand = new SQLiteCommand(myconnection))
        {
          SQLiteParameter myparam = new SQLiteParameter();
          int n;
        
          mycommand.CommandText = "INSERT INTO [MyTable] ([MyId]) VALUES(?)";
          mycommand.Parameters.Add(myparam);
          
          for (n = 0; n < 100000; n ++)
          {
            myparam.Value = n + 1;
            mycommand.ExecuteNonQuery();
          }
        }
        mytransaction.Commit();
      } </pre>
      </div>
      <p>Now this is a blazing fast insert for <b><i>any</i></b> database engine, not 
        just SQLite. The SQL statement is prepared one time -- on the first call to 
        ExecuteNonQuery(). Once prepared, it never needs re-evaluating. Furthermore, 
        we're allocating no memory in the loop and doing a very minimal number of 
        interop transitions. Surround the entire thing with a transaction, and the 
        performance of this insert is so far and away faster than the original that it 
        merits a hands-on-the-hips pirate-like laugh.</p>
      <p>Every database engine worth its salt utilizes prepared statements. If you're 
        not coding for this, you're not writing optimized SQL, and that's the bottom 
        line.
      </p>
      <hr />
      <div id="footer">
        <p>
          <a href="mailto:sqlite-users@sqlite.org?subject=SQLite.NET%20Class%20Library%20Documentation%20Feedback:%20Optimizing">
            Send comments on this topic.</a>
        </p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































Deleted Doc/Extra/pragma.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>PRAGMA</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">PRAGMA</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <h4>
        PRAGMA</h4>
      <p>
        The <a href="#syntax">PRAGMA command</a> is a special command used to modify the
        operation of the SQLite library or to query the library for internal (non-table)
        data. The PRAGMA command is issued using the same interface as other SQLite commands
        (e.g. SELECT, INSERT) but is different in the following important respects:
      </p>
      <ul>
        <li>Specific pragma statements may be removed and others added in future releases
          of SQLite. Use with caution! </li>
        <li>No error messages are generated if an unknown pragma is issued. Unknown pragmas
          are simply ignored. This means if there is a typo in a pragma statement the library
          does not inform the user of the fact. </li>
        <li>Some pragmas take effect during the SQL compilation stage, not the execution stage.
          This means if using the C-language sqlite3_compile(), sqlite3_step(), sqlite3_finalize()
          API (or similar in a wrapper interface), the pragma may be applied to the library
          during the sqlite3_compile() call. </li>
        <li>The pragma command is unlikely to be compatible with any other SQL engine. </li>
      </ul>
      <p>
        The available pragmas fall into four basic categories:</p>
      <ul>
        <li>Pragmas used to <a href="#schema">query the schema</a> of the current database.
        </li>
        <li>Pragmas used to <a href="#modify">modify the operation</a> of the SQLite library
          in some manner, or to query for the current mode of operation. </li>
        <li>Pragmas used to <a href="#version">query or modify the databases two version values</a>,
          the schema-version and the user-version. </li>
        <li>Pragmas used to <a href="#debug">debug the library</a> and verify that database
          files are not corrupted. </li>
      </ul>
      <hr />
      <a name="syntax"></a>
      <h1>
        PRAGMA command syntax</h1>
      <p>
        <table cellpadding="10">
          <tr>
            <td align="right" width="1%" nowrap>
              <i><font color="#ff3434">sql-statement</font></i> ::=</td>
            <td>
              <b><font color="#2c2cf0">PRAGMA </font></b><i><font color="#ff3434">name</font></i><b><font
                color="#2c2cf0"> </font></b>[<b><font color="#2c2cf0">= </font></b><i><font color="#ff3434">
                  value</font></i><b><font color="#2c2cf0"></font></b>]<b><font color="#2c2cf0"> </font>
                  </b><big>|</big><b><font color="#2c2cf0"><br />
                    PRAGMA </font></b><i><font color="#ff3434">function</font></i><b><font color="#2c2cf0"><big>(</big></font></b><i><font
                      color="#ff3434">arg</font></i><b><font color="#2c2cf0"><big>)</big></font></b></td>
          </tr>
        </table>
      </p>
      <p>
        The pragmas that take an integer <b><i>value</i></b> also accept symbolic names.
        The strings "<b>on</b>", "<b>true</b>", and "<b>yes</b>" are equivalent to <b>1</b>.
        The strings "<b>off</b>", "<b>false</b>", and "<b>no</b>" are equivalent to <b>0</b>.
        These strings are case- insensitive, and do not require quotes. An unrecognized
        string will be treated as <b>1</b>, and will not generate an error. When the <i>value</i>
        is returned it is as an integer.</p>
      <hr />
      <a name="modify"></a>
      <h1>
        Pragmas to modify library operation</h1>
      <ul>
        <a name="pragma_auto_vacuum"></a>
        <li>
          <p>
            <b>PRAGMA auto_vacuum;
              <br />
              PRAGMA auto_vacuum = </b><i>0 | 1</i><b>;</b></p>
          <p>
            Query or set the auto-vacuum flag in the database.</p>
          <p>
            Normally, when a transaction that deletes data from a database is committed, the
            database file remains the same size. Unused database file pages are marked as such
            and reused later on, when data is inserted into the database. In this mode the <a
              href="lang_vacuum.html">VACUUM</a> command is used to reclaim unused space.</p>
          <p>
            When the auto-vacuum flag is set, the database file shrinks when a transaction that
            deletes data is committed (The VACUUM command is not useful in a database with the
            auto-vacuum flag set). To support this functionality the database stores extra information
            internally, resulting in slightly larger database files than would otherwise be
            possible.</p>
          <p>
            It is only possible to modify the value of the auto-vacuum flag before any tables
            have been created in the database. No error message is returned if an attempt to
            modify the auto-vacuum flag is made after one or more tables have been created.
          </p>
          <a name="pragma_cache_size"></a></li>
        <li>
          <p>
            <b>PRAGMA cache_size;
              <br />
              PRAGMA cache_size = </b><i>Number-of-pages</i><b>;</b></p>
          <p>
            Query or change the maximum number of database disk pages that SQLite will hold
            in memory at once. Each page uses about 1.5K of memory. The default cache size is
            2000. If you are doing UPDATEs or DELETEs that change many rows of a database and
            you do not mind if SQLite uses more memory, you can increase the cache size for
            a possible speed improvement.</p>
          <p>
            When you change the cache size using the cache_size pragma, the change only endures
            for the current session. The cache size reverts to the default value when the database
            is closed and reopened. Use the <a href="#pragma_default_cache_size"><b>default_cache_size</b></a>
            pragma to check the cache size permanently.</p>
          <a name="pragma_case_sensitive_like"></a></li>
        <li>
          <p>
            <b>PRAGMA case_sensitive_like;
              <br />
              PRAGMA case_sensitive_like = </b><i>0 | 1</i><b>;</b></p>
          <p>
            The default behavior of the LIKE operator is to ignore case for latin1 characters.
            Hence, by default <b>'a' LIKE 'A'</b> is true. The case_sensitive_like pragma can
            be turned on to change this behavior. When case_sensitive_like is enabled, <b>'a'
              LIKE 'A'</b> is false but <b>'a' LIKE 'a'</b> is still true.</p>
          <a name="pragma_count_changes"></a></li>
        <li>
          <p>
            <b>PRAGMA count_changes;
              <br />
              PRAGMA count_changes = </b><i>0 | 1</i><b>;</b></p>
          <p>
            Query or change the count-changes flag. Normally, when the count-changes flag is
            not set, INSERT, UPDATE and DELETE statements return no data. When count-changes
            is set, each of these commands returns a single row of data consisting of one integer
            value - the number of rows inserted, modified or deleted by the command. The returned
            change count does not include any insertions, modifications or deletions performed
            by triggers.</p>
          <a name="pragma_default_cache_size"></a></li>
        <li>
          <p>
            <b>PRAGMA default_cache_size;
              <br />
              PRAGMA default_cache_size = </b><i>Number-of-pages</i><b>;</b></p>
          <p>
            Query or change the maximum number of database disk pages that SQLite will hold
            in memory at once. Each page uses 1K on disk and about 1.5K in memory. This pragma
            works like the <a href="#pragma_cache_size"><b>cache_size</b></a> pragma with the
            additional feature that it changes the cache size persistently. With this pragma,
            you can set the cache size once and that setting is retained and reused every time
            you reopen the database.</p>
          <a name="pragma_default_synchronous"></a></li>
        <li>
          <p>
            <b>PRAGMA default_synchronous;</b></p>
          <p>
            This pragma was available in version 2.8 but was removed in version 3.0. It is a
            dangerous pragma whose use is discouraged. To help dissuide users of version 2.8
            from employing this pragma, the documentation will not tell you what it does.</p>
          <a name="pragma_empty_result_callbacks"></a></li>
        <li>
          <p>
            <b>PRAGMA empty_result_callbacks;
              <br />
              PRAGMA empty_result_callbacks = </b><i>0 | 1</i><b>;</b></p>
          <p>
            Query or change the empty-result-callbacks flag.</p>
          <p>
            The empty-result-callbacks flag affects the sqlite3_exec API only. Normally, when
            the empty-result-callbacks flag is cleared, the callback function supplied to the
            sqlite3_exec() call is not invoked for commands that return zero rows of data. When
            empty-result-callbacks is set in this situation, the callback function is invoked
            exactly once, with the third parameter set to 0 (NULL). This is to enable programs
            that use the sqlite3_exec() API to retrieve column-names even when a query returns
            no data.
          </p>
          <a name="pragma_encoding"></a></li>
        <li>
          <p>
            <b>PRAGMA encoding;
              <br />
              PRAGMA encoding = "UTF-8";
              <br />
              PRAGMA encoding = "UTF-16";
              <br />
              PRAGMA encoding = "UTF-16le";
              <br />
              PRAGMA encoding = "UTF-16be";</b></p>
          <p>
            In first form, if the main database has already been created, then this pragma returns
            the text encoding used by the main database, one of "UTF-8", "UTF-16le" (little-endian
            UTF-16 encoding) or "UTF-16be" (big-endian UTF-16 encoding). If the main database
            has not already been created, then the value returned is the text encoding that
            will be used to create the main database, if it is created by this session.</p>
          <p>
            The second and subsequent forms of this pragma are only useful if the main database
            has not already been created. In this case the pragma sets the encoding that the
            main database will be created with if it is created by this session. The string
            "UTF-16" is interpreted as "UTF-16 encoding using native machine byte-ordering".
            If the second and subsequent forms are used after the database file has already
            been created, they have no effect and are silently ignored.</p>
          <p>
            Once an encoding has been set for a database, it cannot be changed.</p>
          <p>
            Databases created by the ATTACH command always use the same encoding as the main
            database.</p>
          <a name="pragma_full_column_names"></a></li>
        <li>
          <p>
            <b>PRAGMA full_column_names;
              <br />
              PRAGMA full_column_names = </b><i>0 | 1</i><b>;</b></p>
          <p>
            Query or change the full-column-names flag. This flag affects the way SQLite names
            columns of data returned by SELECT statements when the expression for the column
            is a table-column name or the wildcard "*". Normally, such result columns are named
            &lt;table-name/alias&gt;&lt;column-name&gt; if the SELECT statement joins two or
            more tables together, or simply &lt;column-name&gt; if the SELECT statement queries
            a single table. When the full-column-names flag is set, such columns are always
            named &lt;table-name/alias&gt; &lt;column-name&gt; regardless of whether or not
            a join is performed.
          </p>
          <p>
            If both the short-column-names and full-column-names are set, then the behaviour
            associated with the full-column-names flag is exhibited.
          </p>
          <a name="pragma_fullfsync"></a></li>
        <li>
          <p>
            <b>PRAGMA fullfsync
              <br />
              PRAGMA fullfsync = </b><i>0 | 1</i><b>;</b></p>
          <p>
            Query or change the fullfsync flag. This flag affects determines whether or not
            the F_FULLFSYNC syncing method is used on systems that support it. The default value
            is off. As of this writing (2006-02-10) only Mac OS X supports F_FULLFSYNC.
          </p>
          <a name="pragma_legacy_file_format"></a></li>
        <li>
          <p>
            <b>PRAGMA legacy_file_format;
              <br />
              PRAGMA legacy_file_format = <i>ON | OFF</i></b></p>
          <p>
            This pragma sets or queries the value of the legacy_file_format flag. When this
            flag is on, new SQLite databases are created in a file format that is readable and
            writable by all versions of SQLite going back to 3.0.0. When the flag is off, new
            databases are created using the latest file format which might to be readable or
            writable by older versions of SQLite.</p>
          <p>
            This flag only effects newly created databases. It has no effect on databases that
            already exists.</p>
          <a name="pragma_page_size"></a></li>
        <li>
          <p>
            <b>PRAGMA page_size;
              <br />
              PRAGMA page_size = </b><i>bytes</i><b>;</b></p>
          <p>
            Query or set the page-size of the database. The page-size may only be set if the
            database has not yet been created. The page size must be a power of two greater
            than or equal to 512 and less than or equal to 8192. The upper limit may be modified
            by setting the value of macro SQLITE_MAX_PAGE_SIZE during compilation. The maximum
            upper bound is 32768.
          </p>
          <a name="pragma_read_uncommitted"></a></li>
        <li>
          <p>
            <b>PRAGMA read_uncommitted;
              <br />
              PRAGMA read_uncommitted = </b><i>0 | 1</i><b>;</b></p>
          <p>
            Query, set, or clear READ UNCOMMITTED isolation. The default isolation level for
            SQLite is SERIALIZABLE. Any process or thread can select READ UNCOMMITTED isolation,
            but SERIALIZABLE will still be used except between connections that share a common
            page and schema cache. Cache sharing is enabled using the <a href="capi3ref.html#sqlite3_enable_shared_cache">
              sqlite3_enable_shared_cache()</a> API and is only available between connections
            running the same thread. Cache sharing is off by default.
          </p>
          <a name="pragma_short_column_names"></a></li>
        <li>
          <p>
            <b>PRAGMA short_column_names;
              <br />
              PRAGMA short_column_names = </b><i>0 | 1</i><b>;</b></p>
          <p>
            Query or change the short-column-names flag. This flag affects the way SQLite names
            columns of data returned by SELECT statements when the expression for the column
            is a table-column name or the wildcard "*". Normally, such result columns are named
            &lt;table-name/alias&gt;lt;column-name&gt; if the SELECT statement joins two or
            more tables together, or simply &lt;column-name&gt; if the SELECT statement queries
            a single table. When the short-column-names flag is set, such columns are always
            named &lt;column-name&gt; regardless of whether or not a join is performed.
          </p>
          <p>
            If both the short-column-names and full-column-names are set, then the behaviour
            associated with the full-column-names flag is exhibited.
          </p>
          <a name="pragma_synchronous"></a></li>
        <li>
          <p>
            <b>PRAGMA synchronous;
              <br />
              PRAGMA synchronous = FULL; </b>(2)<b>
                <br />
                PRAGMA synchronous = NORMAL; </b>(1)<b>
                  <br />
                  PRAGMA synchronous = OFF; </b>(0)</p>
          <p>
            Query or change the setting of the "synchronous" flag. The first (query) form will
            return the setting as an integer. When synchronous is FULL (2), the SQLite database
            engine will pause at critical moments to make sure that data has actually been written
            to the disk surface before continuing. This ensures that if the operating system
            crashes or if there is a power failure, the database will be uncorrupted after rebooting.
            FULL synchronous is very safe, but it is also slow. When synchronous is NORMAL,
            the SQLite database engine will still pause at the most critical moments, but less
            often than in FULL mode. There is a very small (though non-zero) chance that a power
            failure at just the wrong time could corrupt the database in NORMAL mode. But in
            practice, you are more likely to suffer a catastrophic disk failure or some other
            unrecoverable hardware fault. With synchronous OFF (0), SQLite continues without
            pausing as soon as it has handed data off to the operating system. If the application
            running SQLite crashes, the data will be safe, but the database might become corrupted
            if the operating system crashes or the computer loses power before that data has
            been written to the disk surface. On the other hand, some operations are as much
            as 50 or more times faster with synchronous OFF.
          </p>
          <p>
            In SQLite version 2, the default value is NORMAL. For version 3, the default was
            changed to FULL.
          </p>
          <a name="pragma_temp_store"></a></li>
        <li>
          <p>
            <b>PRAGMA temp_store;
              <br />
              PRAGMA temp_store = DEFAULT;</b> (0)<b>
                <br />
                PRAGMA temp_store = FILE;</b> (1)<b>
                  <br />
                  PRAGMA temp_store = MEMORY;</b> (2)</p>
          <p>
            Query or change the setting of the "<b>temp_store</b>" parameter. When temp_store
            is DEFAULT (0), the compile-time C preprocessor macro TEMP_STORE is used to determine
            where temporary tables and indices are stored. When temp_store is MEMORY (2) temporary
            tables and indices are kept in memory. When temp_store is FILE (1) temporary tables
            and indices are stored in a file. The <a href="#pragma_temp_store_directory">temp_store_directory</a>
            pragma can be used to specify the directory containing this file. <b>FILE</b> is
            specified. When the temp_store setting is changed, all existing temporary tables,
            indices, triggers, and views are immediately deleted.</p>
          <p>
            It is possible for the library compile-time C preprocessor symbol TEMP_STORE to
            override this pragma setting. The following table summarizes the interaction of
            the TEMP_STORE preprocessor macro and the temp_store pragma:</p>
          <blockquote>
            <table border="1" cellpadding="2">
              <tr>
                <th valign="bottom">
                  TEMP_STORE</th>
                <th valign="bottom">
                  PRAGMA<br />
                  temp_store</th>
                <th>
                  Storage used for<br />
                  TEMP tables and indices</th>
              </tr>
              <tr>
                <td align="middle">
                  0</td>
                <td align="middle">
                  <em>any</em></td>
                <td align="middle">
                  file</td>
              </tr>
              <tr>
                <td align="middle">
                  1</td>
                <td align="middle">
                  0</td>
                <td align="middle">
                  file</td>
              </tr>
              <tr>
                <td align="middle">
                  1</td>
                <td align="middle">
                  1</td>
                <td align="middle">
                  file</td>
              </tr>
              <tr>
                <td align="middle">
                  1</td>
                <td align="middle">
                  2</td>
                <td align="middle">
                  memory</td>
              </tr>
              <tr>
                <td align="middle">
                  2</td>
                <td align="middle">
                  0</td>
                <td align="middle">
                  memory</td>
              </tr>
              <tr>
                <td align="middle">
                  2</td>
                <td align="middle">
                  1</td>
                <td align="middle">
                  file</td>
              </tr>
              <tr>
                <td align="middle">
                  2</td>
                <td align="middle">
                  2</td>
                <td align="middle">
                  memory</td>
              </tr>
              <tr>
                <td align="middle">
                  3</td>
                <td align="middle">
                  <em>any</em></td>
                <td align="middle">
                  memory</td>
              </tr>
            </table>
          </blockquote>
          <br />
          <a name="pragma_temp_store_directory"></a></li>
        <li>
          <p>
            <b>PRAGMA temp_store_directory;
              <br />
              PRAGMA temp_store_directory = 'directory-name';</b></p>
          <p>
            Query or change the setting of the "temp_store_directory" - the directory where
            files used for storing temporary tables and indices are kept. This setting lasts
            for the duration of the current connection only and resets to its default value
            for each new connection opened.
          </p>
          <p>
            When the temp_store_directory setting is changed, all existing temporary tables,
            indices, triggers, and viewers are immediately deleted. In practice, temp_store_directory
            should be set immediately after the database is opened.
          </p>
          <p>
            The value <i>directory-name</i> should be enclosed in single quotes. To revert the
            directory to the default, set the <i>directory-name</i> to an empty string, e.g.,
            <i>PRAGMA temp_store_directory = ''</i>. An error is raised if <i>directory-name</i>
            is not found or is not writable.
          </p>
          <p>
            The default directory for temporary files depends on the OS. For Unix/Linux/OSX,
            the default is the is the first writable directory found in the list of: <b>/var/tmp,
              /usr/tmp, /tmp,</b> and <b><i>current-directory</i></b>. For Windows NT, the default
            directory is determined by Windows, generally <b>C:\Documents and Settings\<i>user-name</i>\Local
              Settings\Temp\</b>. Temporary files created by SQLite are unlinked immediately
            after opening, so that the operating system can automatically delete the files when
            the SQLite process exits. Thus, temporary files are not normally visible through
            <i>ls</i> or <i>dir</i> commands.</p>
        </li>
      </ul>
      <hr />
      <a name="schema"></a>
      <h1>
        Pragmas to query the database schema</h1>
      <ul>
        <a name="pragma_database_list"></a>
        <li>
          <p>
            <b>PRAGMA database_list;</b></p>
          <p>
            For each open database, invoke the callback function once with information about
            that database. Arguments include the index and the name the database was attached
            with. The first row will be for the main database. The second row will be for the
            database used to store temporary tables.</p>
          <a name="pragma_foreign_key_list"></a></li>
        <li>
          <p>
            <b>PRAGMA foreign_key_list(</b><i>table-name</i><b>);</b></p>
          <p>
            For each foreign key that references a column in the argument table, invoke the
            callback function with information about that foreign key. The callback function
            will be invoked once for each column in each foreign key.</p>
          <a name="pragma_index_info"></a></li>
        <li>
          <p>
            <b>PRAGMA index_info(</b><i>index-name</i><b>);</b></p>
          <p>
            For each column that the named index references, invoke the callback function once
            with information about that column, including the column name, and the column number.</p>
          <a name="pragma_index_list"></a></li>
        <li>
          <p>
            <b>PRAGMA index_list(</b><i>table-name</i><b>);</b></p>
          <p>
            For each index on the named table, invoke the callback function once with information
            about that index. Arguments include the index name and a flag to indicate whether
            or not the index must be unique.</p>
          <a name="pragma_table_info"></a></li>
        <li>
          <p>
            <b>PRAGMA table_info(</b><i>table-name</i><b>);</b></p>
          <p>
            For each column in the named table, invoke the callback function once with information
            about that column, including the column name, data type, whether or not the column
            can be NULL, and the default value for the column.</p>
        </li>
      </ul>
      <hr />
      <a name="version"></a>
      <h1>
        Pragmas to query/modify version values</h1>
      <ul>
        <a name="pragma_schema_version"></a><a name="pragma_user_version"></a>
        <li>
          <p>
            <b>PRAGMA [database.]schema_version;
              <br />
              PRAGMA [database.]schema_version = </b><i>integer </i><b>;
                <br />
                PRAGMA [database.]user_version;
                <br />
                PRAGMA [database.]user_version = </b><i>integer </i><b>;</b>
          </p>
          <p>
            The pragmas schema_version and user_version are used to set or get the value of
            the schema-version and user-version, respectively. Both the schema-version and the
            user-version are 32-bit signed integers stored in the database header.</p>
          <p>
            The schema-version is usually only manipulated internally by SQLite. It is incremented
            by SQLite whenever the database schema is modified (by creating or dropping a table
            or index). The schema version is used by SQLite each time a query is executed to
            ensure that the internal cache of the schema used when compiling the SQL query matches
            the schema of the database against which the compiled query is actually executed.
            Subverting this mechanism by using "PRAGMA schema_version" to modify the schema-version
            is potentially dangerous and may lead to program crashes or database corruption.
            Use with caution!</p>
          <p>
            The user-version is not used internally by SQLite. It may be used by applications
            for any purpose.</p>
        </li>
      </ul>
      <hr />
      <a name="debug"></a>
      <h1>
        Pragmas to debug the library</h1>
      <ul>
        <a name="pragma_integrity_check"></a>
        <li>
          <p>
            <b>PRAGMA integrity_check;</b></p>
          <p>
            The command does an integrity check of the entire database. It looks for out-of-order
            records, missing pages, malformed records, and corrupt indices. If any problems
            are found, then a single string is returned which is a description of all problems.
            If everything is in order, "ok" is returned.</p>
          <a name="pragma_parser_trace"></a></li>
        <li>
          <p>
            <b>PRAGMA parser_trace = ON; </b>(1)<b>
              <br />
              PRAGMA parser_trace = OFF;</b> (0)</p>
          <p>
            Turn tracing of the SQL parser inside of the SQLite library on and off. This is
            used for debugging. This only works if the library is compiled without the NDEBUG
            macro.
          </p>
          <a name="pragma_vdbe_trace"></a></li>
        <li>
          <p>
            <b>PRAGMA vdbe_trace = ON; </b>(1)<b>
              <br />
              PRAGMA vdbe_trace = OFF;</b> (0)</p>
          <p>
            Turn tracing of the virtual database engine inside of the SQLite library on and
            off. This is used for debugging. See the <a href="vdbe.html#trace">VDBE documentation</a>
            for more information.</p>
          <a name="pragma_vdbe_listing"></a></li>
        <li>
          <p>
            <b>PRAGMA vdbe_listing = ON; </b>(1)<b>
              <br />
              PRAGMA vdbe_listing = OFF;</b> (0)</p>
          <p>
            Turn listings of virtual machine programs on and off. With listing is on, the entire
            content of a program is printed just prior to beginning execution. This is like
            automatically executing an EXPLAIN prior to each statement. The statement executes
            normally after the listing is printed. This is used for debugging. See the <a href="vdbe.html#trace">
              VDBE documentation</a> for more information.</p>
        </li>
      </ul>
      <p>
      <hr>
        &nbsp;</p>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Doc/Extra/syntax.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>SQLite Query Syntax</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">SQLite Query Syntax</span>&nbsp;</td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite Language Reference Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">
        SQL As Understood By SQLite</h1>
      <p>
        The SQLite library understands most of the standard SQL language. But it does omit
        some features while at the same time adding a few features of its own. This document
        attempts to describe precisely what parts of the SQL language SQLite does and does
        not support. A list of keywords is also provided. In all of the syntax diagrams
        that follow, literal text is shown in bold blue. Non-terminal symbols are shown
        in italic red. Operators that are part of the syntactic markup itself are shown
        in black roman. This document is just an overview of the SQL syntax implemented
        by SQLite.
      </p>
      <h4>
        SQLite implements the follow syntax:</h4>
      <p>
        <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse">
          <tr>
            <td>
              <a href="lang_altertable.html">
              ALTER TABLE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_analyze.html">
              ANALYZE</a></td>
          </tr>
          <tr>
            <td style="height: 19px">
              <a href="lang_attach.html">
              ATTACH DATABASE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_transaction.html">
              BEGIN TRANSACTION</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_comment.html">
              comment</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_transaction.html">
              COMMIT TRANSACTION</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_createindex.html">CREATE INDEX</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_createtable.html">CREATE TABLE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_createtrigger.html">CREATE TRIGGER</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_createview.html">CREATE VIEW</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_createvtab.html">
              CREATE VIRTUAL TABLE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_delete.html">
              DELETE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_detach.html">
              DETACH DATABASE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_dropindex.html">DROP INDEX</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_droptable.html">DROP TABLE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_droptrigger.html">DROP TRIGGER</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_dropview.html">DROP VIEW</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_transaction.html">
              END TRANSACTION</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_explain.html">
              EXPLAIN</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_expr.html">
              expression</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_insert.html">
              INSERT</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_conflict.html">
              ON CONFLICT clause</a></td>
          </tr>
          <tr>
            <td style="height: 19px">
              <a href="pragma.html">
              PRAGMA</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_reindex.html">
              REINDEX</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_replace.html">
              REPLACE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_transaction.html">
              ROLLBACK TRANSACTION</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_select.html">
              SELECT</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_types.html">
              TYPES</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_update.html">
              UPDATE</a></td>
          </tr>
          <tr>
            <td>
              <a href="lang_vacuum.html">
              VACUUM</a></td>
          </tr>
        </table>
      </p>
      <hr>
      <div id="footer">
        <p>
          &nbsp;</p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































Deleted Doc/Extra/version.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>Version History</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">Version History</span>
          </td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite.NET Class Library Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
    <h1 class="heading">Version History</h1>
    <p><b>1.0.77.0 - November 28, 2011</b></p>
    <ul>
      <li>Updated to SQLite 3.7.9 <a href="http://www.sqlite.org/src/info/a499ae3835">[a499ae3835]</a>.</li>
      <li>More enhancements to the build and test automation.</li>
      <li>Plug native memory leak when closing a database connection containing a statement that cannot be finalized for some reason.</li>
      <li>The SQLite3 class should always attempt to dispose the contained SQLiteConnectionHandle, even when called via the finalizer.</li>
      <li>When compiled with DEBUG defined, emit diagnostic information related to resource cleanup to any TraceListener objects that may be registered.</li>
      <li>Stop characterizing all log messages as errors. From now on, if the errorCode is zero, the message will not be considered an error.</li>
      <li>Never attempt to configure the native logging interface if the SQLite core library has already been initialized for the process. Fix for <a href="http://system.data.sqlite.org/index.html/info/2ce0870fad">[2ce0870fad]</a>.</li>
      <li>Allow the SQLiteLog class to be used for logging messages without having an open connection.</li>
      <li>Support building the core System.Data.SQLite assemblies using the .NET Framework 4.0 Client Profile. Fix for <a href="http://system.data.sqlite.org/index.html/info/566f1ad1e4">[566f1ad1e4]</a>.</li>
      <li>When generating the schema based on the contents of a SQLiteDataReader, skip flagging columns as unique if the data reader is holding the result of some kind of multi-table construct (e.g. a cross join) because we must allow duplicate values in that case. Fix for <a href="http://system.data.sqlite.org/index.html/info/7e3fa93744">[7e3fa93744]</a>.</li>
      <li>When returning schema information that may be used by the .NET Framework to construct dynamic SQL, use a fake schema name (instead of null) so that the table names will be properly qualified with the catalog name (i.e. the attached database name). Partial fix for <a href="http://system.data.sqlite.org/index.html/info/343d392b51">[343d392b51]</a>.</li>
      <li>Add SQLiteSourceId property to the SQLiteConnection class to return the SQLite source identifier.</li>
      <li>Add MemoryUsed and MemoryHighwater properties to the SQLiteConnection class to help determine the memory usage of SQLite.</li>
      <li>Add DateTimeKind connection string property to control the DateTimeKind of parsed DateTime values. Partial fix for <a href="http://system.data.sqlite.org/index.html/info/343d392b51">[343d392b51]</a>.</li>
      <li>Improve the robustness of the SQLiteLog class when it will be initialized and unloaded multiple times.</li>
      <li>Fix the name of the interop assembly for Windows CE. Add unit tests to prevent this type of issue from happening again. Fix for <a href="http://system.data.sqlite.org/index.html/info/737ca4ff74">[737ca4ff74]</a>.</li>
      <li>Formally support the SQL type name BOOLEAN in addition to BOOL. Fix for <a href="http://system.data.sqlite.org/index.html/info/544dba0a2f">[544dba0a2f]</a>.</li>
      <li>Make sure the SQLiteConvert.TypeNameToDbType method is thread-safe. Fix for <a href="http://system.data.sqlite.org/index.html/info/84718e79fa">[84718e79fa]</a>.</li>
    </ul>
    <p><b>1.0.76.0 - October 4, 2011</b></p>
    <ul>
      <li>Prevent the domain unload event handler in SQLiteLog from being registered multiple times. Fix for <a href="http://system.data.sqlite.org/index.html/info/0d5b1ef362">[0d5b1ef362]</a>.</li>
      <li>Stop allowing non-default application domains to initialize the SQLiteLog class. Fix for <a href="http://system.data.sqlite.org/index.html/info/ac47dd230a">[ac47dd230a]</a>.</li>
    </ul>
    <p><b>1.0.75.0 - October 3, 2011</b></p>
    <ul>
      <li>Updated to SQLite 3.7.8 <a href="http://www.sqlite.org/src/info/3e0da808d2">[3e0da808d2]</a>.</li>
      <li>More enhancements to the build system.</li>
      <li>Add official <a href="http://www.nuget.org/">NuGet</a> packages for x86 and x64.</li>
      <li>Add Changes and LastInsertRowId properties to the connection class.</li>
      <li>Support more formats when converting data from/to the DateTime type.</li>
      <li>Make all the assembly versioning attributes consistent.</li>
      <li>Add unit testing infrastructure using <a href="http://eagle.to/">Eagle</a>.</li>
      <li>Integrate all legacy unit tests, including the &quot;testlinq&quot; project, into the new test suite.</li>
      <li>Add projects to build the interop assembly statically linked to the Visual C++ runtime. Fix for <a href="http://system.data.sqlite.org/index.html/info/53f0c5cbf6">[53f0c5cbf6]</a>.</li>
      <li>Add SQLITE_ENABLE_STAT2 compile-time option to the interop assembly.  Fix for <a href="http://system.data.sqlite.org/index.html/info/74807fbf27">[74807fbf27]</a>.</li>
      <li>Fix mutex issues exposed when running the test suite with the debug version of SQLite.</li>
      <li>Fix transaction enlistment when repeated attempts are made to enlist in the same transaction. Fix for <a href="http://system.data.sqlite.org/index.html/info/ccfa69fc32">[ccfa69fc32]</a>.</li>
      <li>Support the SQLITE_FCNTL_WIN32_AV_RETRY file control to mitigate the impact of file sharing violations caused by external processes.</li>
      <li>Refactor the logging interface to be thread-safe and self-initializing.</li>
      <li>Shutdown the SQLite native interface when the AppDomain is being unloaded. Fix for <a href="http://system.data.sqlite.org/index.html/info/b4a7ddc83f">[b4a7ddc83f]</a>.</li>
      <li>Support Skip operation for LINQ using OFFSET. Fix for <a href="http://system.data.sqlite.org/index.html/info/8b7d179c3c">[8b7d179c3c]</a>.</li>
      <li>Support EndsWith operation for LINQ using SUBSTR. Fix for <a href="http://system.data.sqlite.org/index.html/info/59edc1018b">[59edc1018b]</a>.</li>
      <li>Support all SQLite journal modes. Fix for <a href="http://system.data.sqlite.org/index.html/info/448d663d11">[448d663d11]</a>.</li>
      <li>Do not throw exceptions when disposing SQLiteDataReader. Fix for <a href="http://system.data.sqlite.org/index.html/info/e1b2e0f769">[e1b2e0f769]</a>.</li>
      <li>The REAL type should be mapped to System.Double. Fix for <a href="http://system.data.sqlite.org/index.html/info/2c630bffa7">[2c630bffa7]</a> and <a href="http://system.data.sqlite.org/index.html/info/b0a5990f48">[b0a5990f48]</a>.</li>
      <li>Minor optimization to GetParamValueBytes(). Fix for <a href="http://system.data.sqlite.org/index.html/info/201128cc88">[201128cc88]</a>.</li>
      <li>Support the ON UPDATE, ON DELETE, and MATCH clause information when generating schema metadata for foreign keys. Partial fix for <a href="http://system.data.sqlite.org/index.html/info/b226147b37">[b226147b37]</a>. VS designer changes are not yet tested.</li>
      <li>Fix incorrect resource name for SR.resx in the mixed-mode assembly.</li>
      <li>Reduce the number of String.Compare() calls in the hot path for SQLiteCommand.ExecuteReader().</li>
    </ul>
    <p><b>1.0.74.0 - July 4, 2011</b></p>
    <ul>
      <li>Updated to SQLite 3.7.7.1 <a href="http://www.sqlite.org/src/info/af0d91adf4">[af0d91adf4]</a>.</li>
      <li>Fix incorrect hard-coded .NET Framework version information SQLiteFactory_Linq.cs that was causing IServiceProvider.GetService to fail when running against the .NET Framework 3.5.</li>
      <li>Fix all XML documentation warnings.</li>
      <li>Restore support for the mixed-mode assembly (i.e. the one that can be registered in the Global Assembly Cache).</li>
      <li>Restore support for the Compact Framework.</li>
      <li>Remove unused &quot;using&quot; statements from the System.Data.SQLite and System.Data.SQLite.Linq projects.</li>
      <li>Remove hard-coded System.Data.SQLite.Linq version from SQLiteFactory_Linq.cs</li>
      <li>Modify the setup to support bundled packages (i.e. with the mixed-mode assembly) and standard packages (i.e. with the managed assembly separate from the native interop library).</li>
      <li>Disable the ability to register with the Global Assembly Cache in the standard setup package (i.e. it is available in the bundled setup only).</li>
      <li>Remove PATH modification from the setup.</li>
      <li>Modify the naming scheme for the source, setup, and binary packages to allow for the necessary variants.</li>
      <li>In the build automation, attempt to automatically detect if Visual Studio 2008 and/or 2010 are installed and support building binaries for both at once, when available.</li>
      <li>Add release automation to build the source, setup, and binary packages in all supported build variants.</li>
      <li>Add the testlinq project to the new build system and make it work properly with Visual Studio 2008 and 2010.</li>
    </ul>
    <p><b>1.0.73.0 - June 2, 2011</b></p>
    <ul>
      <li>Updated to SQLite 3.7.6.3 <a href="http://www.sqlite.org/src/info/ed1da510a2">[ed1da510a2]</a>.</li>
      <li>Minor optimization to GetBytes(). Fix for <a href="http://system.data.sqlite.org/index.html/info/8c1650482e">[8c1650482e]</a>.</li>
      <li>Update various assembly information settings.</li>
      <li>Correct System.Data.SQLite.Linq version and resource information. Fix for <a href="http://system.data.sqlite.org/index.html/info/6489c5a396">[6489c5a396]</a> and <a href="http://system.data.sqlite.org/index.html/info/133daf50d6">[133daf50d6]</a>.</li>
      <li>Moved log handler from SQLiteConnection object to SQLiteFactory object to prevent if from being prematurely GCed.</li>
      <li>We should block x64 installs on x86 and we should install native only if the setup package itself is native. Fix for <a href="http://system.data.sqlite.org/index.html/info/e058ce156e">[e058ce156e]</a>.</li>
    </ul>
    <p><b>1.0.72.0 - May 1, 2011</b></p>
    <ul>
      <li>Add the correct directory to the path. Fix for <a href="http://system.data.sqlite.org/index.html/info/50515a0c8e">[50515a0c8e]</a>.</li>
    </ul>
    <p><b>1.0.71.0 - April 27, 2011</b></p>
    <ul>
      <li>Updated to SQLite 3.7.6+ <a href="http://www.sqlite.org/src/info/1bd1484cd7">[1bd1484cd7]</a> to get additional Windows error logging.</li>
      <li>Updated setup to optionally add install directory to PATH if GAC option selected.</li>
    </ul>
    <p><b>1.0.69.0 - April 12, 2011</b></p>
    <ul>
      <li>Code merge with SQLite 3.7.6</li>
      <li>New VS2008 and VS2010 solution files</li>
      <li>Build and packaging automation</li>
      <li>New Inno Setup files</li>
      <li>Designer support currently not ready for release</li>
    </ul>
    <p><b>1.0.68.0 - February 2011</b></p>
    <ul>
      <li>Code merge with SQLite 3.7.5</li>
      <li>Continuing work on supporting Visual Studio 2010</li>
    </ul>
    <p><b>1.0.67.0 - January 3, 2011</b></p>
    <ul>
      <li>Code merge with SQLite 3.7.4</li>
      <li>Continuing work on supporting Visual Studio 2010</li>
    </ul>
    <p><b>1.0.66.1 - August 1, 2010</b></p>
    <ul>
      <li>Code merge with SQLite 3.7.0.1</li>
      <li>Re-enabled VS2005 designer support, broken in previous versions during the 2008 transition</li>
      <li>Implemented new forms of Take/Skip in the EF framework courtesy jlsantiago</li>
      <li>Added "Foreign Keys" to the connection string parameters</li>
      <li>Added the Truncate option to the Journal Modes enumeration</li>
    </ul>
    <p><b>1.0.66.0 - April 18, 2010</b></p>
    <ul>
      <li>Code merge with SQLite 3.6.23.1</li>
      <li>Fixed a bug in the installer that accidentally modified the machine.config on .NET versions prior to 2.0, invaliding the config file.</li>
      <li>Fixed INTERSECT and EXCEPT union query generation in EF</li>
      <li>Fixed an out of memory error in the trigger designer in cases where a WHEN clause is used in the trigger</li>
    </ul>
    <p><b>1.0.65.0 - July 26, 2009</b></p>
    <ul>
      <li>Fixed a bug in the encryption module to prevent a double free() when rekeying a database.</li>
      <li>Fixed a bug in the encryption module when ATTACHing an encrypted database.</li>
      <li>Incorporated the WinCE locking fix from ticket
        <a href="http://www.sqlite.org/cvstrac/tktview?tn=3991">#3991</a></li>
      <li>Added &quot;bigint&quot; to the dropdown in the table designer, plus other minor table
        designer bugfixes.</li>
    </ul>
    <p><b>1.0.64.0 - July 9, 2009</b></p>
    <ul>
      <li>Fixed the missing resources problem from the 63 release.</li>
      <li>Added preliminary support for the Visual Studio 2010 beta.</li>
      <li>Fixed a bug in SQLiteCommand that threw a null reference exception when
        setting the Transaction object to null.</li>
      <li>If SQLiteConnection.EnlistTransaction is called multiple times for the same
        transaction scope, just return without throwing an error.</li>
    </ul>
    <p><b>1.0.63.0 - June 29, 2009</b></p>
    <ul>
      <li>Code merge with SQLite 3.6.16</li>
      <li>Check the autocommit mode of the connection to which a transaction is bound
        during the disposal of the transaction.&nbsp; If autocommit is enabled, then the
        database has already rolled back the transaction and we don&#39;t need to do it
        during dispose, and can quietly ignore the step without throwing an error.</li>
      <li>Eliminated the mergebin step altogether.&nbsp; It was developed primarily to
        merge the Compact Framework binaries together, but since we&#39;re not doing that
        anymore, its use is limited.&nbsp; Its non-standard method of merging a binary
        on the desktop framework is redundant as well.&nbsp; The desktop binary now
        hard-links to MSCOREE, but as of Windows XP, this was redundant as well since XP
        and beyond automatically attempt to load MSCOREE on startup when a DLL has a
        .NET header.</li>
      <li>More improvements to the test.exe program for running the tests against Sql
        Server for comparison purposes.</li>
    </ul>
    <p><b>1.0.62.0 - June 20, 2009</b></p>
    <ul>
      <li>Code merge with SQLite 3.6.15</li>
      <li>Fixed the decimal reading bug in the SQLiteDataReader</li>
      <li>Changed Join()&#39;s to Sleep()&#39;s in the statement retry code to prevent message
        pumping</li>
      <li>Fixed a bad pointer conversion when retrieving blobs using GetBytes() in
        64-bit land</li>
      <li>Several changes to the Test program that comes with the provider.&nbsp; Tests
        can now be individually disabled, and the test program can run against several
        provider back-ends</li>
    </ul>
    <p><b>1.0.61.0 - April 28, 2009</b></p>
    <ul>
      <li>Code merge with SQLite 3.6.13.  The new backup features are as yet unimplemented in the provider, but will be forthcoming in a subsequent release</li>
      <li>Fixed the default-value lookups in SQLiteConnectionStringBuilder when accessing properties</li>
      <li>Lock the SQLiteTransaction object during dispose to avoid potential race condition during cleanup</li>
      <li>Fixed SQLiteDataReader.GetDecimal() processing and parsing of decimal values for cases when SQLite returns things like "1.0e-05" instead of "0.0001"</li>
    </ul>
    <p><b>1.0.60.0 - October 3, 2008</b></p>
    <ul>
      <li>Throw a NotSupported exception in the EF Sql Gen code instead of parsing
        illegal SQL during an update/insert/delete where no primary key is defined.</li>
      <li>Fixed the Compact Framework interop library.&nbsp; Since the linker flag
        /subsystem had no version specified, it was causing a problem for many CE-based
        platforms.</li>
      <li>Incorporated SQLite patch for ticket
        <a href="http://www.sqlite.org/cvstrac/tktview?tn=3387">#3387</a> and reverted
        out the vfs override code I added in build 59 to work around this problem.</li>
      <li>Fixed a designer issue when creating a new table from the Server Explorer.&nbsp;
        After initially saving it, if you then continued to edit it and tried to save it
        again, it would generate the change SQL using the old temporary table name
        rather than the new name.</li>
    </ul>
    <p><b>1.0.59.0 - September 22, 2008</b></p>
    <ul>
      <li>Code merge with SQLite 3.6.3.&nbsp; Solves
        a couple different EF issues that were either giving inconsistent results or
        crashing the engine.</li>
      <li>Fixed the parsing of literal binaries in the EF SqlGen code.&nbsp; SQLite now
        passes nearly all the testcases in
        <a href="http://sqlite.phxsoftware.com/forums/p/1377/5921.aspx#5921">Microsoft's EF Query Samples</a> application --
        the exception being the <i>datetimeoffset </i>and<i> time</i> constants tests, and tests
        that use the <i>APPLY </i>keyword which are unsupported for now.</li>
      <li>Revamped the Compact Framework mixed-mode assembly.&nbsp; Tired of playing cat
        and mouse with the Compact Framework&#39;s support for mixed-mode assemblies.&nbsp;
        The CF build now requires that you distribute both the System.Data.SQLite
        library and the paired SQLite.Interop.XXX library.&nbsp;&nbsp; The XXX denotes
        the build number of the library.</li>
      <li>Implemented a workaround for Vista&#39;s overzealous caching by turning off
        FILE_FLAG_RANDOM_ACCESS for OS versions above XP.&nbsp; This is implemented
        as a custom (default override) VFS in the interop.c file, so no changes are made
        to the SQLite source code.</li>
      <li>Fixed some registry issues in the designer install.exe, which prevented some
        design-time stuff from working on the Compact Framework when .NET 3.5 was
        installed.</li>
    </ul>
    <p><b>1.0.58.0 - August 30, 2008</b></p>
    <ul>
      <li>Code merge with SQLite 3.6.2.&nbsp; If only I&#39;d waited one more day to release
        57!&nbsp; Several LINQ issues have been resolved with this engine release
        relating to deeply-nested subqueries that the EF SqlGen creates.</li>
      <li>Fixed the Rollback SQLiteConnection event to not require a connection be
        opened first.</li>
    </ul>
    <p><b>1.0.57.0 - August 29, 2008</b></p>
    <ul>
      <li>Compiled against 3.6.1 with checkin
        <a href="http://www.sqlite.org/cvstrac/tktview?tn=3300">#3300</a> resolved,
        which fixes an Entity Framework bug I was seeing.&nbsp; I currently have 3 other
        tickets out on the engine, which are not yet resolved and relate to EF.</li>
      <li>Fixed decimal types to store and fetch using InvariantCulture.&nbsp; If you&#39;re
        using decimal datatypes in your database and were affected by the 56 release,
        please issue an UPDATE &lt;table&gt; SET &lt;column&gt; = REPLACE(&lt;column&gt;, &#39;,&#39;, &#39;.&#39;);&nbsp;
        to fix the decimal separators.&nbsp; Apologies for not testing that more
        thoroughly before releasing 56.</li>
      <li>Too many LINQ fixes to list.&nbsp; Fixed views so they generate,
        fixed the LIMIT clause, implemented additional functionality and removed unnecessary code.</li>
      <li>Fixed foreign key names in the designer so viewing the SQL script on a new
        unsaved table after renaming it in the properties toolwindow will reflect in the
        script properly.</li>
      <li>Fixed the Update and Commit events on SQLiteConnection so they don&#39;t require
        the connection to be opened first.</li>
      <li>Fixed userdef aggregate functions so they play nice with each other when
        appearing multiple times in the same statement.</li>
      <li>Fixed the editing and saving of default values in the table designer.</li>
      <li>Fixed ForeignKeys schema to support multi-column foreign keys.&nbsp; Also
        hacked support for them in the table designer, provided two foreign keys in the
        designer have the same name and reference the same foreign table and different
        columns.&nbsp; Will implement first-class support for this in the next release.</li>
    </ul>
    <p><b>1.0.56.0 - August 11, 2008</b></p>
    <ul>
      <li>Fixed a bug in the table designer when designing new tables, wherein you had to
        save the table first before being able to create indexes and foreign keys.</li>
      <li>Tweaks to decimal type handling.&nbsp; The &#39;decimal&#39; type can&#39;t be represented
        by Int64 or Double (without loss of precision) in SQLite, so we have to fudge it
        by treating it like a string and converting it back and forth in the provider.&nbsp;
        Unfortunately backing it to the db as a string causes sorting problems.&nbsp;
        See <a href="http://sqlite.phxsoftware.com/forums/p/1296/5595.aspx#5595">this
        post</a>
        for details on using a custom collation sequence to overcome the sorting issue arising from this patch.</li>
      <li>Minor tweaks and bugfixes to the test program and the provider.</li>
      <li>More adjustments to make the managed-only version of the provider run and pass
        all tests on Mono.</li>
      <li>LINQ to Entities bits heavily updated and compiled against VS2008 SP1 RTM.&nbsp; SQLite
        LINQ support is still considered beta.</li>
    </ul>
    <p><b>1.0.55.0 - August 6, 2008</b></p>
    <ul>
      <li>Code merge with SQLite 3.6.1</li>
      <li>Added support for the user-contributed extension-functions at
        <a href="http://www.sqlite.org/contrib">http://www.sqlite.org/contrib</a>.&nbsp;
        Feel free to override any of them with your own implementation.&nbsp; The new
        functions are: <i>acos, asin, atan, atn2, atan2, acosh, asinh, atanh,
        difference, degrees, radians, cos, sin, tan, cot, cosh, sinh, tanh, coth, exp,
        log, log10, power, sign, sqrt, square, ceil, floor, pi, replicate, charindex,
        leftstr, rightstr, reverse, proper, padl, padr, padc, strfilter,</i> and
        aggregates <i>stdev, variance, mode, median, lower_quartile, upper_quartile.</i></li>
      <li>Moved the last_rows_affected() function to the C extension library.</li>
      <li>Added a new class, SQLiteFunctionEx which extends SQLiteFunction and adds the
        ability for a user-defined function to get the collating sequence during the
        Invoke/Step methods.&nbsp; User-defined functions can use the collating sequence
        as a helper to compare values.</li>
      <li>When registering user-defined collation sequences and functions, the provider
        will now register both a UTF8 and a UTF16 version instead of just UTF8.</li>
      <li>Revamped connection pooling and added static ClearPool() and ClearAllPools()
        functions to SQLiteConnection.&nbsp; Behavior of the pool and its clearing
        mechanics match SqlClient.</li>
      <li>Fixed connections going to the pool so that any unfinalized lingering commands
        from un-collected datareaders are automatically reset and any lurking
        transactions made on the connection are rolled back.</li>
      <li>Transaction isolation levels are now partially supported.&nbsp; Serializable
        is the default, which obtains read/write locks immediately -- this is compatible
        with previous releases of the provider.&nbsp; Unspecified will default to
        whatever the default isolation mode is set to, and ReadCommitted will cause a
        deferred lock to be obtained.&nbsp; No other values are legal.</li>
      <li>Revamped the test.exe program.&nbsp; It&#39;s now an interactive GUI application.&nbsp;
        Easier for me to add tests now.</li>
      <li>Tweaks to the VS designer package and installer.</li>
      <li>More adjustments to the internal SQLite3.Prepare() method to account for both
        kinds of lock errors when retrying.</li>
      <li>Stripped a lot of unnecessary interop() calls and replaced with base sqlite calls.&nbsp;
        Revamped most of UnsafeNativeMethods to make it easier to port the code.</li>
      <li>Rerigged internal callbacks for userdef functions and other native to managed
        callbacks.&nbsp; More portable this way.</li>
      <li>Source can now can be compiled with the SQLITE_STANDARD preprocessor symbol to
        force the wrapper to use the stock sqlite3 library.&nbsp; Some functionality is
        missing, but its minimal.&nbsp; None of the precompiled binaries are compiled
        using this setting, but its useful for testing portability.</li>
      <li>Added &quot;boolean&quot; and a couple other missing datatypes to the &quot;DataTypes&quot; schema
        xml file.&nbsp; Used by the VS designer when displaying tables and querying.</li>
      <li>Added a new connection string option &quot;Read Only&quot;.&nbsp; When set to True, the
        database will be opened in read-only mode.</li>
      <li>Added a new connection string option &quot;Max Pool Size&quot; to set the maximum size
        of the connection pool for a given db file connection.</li>
      <li>Added a new connection string option &quot;Default IsolationLevel&quot; to set the
        default isolation level of transactions.&nbsp; Possible values are Serializable and
        ReadCommitted.</li>
      <li>Added a new connection string option &quot;URI&quot; as an optional parameter for
        compatibility with other ports of the provider.</li>
    </ul>
    <p><b>1.0.54.0 - July 25, 2008</b></p>
    <ul>
      <li>Fixed the setup project, which somehow &quot;forgot&quot; to include all the binaries in
        the 53 release.</li>
      <li>Fixed a crash in the table designer when creating a new table and tabbing past
        the &quot;Allow Nulls&quot; cell in the grid while creating a new column.</li>
      <li>Fixed a mostly-benign bug in SQLiteDataReader&#39;s GetEnumerator, which failed to
        pass along a flag to the underyling DbEnumerator it creates.&nbsp; This one&#39;s
        been around since day 1 and nobody&#39;s noticed it in all these years.</li>
      <li>Added a new connection string parameter &quot;Journal Mode&quot; that allows you to set
        the SQLite journal mode to Delete, Persist or Off.</li>
    </ul>
    <p><b>1.0.53.0 - July 24, 2008</b></p>
    <ul>
      <li>Enabled sqlite_load_extension</li>
      <li>Added retry/timeout code to SQLite3.Prepare() when preparing statements for
        execution and a SQLITE_BUSY error occurs.</li>
      <li>Added a new schema to SQLiteConnection.GetSchema() called <i>Triggers</i>.&nbsp;
        Used to retrieve the trigger(s) associated with a database and/or table/view.</li>
      <li>Extensive updates to table/view editing capabilities inside Visual Studio&#39;s
        Server Explorer.&nbsp; The program now parses and lets you edit CHECK constraints and
        triggers on a table, as well as define triggers on views.&nbsp; Experimental
        still, so e-mail me if you have issues.</li>
      <li>Minor bugfix to the ViewColumns schema to return the proper base column name
        for a view that aliases a column.</li>
      <li>Fixed the insert/update/delete DML support in the Linq module.</li>
      <li>Changed the behavior of SQLiteCommand to allow a transaction to be set even if
        the command hasn&#39;t been associated with a connection yet.</li>
    </ul>
    <p><b>1.0.52.0 - July 16, 2008</b></p>
    <ul>
      <li>Code merge with SQLite 3.6.0</li>
      <li>Added a lot of previously-missing exports to the DEF file for the
        native library.</li>
      <li>Fixed SQLiteDataReader to check for an invalid connection before operating on
        an open cursor.</li>
      <li>Implemented the Cancel() function of SQLiteCommand to cancel an active reader.</li>
      <li>Added beta table and view designers to the Visual Studio Server Explorer.&nbsp; You can now
        edit/create tables and views, manage indexes and foreign keys from Visual Studio.&nbsp;
        This feature is still undergoing testing so use at your own risk!</li>
      <li>Fixed the Server Explorer so VS2005 users can once again right-click tables
        and views and open the table data.</li>
      <li>Added some new interop code to assist in returning more metadata not normally
        available through the SQLite API.&nbsp; Specifically, index column sort modes
        and collating sequences.&nbsp; Also added code to detect (but not parse) CHECK
        constraints, so the table designer can pop up a warning when editing a table
        with these constraints.&nbsp; Since I can&#39;t currently parse them.</li>
      <li>Lots of LINQ SQL generation improvements and fixes.</li>
      <li>Made some progress cleaning up and fixing up the schema definitions and
        manifests for EdmGen.</li>
      <li>Added a built-in SQLiteFunction called last_rows_affected() which can be
        called from SQL to get the number of rows affected by the last update/insert
        operation on the connection.&nbsp; This is roughly equivalent to Sql Server&#39;s
        @@ROWCOUNT variable.</li>
    </ul>
    <p><b>1.0.51.0 - July 1, 2008</b></p>
    <ul>
      <li><b>VS2008 SP1 Beta1 LINQ Support</b></li>
      <li>Added experimental Entity Framework support in a new library,
        System.Data.SQLite.Linq.&nbsp; Some things work, some don&#39;t.&nbsp; I haven&#39;t
        finished rigging everything up yet.&nbsp; The core library remains stable.&nbsp;
        All LINQ-specific code is completely separate from the core.</li>
      <li>&nbsp;Added some columns to several existing schemas to support some of the
        EDM framework stuff.</li>
      <li>Minor tweaks to the factory to better support dynamic loading of the Linq
        extension library for SQLite.</li>
      <li>SQLite&#39;s busy handler was interfering with the provider&#39;s busy handling
        mechanism, so its been disabled.</li>
    </ul>
    <p><b>1.0.50.0 - June 27, 2008</b></p>
    <ul>
      <li>Fixed some lingering dispose issues and race conditions when some objects were finalized.</li>
      <li>Fixed the SQLiteConvert.Split() routine to be a little smarter when splitting
        strings, which solves the quoted data source filename problem.</li>
      <li>Enhanced the mergebin utility to work around the strong name validation bug on
        the Compact Framework.&nbsp; The old workaround kludged the DLL and caused WM6.1
        to fail to load it.&nbsp; This new solution is permanent and no longer kludges
        the DLL.</li>
    </ul>
    <p><b>1.0.49.0 - May 28, 2008</b></p>
    <ul>
      <li>Code merge with SQLite 3.5.9</li>
      <li>Fixed schema problems when querying the TEMP catalog.</li>
      <li>Changed BLOB datatype schema to return IsLong = False instead of True.&nbsp; This
        was preventing DbCommandBuilder from using GUID's and BLOB's as primary keys.</li>
      <li>Fix rollover issue with SQLite3.Reset() using TickCount.</li>
      <li>Fixed SQLiteDataReader to dispose of its command (if called for) before
        closing the connection (when flagged to do so) instead of the other way around.</li>
      <li>Fixed a DbNull error when retrieving items not backed by a table schema.</li>
      <li>Fixed foreign key constraint parsing bug.</li>
      <li>Added FailIfMissing property to the SQLiteConnectionStringBuilder.</li>
      <li>Converted the source projects to Visual Studio 2008.</li>
    </ul>
    <p><b>1.0.48.0 - December 28, 2007</b></p>
    <ul>
      <li>Code merge with SQLite 3.5.4</li>
      <li>Calling SQLiteDataReader.GetFieldType() on a column with no schema information
        and whos first row is initially NULL now returns type Object instead of type DbNull.</li>
      <li>Added support for a new DateTime type, JulianDay.&nbsp; SQLite uses Julian dates
        internally.</li>
      <li>Added a new connection string parameter "Default Timeout" and a corresponding
        method on the SQLiteConnection object to change the default command timeout.&nbsp;
        This is especially useful for changing the timeout on transactions, which use SQLiteCommand
        objects internally and have no ADO.NET-friendly way to adjust the command timeout
        on those commands.</li>
      <li>FTS1 and FTS2 modules were removed from the codebase.&nbsp; Please upgrade all
        full-text indexes to use the FTS3 module.&nbsp;</li>
    </ul>
    <p><b>1.0.47.2 - December 10, 2007</b></p>
    <ul>
      <li>Fixed yet one more bug when closing a database with unfinalized command objects</li>
      <li>Fixed the DataReader's GetFieldType function when dealing with untyped SQLite affinities</li>
    </ul>
    <p><b>1.0.47.1 - December 5, 2007</b></p>
    <ul>
      <li>Fixed a leftover bug from the codemerge with SQLite 3.5.3 that failed to close a database.</li>
      <li>Fixed the broken Compact Framework distribution binary.</li>
      <li>SQLite 3.5.x changed some internal infrastructure pieces in the encryption interface
        which I didn't catch initially.&nbsp; Fixed.&nbsp;</li>
    </ul>
    <p><b>1.0.47.0 - December 4, 2007</b></p>
    <ul>
      <li>Code merge with SQLite 3.5.3</li>
      <li>Added installer support for Visual Studio 2008.&nbsp; Code is still using the
        VS2005 SDK so one or two bells and whistles are missing, but nothing significant.</li>
      <li>This is the last version that the FTS1 and FTS2 extensions will appear.&nbsp;
        Everyone should rebuild their fulltext indexes using the new FTS3 module.&nbsp;
        FTS1 and FTS2 suffer from a design flaw that could cause database corruption with
        certain vacuum operations.</li>
      <li>Fixed pooled connections so they rollback any outstanding transactions before
        going to the pool.&nbsp; </li>
      <li>Fixed the unintended breaking of the TYPES keyword, and mis-typing of untyped
        or indeterminate column types. </li>
      <li>Assert a FileIOPermission() requirement in the static SQLiteFunction constructor.
      </li>
      <li>The CE-only SQLiteFunction.RegisterFunction() is now available on the desktop
        platform for dynamic registration of functions.&nbsp; You must still close and re-open
        a connection in order for the new function to be seen by a connection.</li>
      <li>Fixed the "database is locked" errors by implementing behavioral changes in the
        interop.c file for SQLite.&nbsp; Closing a database force-finalizes any prepared
        statements on the database to ensure the connection is fully closed.&nbsp; This
        was rather tricky because the GC thread could still be finalizing statements itself.
        &nbsp;</li>
      <li>Modifed the mergebin utility to help circumvent a long-standing strong name verification
        bug in the Compact Framework.</li>
    </ul>
    <p><b>1.0.46.0 - September 30, 2007</b></p>
    <ul>
    <li>Fixed faulty logic in type discovery code when using SQLiteDataReader.GetValue().</li>
      <li>Fixed Connection.Open() bug when dealing with :memory: databases.</li>
      <li>Fixed SQLiteCommand.ExecuteScalar() to return a properly-typed value.</li>
      <li>Added support for SQLiteParameter.ResetDbType().</li>
      <li>Added test cases for rigid and flexible type testing.</li>
    </ul>
    <p><b>1.0.45.0 - September 25, 2007</b></p>
    <ul>
    <li><strong>Breaking change in GetSchema("Indexes") </strong>-- MetaDataCollections
      restrictions and identifier parts counts were wrong for this schema and I was using
      the wrong final parameter as the final restriction.&nbsp; Meaning, if you use the
      Indexes schema and are querying for a specific index the array should now be {catalog,
      null, table, index } instead of {catalog, null, table, null, index}</li>
      <li>Fixed some errors in the encryption module, most notably when a non-default page
        size is specified in the connection string.</li>
      <li>Fixed SQLiteDataReader to better handle type-less usage scenarios, which also
        fixes problems with null values and datetimes.</li>
      <li>Fixed the leftover temp files problem on WinCE </li>
      <li>Added connection pooling.&nbsp; The default is disabled for now, but may change
      in the future.&nbsp; Set "Pooling=True" in the connection string to enable it. </li>
      <li>Sped up SQLiteConnection.Open() considerably.</li>
      <li>Added some more robust cleanup code regarding SQLiteFunctions.</li>
      <li>Minor additions to the code to allow for future LINQ integration into the main
        codebase.</li>
      <li>Fixed a long-standing bug in the Open() command of SQLiteConnection which failed
      to honor the documented default behavior of the SQLite.NET provider to open the
      database in "Synchronous=Normal" mode.&nbsp; The default was "Full". </li>
      <li>If Open() fails, it no longer sets the connection state to Broken.&nbsp; It instead
        reverts back to Closed, and cleans up after itself.</li>
      <li>Added several new parameters to the ConnectionString for setting max page count,
        legacy file format, and another called FailIfMissing to raise an error rather than
        create the database file automatically if it does not already exist.</li>
      <li>Fixed some designer toolbox references to the wrong version of the SQLite.Designer</li>
      <li>Fixed a bug in the mergebin utility with regards to COR20 metadata rowsize computations.&nbsp;
      </li>
      <li>Minor documentation corrections &nbsp;&nbsp;</li>
    </ul>
    <p><b>1.0.44.0 - July 21, 2007</b></p>
    <ul>
    <li>Code merge with SQLite 3.4.1</li>
      <li>Fixed a bug in SQLiteConnection.Open() which threw the wrong kind of error in
        the wrong kind of way when a database file could not be opened or created.&nbsp;</li>
      <li>Small enhancements to the TYPES keyword, and added documentation for it in the
        help file.</li>
      <li>Hopefully fixed the occasional SQLITE_BUSY errors that cropped up when starting
        a transaction.&nbsp; Usually occurred in high-contention scenarios, and the underlying
        SQLite engine bypasses the busy handler in this scenario to return immediately.</li>
    </ul>
    <p><b>1.0.43.0 - June 21, 2007</b></p>
    <ul>
    <li>Code merge with SQLite 3.4.0</li>
      <li>Fixed a reuse bug in the SQLiteDataAdapter in conjunction with the SQLiteCommandBuilder.&nbsp;
      It's been there unnoticed for more than a year, so it looks like most folks never
      encountered it. </li>
      <li>Fixed an event handler bug in SQLiteCommandBuilder in which it could fail to unlatch
        from the DataAdapter when reused.&nbsp; Relates to the previous bugfix.</li>
      <li>Fixed a double-dispose bug in SQLiteStatement that triggered a SQLiteException.&nbsp;</li>
    </ul>
    <p><b>1.0.42.0 - June 1, 2007</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.17</li>
      <li>Changed the SQLiteFunction static constructor so it only enumerates loaded modules
        that have referenced the SQLite assembly, which hopefully should cut down dramatically
        the time it takes for that function to execute.&nbsp;</li>
      <li>Added the FTS2 full-text search extension to the project.&nbsp; Look for FTS1
        to disappear within the next couple of revisions.&nbsp;</li>
      <li>Fixed a bug introduced with the finalizers that triggered an error when statements
        ended with a semi-colon or had other non-parsable comments at the end of a statement&nbsp;</li>
      <li>Fixed an intermittent multi-threaded race condition between the garbage collector
        thread and the main application thread which lead to an occasional SQLITE_MISUSE
        error.</li>
      <li>Fixed another issue relating to SQLite's inherent typelessness when dealing with
        aggregate functions which could return Int64 or Double or even String for a given
        row depending on what was aggregated.</li>
      <li>Remembered to recompile the DDEX portion of the engine this time, so Compact Framework
        users can once again use the design-time functionality</li>
    </ul>
    <p><b>1.0.41.0 - April 23, 2007</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.16</li>
      <li>Second go at implementing proper finalizers to cleanup after folks who've forgotten to Dispose() of the SQLite objects</li>
      <li>Enhanced GetSchema(IndexColumns) to provide numeric scale and precision values</li>
      <li>Fixed the column ordinals in GetSchema(IndexColumns) to report the ordinal of the column in the index, not the table</li>
      <li>Fixed a bug whereby parameters named with an empty string (such as String.Empty) were treated like a named parameter instead of an unnamed parameter</li>
    </ul>
    <p><b>1.0.40.0 - January 31, 2007</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.12</li>
      <li>Lots of new code to handle misuse of the library.&nbsp; Implemented finalizers
        where it made sense, fixed numerous garbage collector issues when objects are not
        disposed properly, &nbsp;fixed some object lifetime issues, etc.</li>
      <li>A failed Commit() on a transaction no longer leaves the transaction in an unusable
        state.</li>
    </ul>
    <p><b>1.0.39.1 - January 11, 2007</b></p>
    <ul>
    <li>Fixed a really dumb mistake that for some reason didn't trigger any errors in
      the testcases, whereby commands when associated with a connection were not adding
      or removing themselves from an internal list of commands for that connection --
      causing a "database is locked" error when trying to close the connection.</li>
    </ul>
    <p><b>1.0.39.0 - January 10, 2007</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.10</li>
      <li>Fixed a multi-threaded race condition bug in the garbage collector when commands
        and/or connections are not properly disposed by the user.</li>
      <li>Switched the encryption's internal deallocation code to use sqlite's built-in
        aux functions instead of modifying the pager.c source to free the crypt block.&nbsp;
        This eliminates the last of the code changes the provider makes to the original
        sqlite engine sources.&nbsp; Props to Ralf Junker for pointing that out.</li>
    </ul>
    <p><b>1.0.38.0 - November 22, 2006</b></p>
    <ul>
    <li>Fixed a bug when using CommandBehavior.KeyInfo whereby integer primary key columns may be duplicated in the results. </li>
      <li>Enhanced the CommandBuilder so that update/delete statements are optimized when the affected table contains unique constraints and
      a primary key is present.</li>
      <li>Fixed a bug in the DataReader when used in conjunction with CommandBehavior.CloseConnection.</li></ul>
    <p><b>1.0.37.0 - November 19, 2006</b></p>
    <ul>
    <li>Added support for CommandBehavior.KeyInfo.&nbsp;
      When specified in a query, additional column(s) will be returned describing the
      key(s) defined for the table(s) selected in the query.&nbsp; This is optimized when
      INTEGER PRIMARY KEY is set for the given tables, but does additional work for other
      kinds of primary keys.</li>
      <li>Removed the default values from SQLiteDataReader.GetTableSchema(), to better follow
        Sql Server's pattern and suppress schema errors when loading the records into a
        dataset/datatable.</li>
      <li>Allow integers to implicitly convert to double/decimal/single.</li></ul>
    <p><b>1.0.36.1 - October 25, 2006</b></p>
    <ul>
    <li>Added support for LONGVARCHAR, SMALLDATE and SMALLDATETIME.  These were actually added in 1.0.36.0 but were undocumented.</li>
    <li>Fixed the embedded helpfile which was accidentally built from old sources. </li>
    <li>Fixed an unfortunate re-entry of a bug in the .36 codebase that caused the provider to "forget" about commands on a connection under certain circumstances.</li>
    </ul>
    <p><b>1.0.36.0 - October 23, 2006</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.8, including support for full-text search via the FTS1
      extension.&nbsp;</li><li>Fixed a bug retrieving data types when UseUtf16Encoding is true.  Side-effect of further merging the common code between the two base classes.</li>
      <li>Fixed a bug with System.Transactions whereby a connection closed/disposed within
        a transaction scope is rolled back and cannot be committed.</li>
      <li>Added more error checking and reporting to transactions to help user's isolate
        the source of transaction failures.</li>
      <li>Implemented a workaround for a Compact Framework issue regarding strong-named
        assemblies containing a PE section with a raw size less than the virtual size.&nbsp;</li>
    </ul>
    <p><b>1.0.35.1 - September 12, 2006</b></p>
    <ul>
    <li>Fixed the TYPES keyword to work when UseUTF16Encoding is true.</li>
    <li>Fix another bug revealed in 1.0.35.0 regarding infinite loops when the 2nd or subsequent statements of a semi-colon separated command cannot be parsed.</li>
      <li>Updated the help documentation.&nbsp;</li>
    </ul>
    <p><b>1.0.35.0 - September 10, 2006</b></p>
    <ul>
    <li>Fixed an infinite loop bug in SQLiteCommand caused when multiple semi-colon separated
      statements in a single command are executed via datareader and one of the statements
      contains a syntax error preventing it from being prepared.&nbsp;</li><li>Added the TYPES preparser keyword to be placed before a SELECT statement to
    aid the wrapper in converting expressions in a subsequent select clause into more
    robust types.&nbsp; Documentation yet to be integrated, but available on the forums.</li>
      <li>Added a new connectionstring parameter "BinaryGUID=true/false" (default is "true").&nbsp;
        When true, guid types are stored in the database as binary blobs to save space.&nbsp;
        Binary has been the default format since 1.0.32.0 but this parameter eases backward
        compatibility.</li>
    </ul>
    <p><b>1.0.34.0 - September 4, 2006</b></p>
    <ul>
    <li>Fixed a bug in SQLiteParameterCollection.RemoveAt(namedparam)</li>
    <li>Fixed a bug in SQLiteDataReader introduced in 1.0.30 that broke DateTimes using the Ticks option in the connection string.</li>
      <li>Fixed a bug in the recent changes to guid behavior wherein using a datareader's
        indexer to fetch a guid from a column containing both binary and text guids would
        sometimes return a byte array instead of a guid.</li>
      <li>Enacted a workaround involving typed datasets in Compact Framework projects in
        which it took an excessive amount of time to open a form and generated a lot of
        temporary files in the user's Local Settings\Application Data\Microsoft\VisualStudio\8.0\Assembly
        References folder.</li>
    </ul>
     <p><b>1.0.33.0 - August 21, 2006</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.7</li>
      <li>Fixed a bug in SQLiteConnection that caused it to "forget" about commands bound
      to it and occasionally throw an error when a database is closed and opened repeatedly.&nbsp;
      </li>
    </ul>
<p><b>1.0.32.0 - August 6, 2006</b></p>
    <ul>
    <li>Added AllowPartiallyTrustedCallers attribute to the assembly</li><li>Added the missing "nchar" type</li>
      <li>Added support for binary Guid's.&nbsp; Guids are now stored as binary by default
        when using parameterized queries.&nbsp; Text guids are still fully supported.</li>
      <li>Fixed a TransactionScope() error that caused the transaction not to be completed.</li>
      <li>Enhanced parameter names so that if they are added to the Parameters collection
        without their prefix character (@ : or $) they are still properly mapped.&nbsp;</li>
    </ul>
        <p><b>1.0.31.0 - July 16, 2006</b></p>
    <ul>
    <li>Re-applied the view parsing bugfix in 1.0.29.0 that was accidentally reverted
      out of the 30 build.</li><li>Fixed SQLiteCommand.ExecuteScalar() to return null instead of DbNull.Value
    when no rows were returned.</li>
      <li>Design-time installer now installs the package-based designer on full Visual Studio
        versions.&nbsp; Express editions continue to use the packageless designer.</li>
      <li>In Visual Studio (not Express), you can now right-click a SQLite connection in
        the Server Explorer and vacuum the database and change the encryption password.</li>
    </ul>
    <p><b>1.0.30.1 - July 2, 2006</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.6</li>
      <li>Added support for the |DataDirectory| keyword in the Data Source filename string.&nbsp;
      </li>
      <li>Added hook notification support to SQLiteConnection.&nbsp; Specifically, there
      are three new events on the SQLiteConnection object which are raised when an update/insert/delete
      occurs and when transactions are committed and rolled back.</li><li>Changed SQLiteTransaction to default to BEGIN IMMEDIATE instead of just BEGIN,
    which solves a multithreaded race condition.&nbsp;</li>
      <li>Changed SQLiteDataReader to better support SQLite's typelessness.&nbsp; The data
        reader no longer caches column affinity, but re-evaluates it for each column/row.</li>
      <li>Fixed a bug in Prepare() which caused an intermittant fault due to the code accessing
        the memory of an unpinned variable.&nbsp;</li>
      <li>Fixed a multithreaded lock-retry bug in in SQLiteConnection.Open() and in
    SQLiteTransaction, which failed to use a command timeout before giving up.</li>
    </ul>

    <p><b>1.0.29.0 - May 16, 2006</b></p>
    <ul>
    <li>Fixed a bug in the Views schema information which caused multi-line view definition statements not to be parsed</li>
    <li>Fixed a parsing bug in SQLiteDataReader.GetSchemaTable() to account for numeric(x,y) datatypes with specified precision and scale</li>
    <li>Fixed a bug in SQLiteConnection.Open() which tried to automatically enlist in an ambient transaction but had not yet set the state of the database to Opened, thereby causing a transaction fault</li>
    <li>Changed SQLiteException to inherit from DbException on the full framework</li>
    </ul>
    <p><b>1.0.28.0 - April 14, 2006</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.5</li>
      <li>You can now specify a relative path in the Compact Framework's "Data Source" by
        prefixing the file with ".\".&nbsp; i.e. "Data Source=.\\mydb.db3"</li>
      <li>Several more changes and enhancements to schemas for better compatibility.</li>
      <li>Fixed several bugs with the 64-bit builds of the provider.&nbsp; The x64 binary
        is now optimized.</li>
      <li>Design-time installer now tries to install the 64-bit builds into the GAC along
        with the 32-bit build.</li>
      <li>Fixed a bug in the SQLiteDataReader.GetSchemaTable() function when used with tables
        containing apostrophes.</li>
      <li>Fixed an XSD-related bug whereby the XSD utility was unable to locate the provider
        and could not generate typed datasets.</li>
      <li>Added NTEXT and STRING datatypes to the list of recognized keywords (used for
        schema retrieval).</li>
      <li>Due to the XSD bug and other potential problems related to external build utilities,
        changes to the installation of the designer have had to be made.&nbsp; The installer
        used to write the DbProviderFactories XML into the devenv.exe.config file and its
        express cousins, but now has to write instead to the machine.config.</li>
      <li>Installer writes to both the 32-bit machine.config and the 64-bit machine.config
        if it exists.&nbsp;</li>
    </ul>
    <p><b>1.0.27.1 - February 28, 2006</b></p>
    <ul>
    <li>Fixed a bug when doing data binding in Compact Framework projects that prevented
      you from assigning a typed dataset to a bindingsource.&nbsp; It turns out, the CF
      version of the SQLite provider needs to be flagged as retargetable so it'll work
      in the design-time desktop environment.&nbsp; No changes were made to the desktop
      build, but the revision was bumped on all libraries anyway in order to keep them
      sync'd.&nbsp;</li></ul>
    <p><b>1.0.27.0 - February 27, 2006</b></p>
    <ul>
    <li>Many optimizations and a few more minor adjustments to schemas and schema retrieval
      performance.</li>
      <li>Lots of design-time attributes added to the code.&nbsp; The DbDataAdapter, DbCommand,
        and DbConnection objects now have greatly enhanced design-time capabilities when
        added to the toolbox and dropped on a form.</li>
      <li>Lots of Server Explorer enhancements.</li>
      <li>Binaries are now distributed in a setup program for easier administration and
        configuration of the provider.</li>
    </ul>
    <p><b>1.0.26.2 - February 15, 2006</b></p>
    <ul>
    <li>Yet another bugfix to index schemas, which was incorrectly marking most indexes
      as primary key indexes.</li><li>Fixed GetSchema() to accept a null string array.</li><li>Fixed a misspelled export in the core C library that prevented databases opened
    with UTF16Encoding from getting schema information and would likely cause an error
    if attempted.</li></ul>
    <p><b>1.0.26.1 - February 14, 2006</b></p>
    <ul>
    <li>Fixed even more minor schema bugs having to do with indexes.</li><li>Added two missing pieces in the SQLite designer which were preventing it from
    being used from within VS Express editions.&nbsp;</li><li>Several bugfixes to the design-time installer program, including supporting
    64-bit environments.</li></ul>
    <p><b>1.0.26.0 - February 11, 2006</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.4</li><li>Fixed an encryption bug when changing the password of databases over 1gb in
      size.&nbsp;</li><li>Fixed various designer issues related to construction of named parameters.&nbsp;</li><li>Retooled the GetSchema() method of SQLiteDataReader to use the new 3.3.4 API functions,
        and made several enhancements and fixes to schemas.&nbsp;</li>
      <li>Implemented the SourceColumnNullMapping property of SQLiteParameter to fix
    a DbCommandBuilder code generation bug.&nbsp;</li>
      <li>Removed the runtime dependency on MSVCR80.DLL.&nbsp; File size is somewhat
    larger for the varying desktop versions, but the Compact Framework version remains
    the same.</li><li>Created an install program to manage installation and uninstallation of the
    SQLite design-time support.</li>
      <li>Designer support now works for all Visual Studio editions, including all Express
        Editions.</li>
      <li>Design-time installer will now remove (if present) the machine.config SQLite entries
        in favor of installing the xml code into the devenv.exe.config file (or any of the
        variations for express editions).&nbsp; The officially-accepted behavior of using
        DbProviderFactories is to add the code to your app.config file, and the machine.config
        file should not be touched.</li>
    </ul>
    <p><b>1.0.25.0 - January 31, 2006</b></p>
    <ul>
    <li>Code merge with SQLite 3.3.3</li><li>Added automatic distributed transaction enlistment and implemented the DbConnection.EnlistTransaction
    method for manual enlistment.</li>
      <li>Nested transactions are now supported.</li>
      <li>Rearranged the timing of SetPassword(), which now must be called before the database
        is opened instead of afterwards.&nbsp; Optionally, the password can be supplied
        in the ConnectionString.</li>
      <li>Fixed a bug in SQLiteFunction that caused a failure when an empty resultset was
        returned and a custom user aggregate function was used in the query.</li>
      <li>The designer has had another round of cleanup applied, in preparation for moving
        to a VS package.</li>
      <li>Added SQLiteMetaDataCollectionNames class.</li>
    </ul>
    <p><b>1.0.24.6 beta - January 23, 2006</b></p>
    <ul>
    <li>This beta is built from sqlite.org's 3.3.2 beta.</li><li>Eliminated the static linking of mscoree from all binaries.&nbsp; Native projects
      can now use the library without any dependencies on the .NET framework, while managed
      projects continue to be able to use the library normally.</li></ul>
    <p><b>1.0.24.5 beta - January 20, 2006</b></p>
    <ul>
    <li>This beta is built from sqlite.org's 3.3.1 alpha and contains development-in-progress code.&nbsp; Therefore no guarantees
      can be made regarding its suitability for production use.</li>
    <li><strong>You no longer need to distribute 2 files on the CompactFramework.&nbsp;
      You can delete SQLite.Interop.DLL entirely.&nbsp; </strong>I wrote a custom tool
      called "mergebin" (available in the source zip file) which combines the two libraries
      and gets around a glaring defect in the VS2005 linker for ARM processors which doesn't
      allow you to link netmodules.</li>
      <li><strong>x64 and ia64 builds now use the same strong name as the x86 build.</strong>&nbsp;
        This means breaking backward compatibility, but it was necessary in order to allow
        you to drop any of those 3 builds onto a PC and have your .NET program run properly.&nbsp;
        Prior to this, you'd get an error if you built your program using the x86 build,
        and then installed the x64 version on a target machine and tried to run your program
        against it.</li>
      <li>The entire source project has been gone over top to bottom.&nbsp; A debug build
        no longer combines the binaries into a single module, which was preventing proper
        debugging.</li></ul>
    <p><b>1.0.24.4 beta - January 16, 2006</b></p>
    <ul>
    <li>This beta is built from sqlite.org's 3.3.1 alpha and contains development-in-progress code.&nbsp; Therefore no guarantees
      can be made regarding its suitability for production use.</li>
    <li>Fixed a bug in the UTF-16 handling code for preparing statements due to a behavioral
      change in SQLite 3.3.0.</li>
      <li>Added pager.c code necessary to cleanup after an encrypted file is closed.</li>
      <li>Fixed an encryption bug that caused a fault when an encrypted file was rolled
        back.</li>
      <li>Modified the testcase code to take advantage of optimizations regarding the use
        of a DbCommandBuilder.&nbsp; DataAdapter insert speed increased dramatically as
        a result.</li>
    </ul>
    <p><b>1.0.24.3 beta - January 10, 2006</b></p>
    <ul>
    <li>This beta is built from sqlite.org's CVS HEAD (as it appeared at of the date of
      this beta) and contains development-in-progress code.&nbsp; Therefore no guarantees
      can be made regarding its suitability for production use.</li><li>Added support for database encryption at the pager level.&nbsp; Databases
    are encrypted using a 128-bit RC4 stream algorithm.&nbsp; To open an existing encrypted
    database, you may now specify a "Password={password}" text in the ConnectionString,
    or you may call the SQLiteConnection.SetPassword() function to set the password
    on an open connection. &nbsp;To encrypt existing non-encrypted databases or to change
    the password on an encrypted database, you must use the SQLiteConnection.ChangePassword()
    function.&nbsp; If you use SetPassword() instead of specifying a password in the
    connection string, or call ChangePassword() you may use a binary byte array or a
    text string as the password.</li>
      <li>Rewrote the locking implementation for the Compact Framework.&nbsp; It is now
        more robust and incorporates into the SQLite codebase more efficiently than the
        previous CE adaptation.</li>
      <li>Moved some of the embedded schema XML data into a resource file to ease code readability.</li>
      <li>Automated the fixup of the original sqlite codebase's source prior to compiling,
        to ease merging with sqlite.org's source.&nbsp;</li>
    </ul>
    <p><b>1.0.24.2 - December 30, 2005</b></p>
    <ul>
    <li>Fixed the SQLiteDataReader.HasRows property to return the proper value.</li>
      <li>Implemented the inadvertently neglected RecordsAffected property on SQLiteDataReader.
      </li>
      <li>SQLiteFunction static constructor was changed to pre-filter classes with only the
        SQLiteFunctionAttribute.&nbsp; The code was throwing an exception when certain
        assemblies were referenced in a project. </li>
      <li>Fixed the SQLiteDataAdapter OnRowUpdated event, which was using the wrong variable
        to find the attached event handler and subsequently not raising the event.</li>
      <li>Small optimizations and fixes to SQLiteDataReader.NextResult().&nbsp;</li>
    </ul>
    <p><b>1.0.24.1 - December 19, 2005</b></p>
    <ul>
    <li>Update core SQLite engine to 3.2.8&nbsp;</li></ul>
    <p><b>1.0.24 - December 9, 2005</b></p>
    <ul>
    <li>Fixed the<em> Catalogs</em> schema bug that caused attached databases not to be re-attached to a cloned connection
    </li>
      <li>Enhanced transactions to allow for a deferred or immediate writelock. &nbsp;SQLiteConnection.BeginTransaction()
        now has an additional overload to support it </li>
      <li>Commands are now prepared as they are executed instead of beforehand.&nbsp; This
      fixes a bug whereby a multi-statement command that alters the database and subsequently
      references the altered data would fail during Prepare().</li><li>Tightened up the SQLiteDataReader to prevent reading columns before calling
    the first Read() and to prevent reading columns after the last Read().</li>
      <li>A more descriptive error is thrown if there aren't enough parameters in the command
        to satisfy the parameters required by the statement(s).&nbsp;</li>
    </ul>
    <p><b>1.0.23 - November 21, 2005</b></p>
    <ul>
    <li>Named parameters may now begin with <strong>@</strong> to ease portability of
      the provider. SQLite's named parameters are ordinarily prefixed with a <strong>: </strong>
      or<strong> $</strong>.&nbsp; The designer will still use the <strong>$</strong>
      prefix however, since its more compatible with the default SQLite engine.</li><li>Added several alternate ISO8601 date/time formats to SQLiteConvert.cs to increase
    compatibility.</li>
      <li>Relaxed coersion restrictions to work better with SQLite's inherent typelessenss.&nbsp;</li>
    </ul>
    <p><b>1.0.22 - November 11, 2005</b></p>
    <UL>
    <li>Fixed some globalization issues which resulted in incorrect case-insensitive comparisons</li>
      <li>Fixed a bug in the routine that finds all user-defined functions in a loaded assembly.&nbsp;
        It would throw an exception if any of the types in the assembly could not be loaded.&nbsp;
        The exception is now caught and handled appropriately.</li>
    </UL>
    <p><b>1.0.21 - November 4, 2005</b></p>
    <UL>
      <li>Fixed a designer bug when creating typed datasets with parameterized queries.
      </li><li>The above fix then exposed another bug in the datareader's ability to query
    schema information on parameterized commands, which was also fixed. </li>
      <li>Compiled against the RTM version of VS2005. </li>
      <li>Rewrote the design-time install script to use the XML DOM objects when writing
        to the machine.config and to automatically register the DLL in the GAC.</li>
      <LI>Made changes to the app.config descriptions and help file to improve version-independent
        factory support.&nbsp; </li>
    </UL>
      <P><STRONG>1.0.20 - October 19, 2005</STRONG></P>
      <UL>
        <LI>
        Fixed a shortcut in SQLiteBase.GetValue which was insufficient for international environments.  The shortcut was removed and the "proper" procedure put in.
        </UL>
      <P><STRONG>1.0.19 - October 5, 2005</STRONG></P>
      <UL>
        <LI>
        Code merge with SQLite 3.2.7
        <LI>
        Fixed bugs in the CE port code (os_wince.c)&nbsp;which were brought to
        light&nbsp;by&nbsp;recent changes in the SQLite engine.
        <LI>
          Recompiled and modified to be compatible with the September VS2005 Release
          Candidate.<BR>
          Beta 2 users should continue to use 1.0.18.1</LI></UL>
      <P><STRONG>1.0.18.1 - September 19, 2005</STRONG></P>
      <UL>
        <LI>
          Code merge with SQLite 3.2.6</LI></UL>
      <P><STRONG>1.0.18 - September 1, 2005</STRONG></P>
      <UL>
        <li>
          Added type-specific method calls when using the various SQLite classes that
          would've normally returned a a generic Db base class, which aligns the code
          better with the Microsoft-supplied data providers.</li></UL>
      <p><b>1.0.17 - August 26, 2005</b></p>
      <ul>
        <li>
        Code merge with SQLite 3.2.5
        <li>
        Added Itanium and x64 build settings to the project (needs testing)
        <li>
        Bugfixes and enhancements to several schema types
        <li>
        Additional design-time support to include index and foreign key
        enumerations.&nbsp; Requires re-registering the designer using
        INSTALL.CMD.&nbsp; The new designer code now allows the VS query designer and
        typed datasets to automatically link up foreign keys, use indexes, and
        automatically generate relationships from the schema.<li>
          Additional static methods on SQLiteConnection to create a database file,
          encrypt a file using the Encrypted File System (EFS) on NTFS (requires NT 2K or
          above) and NTFS file compression</li>
      </ul>
      <p><b>1.0.16 - August 24, 2005</b></p>
      <ul>
        <li>
        Code merge with SQLite 3.2.4 with the large delete bugfix in CVS (which will
        become 3.2.5 soon)
        <li>
          Added new GetSchema() types: IndexColumns, ViewColumns, ForeignKeys</li>
      </ul>
      <p><b>1.0.15 - August 22, 2005</b><br>
      </p>
      <ul>
        <li>
        Code merge with SQLite 3.2.3
        <LI>
          Minor updates for better design-time experience. More design-time code to
          follow in subsequent releases.</LI>
      </ul>
      <p><b>1.0.14 - August 16, 2005</b><br>
      </p>
      <ul>
        <li>
        Fixed a bug in the SQLiteDataAdapter due to insufficient implementation of the
        class.&nbsp; The RowUpdating and RowUpdated events are now properly
        implemented, but unfortunately inserting and updating data in a DataTable or
        DataSet is now much slower.&nbsp; This is the proper design however, so the
        changes are here to stay.
        <LI>
        Lots of schema changes to support Visual Studio's Data Designer architecture.<li>Added
          Designer support for the provider.&nbsp; It's not 100%, but you can design
          queries, add typed datasets and perform quite a number of tasks all within
          Visual Studio now.</li></ul>
      <P><B>1.0.13 - August 8, 2005</B><BR>
      </P>
      <DIV>
        <UL>
          <LI>
          Fixed a named parameter bug in the base SQLite_UTF16 class, which of course
          only showed up when a database connection was opened using the
          UseUTF16Encoding=True parameter.
          <LI>
            Fixed a performance issue in SQLite_UTF16 involving string marshaling.</LI></UL>
      </DIV>
      <P><B>1.0.12 - August 5, 2005</B><BR>
      </P>
      <DIV>
        <UL>
          <LI>
            Full support for the Compact Framework.&nbsp; Each build (Debug/Release) now
            has a&nbsp;platform, either Win32 or Compact Framework.&nbsp; The correct
            projects are built accordingly.&nbsp; See the&nbsp;<A href="#redist">Distributing
              SQLite</A>
          section for information on what files need to be distributed for each
          platform.&nbsp;
          <LI>
          Modified SQLite3.Reset() and Step() functions to transparently handle timeouts
          while waiting on the database to become available (typically when a writer is
          waiting on a reader to finish, or a reader is waiting on a writer to finish).
          <LI>
          Lots of code cleanup&nbsp;as suggested&nbsp;by the Code Analyzer (FxCop).
          <LI>
          Lots of updates to the helpfile (as you can see).
          <LI>
            Statements&nbsp;were already prepared lazily&nbsp;in a SQLiteCommand, but now
            its even more lazy.&nbsp; Statements are now only prepared if the statements
            haven't been previously prepared and a Prepare() function is called (and the
            command is associated with a connection) or just prior to the command being
            executed.&nbsp;</LI></UL>
      </DIV>
      <P><B>1.0.11 - August 1, 2005</B><BR>
      </P>
      <UL>
        <LI>
          <STRONG>For everything except the Compact Framework, System.Data.SQLite.DLL is
            now the <EM>only</EM> DLL required to use this provider!</STRONG>&nbsp; The
        assembly is now a multi-module assembly, containing both the native SQLite3
        codebase and the C# classes built on top of it.&nbsp; The Compact Framework
        version (when completed) will not be able to support this feature, so backwards
        compatibility with the Compact Framework has been preserved for the future.
        <LI>
          Fixed a bug in SQLiteCommand.ExecuteScalar() that caused it to stop executing
          commands once it obtained the first column of the first row-returning
          resultset.&nbsp; Any remaining statements after the row-returning statement was
          ignored.
        </LI>
      </UL>
      <P><B>1.0.10 - June 10, 2005</B><BR>
      </P>
      <UL>
        <LI>
        Fixed a bug in the SQLite3.cs Prepare() function that created a statement even
        when the SQLite engine returned a NULL pointer. Typically this occurs when
        multiple statements are processed and there are trailing comments at the end of
        the statement.
        <LI>
          Fixed a bug in SQLiteStatement.cs that retrieved parameter names for a
          parameterized query.&nbsp; SQLite's parameters are 1-based, and the function
          was starting at 0.&nbsp; This was fine when all parameters were unnamed, but
          for named parameters it caused the parameters to be out of whack.
        </LI>
      </UL>
      <P><B>1.0.09a - May 25, 2005</B><BR>
      </P>
      <UL>
        <LI>
        Fixed a broken helpfile and corrected some obsolete help remarks in
        SQLiteFunction.cs
        <LI>
          Added a version resource to the SQLite.Interop.DLL.&nbsp;</LI></UL>
      <P><B>1.0.09 - May 24, 2005</B><BR>
      </P>
      <UL>
        <LI>
        Code merge with the latest 3.21 version of SQLite.
        <LI>
          Removed obsolete methods and properties for Whidbey Beta 2</LI></UL>
      <P><B>1.0.08 Refresh - Mar 24, 2005<BR>
        </B>
      </P>
      <UL>
        <LI>
        Code merge with the latest 3.20 version of SQLite.
        <LI>
          Recompiled the help file to fix a build error in it.
        </LI>
      </UL>
      <P><B>1.0.08 - Mar 11, 2005<BR>
        </B>
      </P>
      <UL>
        <LI>
        Added additional #if statements to support the old beta 1 edition of VS2005.
        <LI>
          Code merged the SQLite 3.14 source.
        </LI>
      </UL>
      <P><B>1.0.07 - Mar 5, 2005</B><BR>
      </P>
      <UL>
        <LI>
        Made more optimizations to frequently-called functions, resulting in
        significant performance gains in all tests.
        <LI>
          Recompiled the binaries using the latest VS2005 February CTP, resulting in yet
          more significant speed gains.&nbsp; The 100k insert test used to take 3.5
          seconds and the insertwithidentity took almost 8 seconds.&nbsp; With the above
          two changes, those tests are now executing in 1.9 and 4.9 seconds respectively.</LI></UL>
      <P><B>1.0.06 - Mar 1, 2005<BR>
        </B>
      </P>
      <UL>
        <LI>
        Speed-ups to SQLiteDataReader.&nbsp; It was interop'ing unnecessarily every
        time it tried to fetch a field due to a logic error.
        <LI>
        Changed/Added some code to SQLiteConvert's internal DbType, Type and
        TypeAffinity functions.
        <LI>
        Fixed the SQLiteDataReader to obey the flags set in the optional
        CommandBehavior flag from SQLiteCommand.ExecuteReader().
        <LI>
        Changed the default page size to 1024 to reflect the defaults of SQLite.&nbsp;
        Ignores the "Page Size" connection string option for memory databases, as tests
        revealed that changing it resulted in memory corruption errors.
        <LI>
          Performance enhancements to the SQLiteCommand and SQLiteStatement classes which
          reduced the 100,000 row insert execution time as well as the various Function
          execution times significantly.
        </LI>
      </UL>
      <P><B>1.0.05 - Feb 25, 2005</B>
      </P>
      <UL>
        <LI>
        Fixed the SQLite3 C# class step/reset functions to accomodate schema changes
        that invalidate a prepared statement.&nbsp; Statements are recompiled
        transparently.
        <LI>
        Moved all native DLL declarations to an UnsafeNativeMethods class.
        <LI>
        Split several classes into their own modules for readability.
        <LI>
        Renamed many internal variables, reviewed access to variables marked as
        internal and altered their protection levels accordingly.
        <LI>
        Due to the presence of the altered sqlite3 codebase and so many added interop
        functions, I decided to rename the sqlite3 C project and the DLL to
        SQLite.Interop.DLL.&nbsp; This is the same core sqlite3 codebase but designed
        specifically for this ADO.NET provider.&nbsp; This eliminates any possibility
        of someone dropping another build of sqlite3.dll into the system and rendering
        the provider inoperable.&nbsp; In the future if the folks at sqlite.org finally
        introduce a method of retrieving column usage for an arbitrary prepared
        statement, I'll retool this library to be a lightweight function call wrapper
        around the core binary distribution.
        <LI>
        Added [SuppressUnmanagedCodeSecurity] attribute to the UnsafeNativeMethods
        class which brings VS2005 November CTP execution speeds inline with the
        December CTP.
        <LI>
          Added a <B>bin</B>
        directory to the project root where pre-compiled binaries can be found.
        <LI>
          Added a <B>doc</B>
        directory where preliminary documentation on the class library can be found.
        <LI>
          Documented a lot more of the classes internally.
        </LI>
      </UL>
      <P><B>1.0.04 - Feb 24, 2005</B>
      </P>
      <UL>
        <LI>
        Removed the SQLiteContext class and revamped the way UserFunctions work to
        simplify the imlementation.
        <LI>
        Fixed a counting bug in the TestCases class, specifically in the function tests
        where I wasn't resetting the counter and it was consequently reporting
        intrinsic and raw select calls as being much much faster than they actually
        were.&nbsp; The numbers are now much closer to what I expected for performance,
        with .NET user-functions still being the slowest, but only by a small margin.
        <LI>
        Small performance tweaks to SQLiteDataReader.
        <LI>
        Added PageSize to the SQLiteConnectionStringBuilder and subsequently to the
        SQLiteConnection
        <LI>
          Added a PRAGMA encoding=XXX execution statement to the SQLiteConnection after
          opening a connection.
        </LI>
      </UL>
      <P><B>1.0.03 - Feb 23, 2005</B>
      </P>
      <UL>
        <LI>
        Fixed up SQLiteCommandBuilder to correct implementation errors, which resulted
        in an enormous performance boost in the InsertMany test.&nbsp;&nbsp; 10,000 row
        insert that executed in 1500ms now executes in 500ms.
        <LI>
        Fixed several errors in the SQLite3_UTF16 class.&nbsp; ToString() was working
        incorrectly and the Open() method failed to register user defined functions and
        collations.
        <LI>
        Fixed a bug in SQLiteCommand.ClearCommands() whereby only the first statement
        was being properly cleaned up.
        <LI>
        Fixed a bug in SQLiteDataReader whereby calling NextResult() would not properly
        reset the previously-executed command in the sequence.
        <LI>
          Added an InsertManyWithIdentityFetch test, which appends a select clause to
          populate the ID of the last inserted row into the InsertCommand, demonstrating
          ADO.NET's ability to auto-fetch identity columns on insert.
        </LI>
      </UL>
      <P><B>1.0.02 - Feb 21, 2005</B></P>
      <UL>
        <LI>
        Tweaks to the xxx_interop functions that return char *'s, so they also return
        the length.&nbsp; Saves an interop call to get the UTF-8 string length during
        conversion to a .NET string.
        <LI>
        Reworked the whole interop.c thing into interop.h and reduced the code required
        to merge the main sqlite3 codebase.
        <LI>
          Added support for user-defined collations.
        </LI>
      </UL>
      <hr />
      <div id="footer">
        <p>
          <a href="mailto:sqlite-users@sqlite.org?subject=SQLite.NET%20Class%20Library%20Documentation%20Feedback:%20Version%20History">
            Send comments on this topic.</a>
        </p>
        <p>
        </p>
      </div>
    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Doc/Extra/welcome.html.
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
<html dir="LTR" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:ndoc="urn:ndoc-preprocess">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <title>Introduction</title>
    <link rel="stylesheet" type="text/css" href="ndoc.css" />
  </head>
  <body>
    <div id="header">
      <table width="100%" id="topTable">
        <tr id="headerTableRow1">
          <td align="left">
            <span id="runningHeaderText">SQLite ADO.NET Provider</span>
          </td>
        </tr>
        <tr id="headerTableRow2">
          <td align="left">
            <span id="nsrTitle">SQLite.NET Class Library Documentation</span>
          </td>
        </tr>
        <tr id="headerTableRow3" style="display:none">
          <td>
            <a id="seeAlsoSectionLink" href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">See Also</a>
            <a id="exampleSectionLink" href="#codeExampleToggle" onclick="OpenSection(codeExampleToggle)">Example</a>
          </td>
        </tr>
     </table>
      <table width="100%" id="bottomTable" cellspacing="0" cellpadding="0" style="display:none">
        <tr>
          <td>
            <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage)" tabindex="0">
              <img ID="toggleAllImage" class="toggleAll" src="collall.gif" />
              <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
							Collapse All
						</label>
              <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
							Expand All
						</label>
            </span>
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
      <h1 class="heading">About SQLite.NET</h1>
      <p>This class library is an ADO.NET wrapper around the popular (and free!) 
        SQLite database engine. For information on SQL syntax, features of SQLite and a 
        good understanding of how it works and what it does, I highly recommend heading 
        over to <a target="_blank" href="http://www.sqlite.org">sqlite.org</a> and 
        reading the documentation there.</p>
      <P>The C# provider, the very minor C code modifications to SQLite, documentation and 
        etc&nbsp;were written by <A href="mailto:robert@blackcastlesoft.com">Robert 
          Simpson</A>, and the SourceForge project page can be found <A target="_blank" href="http://sourceforge.net/projects/sqlite-dotnet2">
          here</A>.</P>
      <DIV>
        <br>
      </DIV>
      <h1 class="heading">What's New?</h1>
      <p><a href="version.html">Click here to see the version history of this SQLite.NET 
          provider</a></p>
      <DIV>
        <br>
      </DIV>
      <h1 class="heading">Using this library</h1>
      <p>The following are links to information on various aspects of the library and 
        how to use it in your application(s)
      </p>
      <p><a href="designer.html">How to install&nbsp;Visual Studio Design-Time Support</a></p>
      <P><A href="dbfactorysupport.html">How to configure and enumerate SQLite.NET 
          through the DbProviderFactories object</A></P>
      <p><a href="optimizing.html">Getting the best performance out of SQLite</a></p>
      <p><a href="limitations.html">Limitations of the SQLite.NET provider and the SQLite 
          engine (compared to other providers and engines)</a></p>
      <br>
      <h1 class="heading">SQLite.NET Provider Features</h1>
      <p>This SQLite provider implements every feature of the underlying SQLite 
        database engine without omission. Here's a brief summary:</p>
      <UL>
        <LI>
        Written from scratch on VS2005/2008 specifically for ADO.NET, implenting all the
        base classes and features recently introduced in the framework, including automatic
        transaction enlistment.<li>Supports the Full and Compact .NET Framework, as well as
          native C/C++ development.&nbsp; 100% binary compatible with the original sqlite3.dll.</li>
        <li>Full support for Mono via a &quot;managed only&quot; provider that runs against the 
          official SQLite 3.6.1 or higher library.</li>
        <li>Full Entity Framework support (ADO.NET 3.5 SP1)</li>
        <li>
        On the Compact Framework, it is faster than Sql Server Mobile.
          SQLite's installed size is a fraction of Sql Mobile's. It uses less memory at runtime,
          runs queries faster, and has a smaller database file size as well. </li>
        <li>Encrypted database support.&nbsp; Encrypted databases are fully encrypted and
          support both binary and cleartext password types. </li>
        <li>Visual Studio 2005/2008 Design-Time Support.&nbsp; You can add a SQLite 
        database to the Servers list, design queries with the Query Designer, 
        drag-and-drop tables onto a Typed DataSet, etc.</li>
            <li>Full SQLite schema editing inside Visual Studio.&nbsp; You can create/edit 
              tables, views, triggers, indexes, check constraints and foreign keys. </li>
        <li>
        Single file redistributable (except Compact Framework).&nbsp; The core sqlite3 codebase and the ADO.NET wrapper 
        are combined into one multi-module assembly. </li>
        <li>Binaries included for Itanium, x64, x86 and ARM processors. </li>
        <li>
        DbProviderFactory support. </li>
        <li>
          Full support for ATTACH'ed databases.&nbsp; Exposed as <i>Catalogs</i>
        in the schema.&nbsp; When cloning a connection, all attached databases are 
        automatically re-attached to the new connection. </li>
        <li>
          DbConnection.GetSchema(...) support includes the <i>MetaDataCollections</i>, <i>
          DataSourceInformation</i>, <i>Columns</i>, <i>Tables</i>, <i>Views, ViewColumns, </i>
          <i>Catalogs, </i><i>Indexes, 
            IndexColumns, ForeignKeys </i>and <em>Triggers</em>.
        </li>
        <li>
        Enhanced DbDataReader.GetSchemaTable() functionality returns catalog, namespace 
        and detailed schema information even for complex queries. </li>
        <li>
        Named and unnamed parameters. </li>
        <li>
        Full UTF-8 and UTF-16 support, each with optimized pipelines into the native 
        database core. </li>
        <li>
        Multiple simultaneous DataReaders (one DataReader per Command however). </li>
        <li>
        Full support for user-defined scalar and aggregate functions, encapsulated into 
        an easy-to-use base class in which only a couple of overrides are necessary to 
        implement new SQL functions. </li>
        <li>
        Full support for user-defined collating sequences, every bit as simple to 
        implement as user-defined functions and uses the same base class. </li>
        <li>
          Full source for the entire engine and wrapper.&nbsp; No copyrights.&nbsp; 
          Public Domain.&nbsp; 100% free for commercial and non-commercial use.&nbsp;</li>
      </UL>
      <br>
      <h1 class="heading">Distributing the Binaries (Desktop)</h1>
      <p><b>System.Data.SQLite.DLL</b> is a mixed assembly signed with a strong name 
        in case you want to add it to the Global Assembly Cache (GAC). This is the only DLL required to be redistributed with 
        your SQLite.NET application(s).&nbsp; It 
        comes in&nbsp;3
        flavors: Win32, Itanium and x64 (AMD64).</p>
      <h1 class="heading">Distributing the Binaries (Compact Framework)</h1>
      <p><b>System.Data.SQLite.DLL </b>and <b>SQLite.Interop.XXX.DLL</b> must be 
        deployed on the Compact Framework.&nbsp; The XXX is the build number of the 
        System.Data.SQLite library (e.g. &quot;077&quot;).&nbsp; SQLite.Interop.XXX 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">
          Send comments on this topic.<!--[if gte IE 5]><tool:tip element="seeAlsoToolTip" avoidmouse="false" /><tool:tip element="languageFilterToolTip" avoidmouse="false" /><![endif]-->    </div>
    </div>
  </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































Changes to Doc/SQLite.NET.chm.

cannot compute difference between binary files

Deleted Doc/SQLite.NET.hhc.
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
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
<!-- Sitemap 1.0 -->
</HEAD><BODY>
<UL>
	<LI> <OBJECT type="text/sitemap">
		<param name="Name" value="Introduction">
		<param name="Local" value="welcome.html">
		</OBJECT>
	<UL>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="Installing Design-Time Support">
			<param name="Local" value="designer.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="Using DbProviderFactories">
			<param name="Local" value="dbfactorysupport.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="Optimizing SQL Queries">
			<param name="Local" value="optimizing.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="Provider Limitations">
			<param name="Local" value="LImitations.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="Version History">
			<param name="Local" value="version.html">
			</OBJECT>
	</UL>
	<LI> <OBJECT type="text/sitemap">
		<param name="Name" value="SQLite Language Reference">
		<param name="Local" value="syntax.html">
		</OBJECT>
	<UL>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="ALTER TABLE">
			<param name="Local" value="lang_altertable.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="ANALYZE">
			<param name="Local" value="lang_analyze.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="ATTACH DATABASE">
			<param name="Local" value="lang_attach.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="BEGIN TRANSACTION">
			<param name="Local" value="lang_transaction.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="comment">
			<param name="Local" value="lang_comment.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="COMMIT TRANSACTION">
			<param name="Local" value="lang_transaction.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="CREATE INDEX">
			<param name="Local" value="lang_createindex.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="CREATE TABLE">
			<param name="Local" value="lang_createtable.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="CREATE TRIGGER">
			<param name="Local" value="lang_createtrigger.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="CREATE VIEW">
			<param name="Local" value="lang_createview.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="CREATE VIRTUAL TABLE">
			<param name="Local" value="lang_createvtab.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="DELETE">
			<param name="Local" value="lang_delete.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="DETACH DATABASE">
			<param name="Local" value="lang_detach.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="DROP INDEX">
			<param name="Local" value="lang_dropindex.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="DROP TABLE">
			<param name="Local" value="lang_droptable.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="DROP TRIGGER">
			<param name="Local" value="lang_droptrigger.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="DROP VIEW">
			<param name="Local" value="lang_dropview.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="END TRANSACTION">
			<param name="Local" value="lang_transaction.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="EXPLAIN">
			<param name="Local" value="lang_explain.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="expression">
			<param name="Local" value="lang_expr.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="INSERT">
			<param name="Local" value="lang_insert.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="ON CONFLICT">
			<param name="Local" value="lang_conflict.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="PRAGMA">
			<param name="Local" value="pragma.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="REINDEX">
			<param name="Local" value="lang_reindex.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="REPLACE">
			<param name="Local" value="lang_replace.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="ROLLBACK TRANSACTION">
			<param name="Local" value="lang_transaction.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="SELECT">
			<param name="Local" value="lang_select.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="UPDATE">
			<param name="Local" value="lang_update.html">
			</OBJECT>
		<LI> <OBJECT type="text/sitemap">
			<param name="Name" value="VACUUM">
			<param name="Local" value="lang_vacuum.html">
			</OBJECT>
	</UL>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































Deleted Doc/SQLite.NET.hhp.
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
[OPTIONS]
Compatibility=1.1 or later
Compiled file=SQLite.NET.extra.chm
Contents file=SQLite.NET.hhc
Default topic=Extra\welcome.html
Display compile progress=Yes
Error log file=SQLite.NET.log
Full-text search=Yes
Language=0x409 English (United States)
Title=SQLite.NET Help

[FILES]
Extra\ndoc.css
Extra\dbfactorysupport.html
Extra\designer.html
Extra\lang_altertable.html
Extra\lang_analyze.html
Extra\lang_attach.html
Extra\lang_comment.html
Extra\lang_conflict.html
Extra\lang_createindex.html
Extra\lang_createtable.html
Extra\lang_createtrigger.html
Extra\lang_createview.html
Extra\lang_createvtab.html
Extra\lang_datetime.html
Extra\lang_delete.html
Extra\lang_detach.html
Extra\lang_dropindex.html
Extra\lang_droptable.html
Extra\lang_droptrigger.html
Extra\lang_dropview.html
Extra\lang_explain.html
Extra\lang_expr.html
Extra\lang_insert.html
Extra\lang_reindex.html
Extra\lang_replace.html
Extra\lang_select.html
Extra\lang_transaction.html
Extra\lang_types.html
Extra\lang_update.html
Extra\lang_vacuum.html
Extra\limitations.html
Extra\optimizing.html
Extra\pragma.html
Extra\syntax.html
Extra\version.html
Extra\welcome.html
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































Changes to Doc/SQLite.NET.ndoc.
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
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<project SchemaVersion="2.0">
    <assemblies>
        <assembly location="..\bin\2008\Release\bin\System.Data.SQLite.dll" documentation="..\bin\2008\Release\bin\System.Data.SQLite.xml" />
    </assemblies>
    <documenters>
        <documenter name="MSDN">
            <property name="IncludeFavorites" value="True" />





            <property name="SdkLinksOnWeb" value="True" />



            <property name="OutputDirectory" value=".\Output\" />




            <property name="HtmlHelpName" value="SQLite.NET" />
            <property name="Title" value="SQLite ADO.NET Provider" />
            <property name="Version" value="" />
            <property name="OutputTarget" value="HtmlHelp" />
            <property name="BinaryTOC" value="False" />
            <property name="AdditionalContentResourceDirectory" value=".\Extra\" />
            <property name="AssemblyVersionInfo" value="AssemblyVersion" />
            <property name="FeedbackEmailAddress" value="sqlite-users@sqlite.org" />
            <property name="SdkDocVersion" value="SDK_v3_5" />
            <property name="SdkDocVersionString" value="VS.90" />
            <property name="DocumentAttributes" value="False" />
            <property name="IncludeDefaultThreadSafety" value="False" />













        </documenter>
    </documenters>
</project>
<
|

|


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

|
<

|
<

|
|
<
<

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




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

<project SchemaVersion="1.3">
    <assemblies>
        <assembly location="..\System.Data.SQLite\bin\Release\System.Data.SQLite.dll" documentation="..\System.Data.SQLite\bin\Release\System.Data.SQLite.xml" />
    </assemblies>
    <documenters>
        <documenter name="JavaDoc">
            <property name="OutputDirectory" value=".\doc\" />
        </documenter>
        <documenter name="LaTeX">
            <property name="OutputDirectory" value=".\doc\" />
            <property name="TextFileFullName" value="Documentation.tex" />
            <property name="TexFileBaseName" value="Documentation" />
            <property name="LatexCompiler" value="latex" />
            <property name="TexFileFullPath" value=".\doc\Documentation.tex" />
        </documenter>
        <documenter name="LinearHtml">
            <property name="OutputDirectory" value=".\doc\" />
            <property name="Title" value="An NDoc Documented Class Library" />
        </documenter>
        <documenter name="MSDN">
            <property name="OutputDirectory" value="c:\src\SQLite.NET\Doc\" />
            <property name="HtmlHelpName" value="SQLite.NET" />
            <property name="Title" value="SQLite.NET Class Library" />

            <property name="OutputTarget" value="HtmlHelp" />
            <property name="IncludeFavorites" value="True" />

            <property name="AssemblyVersionInfo" value="AssemblyVersion" />
            <property name="FeedbackEmailAddress" value="robert@blackcastlesoft.com" />
            <property name="Preliminary" value="True" />


            <property name="IncludeDefaultThreadSafety" value="False" />
            <property name="CleanIntermediates" value="True" />
        </documenter>
        <documenter name="MSDN 2003">
            <property name="OutputDirectory" value=".\doc\" />
            <property name="Title" value="An NDoc Documented Class Library" />
        </documenter>
        <documenter name="VS.NET 2003">
            <property name="OutputDirectory" value=".\doc\" />
            <property name="HtmlHelpName" value="Documentation" />
            <property name="Title" value="An NDoc documented library" />
        </documenter>
        <documenter name="XML">
            <property name="OutputFile" value=".\doc\doc.xml" />
        </documenter>
    </documenters>
</project>
Deleted Doc/buildChm.tcl.
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
###############################################################################
#
# buildChm.tcl -- CHM Build Wrapper & Post-Procssing Tool
#
# WARNING: This tool requires that the "HTML Help Workshop" and "NDoc3"
#          applications are installed to their default locations.
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

proc readFile { fileName } {
  set file_id [open $fileName RDONLY]
  fconfigure $file_id -encoding binary -translation binary
  set result [read $file_id]
  close $file_id
  return $result
}

proc writeFile { fileName data } {
  set file_id [open $fileName {WRONLY CREAT TRUNC}]
  fconfigure $file_id -encoding binary -translation binary
  puts -nonewline $file_id $data
  close $file_id
  return ""
}

proc readFileAsSubSpec { fileName } {
  set data [readFile $fileName]
  regsub -all -- {&} $data {\\\&} data
  regsub -all -- {\\(\d+)} $data {\\\\\1} data
  return $data
}

set path [file dirname [info script]]

set nDocPath [file join $env(ProgramFiles) NDoc3]

if {![file isdirectory $nDocPath]} then {
  puts stdout "NDoc3 must be installed to: $nDocPath"; 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"; exit 1
}

#
# 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 code [catch {exec [file join $nDocPath bin NDoc3Console.exe] \
    "-project=[file nativename [file join $path SQLite.NET.ndoc]]"} result]

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

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

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

set exps(.hhp,1) {Default topic=~System\.Data\.SQLite\.html}
set exps(.hhp,2) {"~System\.Data\.SQLite\.html","~System\.Data\.SQLite\.html",,,,,}

set subSpecs(.hhc,1) [readFileAsSubSpec [file join $path SQLite.NET.hhc]]
set subSpecs(.hhp,1) {Default topic=welcome.html}
set subSpecs(.hhp,2) {"welcome.html","welcome.html",,,,,}

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

  #
  # NOTE: Make sure the file we need actually exists.
  #
  if {![file isfile $fileName]} then {
    puts stdout "Cannot find file: $fileName"; exit 1
  }

  #
  # NOTE: Read the entire file into memory.
  #
  set data [readFile $fileName]

  #
  # NOTE: No replacements have been performed yet.
  #
  set count 0

  foreach name [lsort [array names exps [file extension $fileName],*]] {
    set exp $exps($name)
    set subSpec ""

    if {[info exists subSpecs($name)]} then {
      set subSpec $subSpecs($name)
    }

    set expCount [regsub -- $exp $data $subSpec data]

    if {$expCount > 0} then {
      incr count $expCount
    } else {
      puts stdout "*WARNING* File \"$fileName\" does not match: $exp"
    }
  }

  #
  # NOTE: If we actually performed some replacements, rewrite the file.
  #
  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]

#
# 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 join $path SQLite.NET.chm]

puts stdout SUCCESS; exit 0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































Added Doc/ndoc.log.
























































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
Building documentation...
Initializing...
Merging XML documentation...
Building file mapping...
Loading XSLT files...
    namespace.xslt
    namespacehierarchy.xslt
    type.xslt
    typehierarchy.xslt
    allmembers.xslt
    individualmembers.xslt
    event.xslt
    member.xslt
    memberoverload.xslt
    property.xslt
    field.xslt
    htmlcontents.xslt
Generating HTML pages...
System.Data.SQLite.html
System.Data.SQLiteHierarchy.html
System.Data.SQLite.DateTimeFormat.html
System.Data.SQLite.FunctionType.html
System.Data.SQLite.SQLiteCommand.html
System.Data.SQLite.SQLiteCommandMembers.html
System.Data.SQLite.SQLiteCommandConstructor.html
System.Data.SQLite.SQLiteCommandConstructor1.html
System.Data.SQLite.SQLiteCommandConstructor2.html
System.Data.SQLite.SQLiteCommandConstructor3.html
System.Data.SQLite.SQLiteCommandConstructor4.html
System.Data.SQLite.SQLiteCommandProperties.html
System.Data.SQLite.SQLiteCommand.CommandText.html
System.Data.SQLite.SQLiteCommand.CommandTimeout.html
System.Data.SQLite.SQLiteCommand.CommandType.html
System.Data.SQLite.SQLiteCommand.DesignTimeVisible.html
System.Data.SQLite.SQLiteCommand.UpdatedRowSource.html
System.Data.SQLite.SQLiteCommandMethods.html
System.Data.SQLite.SQLiteCommand.Cancel.html
System.Data.SQLite.SQLiteCommand.ExecuteNonQuery.html
System.Data.SQLite.SQLiteCommand.ExecuteScalar.html
System.Data.SQLite.SQLiteCommand.Prepare.html
System.Data.SQLite.SQLiteCommandBuilder.html
System.Data.SQLite.SQLiteCommandBuilderMembers.html
System.Data.SQLite.SQLiteCommandBuilderConstructor.html
System.Data.SQLite.SQLiteCommandBuilderConstructor1.html
System.Data.SQLite.SQLiteCommandBuilderConstructor2.html
System.Data.SQLite.SQLiteConnection.html
System.Data.SQLite.SQLiteConnectionMembers.html
System.Data.SQLite.SQLiteConnectionConstructor.html
System.Data.SQLite.SQLiteConnectionConstructor1.html
System.Data.SQLite.SQLiteConnectionConstructor2.html
System.Data.SQLite.SQLiteConnectionConstructor3.html
System.Data.SQLite.SQLiteConnectionProperties.html
System.Data.SQLite.SQLiteConnection.ConnectionString.html
System.Data.SQLite.SQLiteConnection.Database.html
System.Data.SQLite.SQLiteConnection.DataSource.html
System.Data.SQLite.SQLiteConnection.ServerVersion.html
System.Data.SQLite.SQLiteConnection.State.html
System.Data.SQLite.SQLiteConnectionMethods.html
System.Data.SQLite.SQLiteConnection.ChangeDatabase.html
System.Data.SQLite.SQLiteConnection.Clone.html
System.Data.SQLite.SQLiteConnection.Close.html
System.Data.SQLite.SQLiteConnection.GetSchema_overloads.html
System.Data.SQLite.SQLiteConnection.GetSchema_overload_1.html
System.Data.SQLite.SQLiteConnection.GetSchema_overload_2.html
System.Data.SQLite.SQLiteConnection.GetSchema_overload_3.html
System.Data.SQLite.SQLiteConnection.Open.html
System.Data.SQLite.SQLiteConnectionEvents.html
System.Data.SQLite.SQLiteConnection.StateChange.html
System.Data.SQLite.SQLiteConnectionStringBuilder.html
System.Data.SQLite.SQLiteConnectionStringBuilderMembers.html
System.Data.SQLite.SQLiteConnectionStringBuilderConstructor.html
System.Data.SQLite.SQLiteConnectionStringBuilderConstructor1.html
System.Data.SQLite.SQLiteConnectionStringBuilderConstructor2.html
System.Data.SQLite.SQLiteConnectionStringBuilderProperties.html
System.Data.SQLite.SQLiteConnectionStringBuilder.CacheSize.html
System.Data.SQLite.SQLiteConnectionStringBuilder.DataSource.html
System.Data.SQLite.SQLiteConnectionStringBuilder.DateTimeFormat.html
System.Data.SQLite.SQLiteConnectionStringBuilder.PageSize.html
System.Data.SQLite.SQLiteConnectionStringBuilder.SyncMode.html
System.Data.SQLite.SQLiteConnectionStringBuilder.UseUTF16Encoding.html
System.Data.SQLite.SQLiteConnectionStringBuilder.Version.html
System.Data.SQLite.SQLiteConvert.html
System.Data.SQLite.SQLiteConvertMembers.html
System.Data.SQLite.SQLiteConvertMethods.html
System.Data.SQLite.SQLiteConvert.Split.html
System.Data.SQLite.SQLiteConvert.ToDateTime.html
System.Data.SQLite.SQLiteConvert.ToString_overloads.html
System.Data.SQLite.SQLiteConvert.ToString_overload_2.html
System.Data.SQLite.SQLiteConvert.ToString_overload_1.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overloads.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overload_2.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overload_1.html
System.Data.SQLite.SQLiteConvert.TryToDateTime.html
System.Data.SQLite.SQLiteDataAdapter.html
System.Data.SQLite.SQLiteDataAdapterMembers.html
System.Data.SQLite.SQLiteDataAdapterConstructor.html
System.Data.SQLite.SQLiteDataAdapterConstructor1.html
System.Data.SQLite.SQLiteDataAdapterConstructor2.html
System.Data.SQLite.SQLiteDataAdapterConstructor3.html
System.Data.SQLite.SQLiteDataAdapterConstructor4.html
System.Data.SQLite.SQLiteDataReader.html
System.Data.SQLite.SQLiteDataReaderMembers.html
System.Data.SQLite.SQLiteDataReaderProperties.html
System.Data.SQLite.SQLiteDataReader.Depth.html
System.Data.SQLite.SQLiteDataReader.FieldCount.html
System.Data.SQLite.SQLiteDataReader.HasRows.html
System.Data.SQLite.SQLiteDataReader.IsClosed.html
System.Data.SQLite.SQLiteDataReaderItem.html
System.Data.SQLite.SQLiteDataReader.Item2.html
System.Data.SQLite.SQLiteDataReader.Item1.html
System.Data.SQLite.SQLiteDataReader.RecordsAffected.html
System.Data.SQLite.SQLiteDataReaderMethods.html
System.Data.SQLite.SQLiteDataReader.Close.html
System.Data.SQLite.SQLiteDataReader.Dispose.html
System.Data.SQLite.SQLiteDataReader.GetBoolean.html
System.Data.SQLite.SQLiteDataReader.GetByte.html
System.Data.SQLite.SQLiteDataReader.GetBytes.html
System.Data.SQLite.SQLiteDataReader.GetChar.html
System.Data.SQLite.SQLiteDataReader.GetChars.html
System.Data.SQLite.SQLiteDataReader.GetDataTypeName.html
System.Data.SQLite.SQLiteDataReader.GetDateTime.html
System.Data.SQLite.SQLiteDataReader.GetDecimal.html
System.Data.SQLite.SQLiteDataReader.GetDouble.html
System.Data.SQLite.SQLiteDataReader.GetEnumerator.html
System.Data.SQLite.SQLiteDataReader.GetFieldType.html
System.Data.SQLite.SQLiteDataReader.GetFloat.html
System.Data.SQLite.SQLiteDataReader.GetGuid.html
System.Data.SQLite.SQLiteDataReader.GetInt16.html
System.Data.SQLite.SQLiteDataReader.GetInt32.html
System.Data.SQLite.SQLiteDataReader.GetInt64.html
System.Data.SQLite.SQLiteDataReader.GetName.html
System.Data.SQLite.SQLiteDataReader.GetOrdinal.html
System.Data.SQLite.SQLiteDataReader.GetSchemaTable.html
System.Data.SQLite.SQLiteDataReader.GetString.html
System.Data.SQLite.SQLiteDataReader.GetValue.html
System.Data.SQLite.SQLiteDataReader.GetValues.html
System.Data.SQLite.SQLiteDataReader.IsDBNull.html
System.Data.SQLite.SQLiteDataReader.NextResult.html
System.Data.SQLite.SQLiteDataReader.Read.html
System.Data.SQLite.SQLiteException.html
System.Data.SQLite.SQLiteExceptionMembers.html
System.Data.SQLite.SQLiteFactory.html
System.Data.SQLite.SQLiteFactoryMembers.html
System.Data.SQLite.SQLiteFactoryConstructor.html
System.Data.SQLite.SQLiteFactoryFields.html
System.Data.SQLite.SQLiteFactory.Instance.html
System.Data.SQLite.SQLiteFactoryProperties.html
System.Data.SQLite.SQLiteFactory.SupportedClasses.html
System.Data.SQLite.SQLiteFactoryMethods.html
System.Data.SQLite.SQLiteFactory.CreateCommand.html
System.Data.SQLite.SQLiteFactory.CreateCommandBuilder.html
System.Data.SQLite.SQLiteFactory.CreateConnection.html
System.Data.SQLite.SQLiteFactory.CreateConnectionStringBuilder.html
System.Data.SQLite.SQLiteFactory.CreateDataAdapter.html
System.Data.SQLite.SQLiteFactory.CreateParameter.html
System.Data.SQLite.SQLiteFunction.html
System.Data.SQLite.SQLiteFunctionMembers.html
System.Data.SQLite.SQLiteFunctionConstructor.html
System.Data.SQLite.SQLiteFunctionProperties.html
System.Data.SQLite.SQLiteFunction.SQLiteConvert.html
System.Data.SQLite.SQLiteFunctionMethods.html
System.Data.SQLite.SQLiteFunction.Compare.html
System.Data.SQLite.SQLiteFunction.Dispose_overloads.html
System.Data.SQLite.SQLiteFunction.Dispose_overload_2.html
System.Data.SQLite.SQLiteFunction.Dispose_overload_1.html
System.Data.SQLite.SQLiteFunction.Final.html
System.Data.SQLite.SQLiteFunction.Invoke.html
System.Data.SQLite.SQLiteFunction.RegisterFunction.html
System.Data.SQLite.SQLiteFunction.Step.html
System.Data.SQLite.SQLiteFunctionAttribute.html
System.Data.SQLite.SQLiteFunctionAttributeMembers.html
System.Data.SQLite.SQLiteFunctionAttributeConstructor.html
System.Data.SQLite.SQLiteFunctionAttributeFields.html
System.Data.SQLite.SQLiteFunctionAttribute.Arguments.html
System.Data.SQLite.SQLiteFunctionAttribute.FuncType.html
System.Data.SQLite.SQLiteFunctionAttribute.Name.html
System.Data.SQLite.SQLiteParameter.html
System.Data.SQLite.SQLiteParameterMembers.html
System.Data.SQLite.SQLiteParameterConstructor.html
System.Data.SQLite.SQLiteParameterConstructor1.html
System.Data.SQLite.SQLiteParameterConstructor2.html
System.Data.SQLite.SQLiteParameterConstructor3.html
System.Data.SQLite.SQLiteParameterConstructor4.html
System.Data.SQLite.SQLiteParameterConstructor5.html
System.Data.SQLite.SQLiteParameterConstructor6.html
System.Data.SQLite.SQLiteParameterConstructor7.html
System.Data.SQLite.SQLiteParameterConstructor8.html
System.Data.SQLite.SQLiteParameterConstructor9.html
System.Data.SQLite.SQLiteParameterConstructor10.html
System.Data.SQLite.SQLiteParameterConstructor11.html
System.Data.SQLite.SQLiteParameterConstructor12.html
System.Data.SQLite.SQLiteParameterConstructor13.html
System.Data.SQLite.SQLiteParameterConstructor14.html
System.Data.SQLite.SQLiteParameterProperties.html
System.Data.SQLite.SQLiteParameter.DbType.html
System.Data.SQLite.SQLiteParameter.Direction.html
System.Data.SQLite.SQLiteParameter.IsNullable.html
System.Data.SQLite.SQLiteParameter.Offset.html
System.Data.SQLite.SQLiteParameter.ParameterName.html
System.Data.SQLite.SQLiteParameter.Size.html
System.Data.SQLite.SQLiteParameter.SourceColumn.html
System.Data.SQLite.SQLiteParameter.SourceColumnNullMapping.html
System.Data.SQLite.SQLiteParameter.SourceVersion.html
System.Data.SQLite.SQLiteParameter.Value.html
System.Data.SQLite.SQLiteParameterMethods.html
System.Data.SQLite.SQLiteParameter.CopyTo.html
System.Data.SQLite.SQLiteParameter.ResetDbType.html
System.Data.SQLite.SQLiteParameterCollection.html
System.Data.SQLite.SQLiteParameterCollectionMembers.html
System.Data.SQLite.SQLiteParameterCollectionProperties.html
System.Data.SQLite.SQLiteParameterCollection.Count.html
System.Data.SQLite.SQLiteParameterCollection.IsFixedSize.html
System.Data.SQLite.SQLiteParameterCollection.IsReadOnly.html
System.Data.SQLite.SQLiteParameterCollection.IsSynchronized.html
System.Data.SQLite.SQLiteParameterCollection.SyncRoot.html
System.Data.SQLite.SQLiteParameterCollectionMethods.html
System.Data.SQLite.SQLiteParameterCollection.Add_overloads.html
System.Data.SQLite.SQLiteParameterCollection.Add_overload_4.html
System.Data.SQLite.SQLiteParameterCollection.Add_overload_5.html
System.Data.SQLite.SQLiteParameterCollection.Add_overload_3.html
System.Data.SQLite.SQLiteParameterCollection.Add_overload_2.html
System.Data.SQLite.SQLiteParameterCollection.Add_overload_1.html
System.Data.SQLite.SQLiteParameterCollection.AddRange_overloads.html
System.Data.SQLite.SQLiteParameterCollection.AddRange_overload_2.html
System.Data.SQLite.SQLiteParameterCollection.AddRange_overload_1.html
System.Data.SQLite.SQLiteParameterCollection.Clear.html
System.Data.SQLite.SQLiteParameterCollection.Contains_overloads.html
System.Data.SQLite.SQLiteParameterCollection.Contains_overload_2.html
System.Data.SQLite.SQLiteParameterCollection.Contains_overload_1.html
System.Data.SQLite.SQLiteParameterCollection.CopyTo.html
System.Data.SQLite.SQLiteParameterCollection.GetEnumerator.html
System.Data.SQLite.SQLiteParameterCollection.IndexOf_overloads.html
System.Data.SQLite.SQLiteParameterCollection.IndexOf_overload_2.html
System.Data.SQLite.SQLiteParameterCollection.IndexOf_overload_1.html
System.Data.SQLite.SQLiteParameterCollection.Insert.html
System.Data.SQLite.SQLiteParameterCollection.Remove.html
System.Data.SQLite.SQLiteParameterCollection.RemoveAt_overloads.html
System.Data.SQLite.SQLiteParameterCollection.RemoveAt_overload_2.html
System.Data.SQLite.SQLiteParameterCollection.RemoveAt_overload_1.html
System.Data.SQLite.SQLiteTransaction.html
System.Data.SQLite.SQLiteTransactionMembers.html
System.Data.SQLite.SQLiteTransactionProperties.html
System.Data.SQLite.SQLiteTransaction.IsolationLevel.html
System.Data.SQLite.SQLiteTransactionMethods.html
System.Data.SQLite.SQLiteTransaction.Commit.html
System.Data.SQLite.SQLiteTransaction.Dispose.html
System.Data.SQLite.SQLiteTransaction.Rollback.html
System.Data.SQLite.SyncMode.html
System.Data.SQLite.TypeAffinity.html
Compiling HTML Help file...
Compiling Html Help file
Microsoft HTML Help Compiler 4.74.8702

Compiling c:\src\SQLite.NET\Doc\ndoc_msdn_temp\SQLite.NET.chm


Compile time: 0 minutes, 3 seconds
233	Topics
1,346	Local links
0	Internet links
8	Graphics


Created c:\src\SQLite.NET\Doc\ndoc_msdn_temp\SQLite.NET.chm, 135,017 bytes
Compression decreased file by 734,402 bytes.

Html Help compile complete
Done.
Deleted Externals/Eagle/bin/Eagle.dll.

cannot compute difference between binary files

Deleted Externals/Eagle/bin/EagleShell.exe.

cannot compute difference between binary files

Deleted Externals/Eagle/bin/EagleShell.exe.config.
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
<?xml version="1.0" encoding="UTF-8" ?>
<!--
 *
 * EagleShell.exe.config -
 *
 * Copyright (c) 2007-2010 by Joe Mistachkin.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: $
 *
-->
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>

  <runtime>
    <!--
    <NetFx40_LegacySecurityPolicy enabled="true" />
    <generatePublisherEvidence enabled="false" />
    -->

    <!--
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Eagle"
                          publicKeyToken="29c6297630be05eb"
                          culture="neutral" />

        <bindingRedirect oldVersion="1.0.0.0-1.0.9999.65535"
                         newVersion="[info engine PatchLevel]" />
      </dependentAssembly>

      <dependentAssembly>
        <assemblyIdentity name="Eagle"
                          publicKeyToken="1e22ec67879739a2"
                          culture="neutral" />

        <bindingRedirect oldVersion="1.0.0.0-1.0.9999.65535"
                         newVersion="[info engine PatchLevel]" />
      </dependentAssembly>
    </assemblyBinding>
    -->
  </runtime>
</configuration>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































Deleted Externals/Eagle/bin/EagleShell.exe.mda.config.
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
<?xml version="1.0" encoding="UTF-8" ?>
<!--
 *
 * EagleShell.exe.mda.config -
 *
 * Copyright (c) 2007-2010 by Joe Mistachkin.  All rights reserved.
 *
 * 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">
  <assistants>
    <!--
    <bindingFailure />
    <callbackOnCollectedDelegate listSize="50" />
    <contextSwitchDeadlock enable="true" />
    <dangerousThreadingAPI />
    <dateTimeInvalidLocalFormat />
    <dirtyCastAndCallOnInterface />
    <disconnectedContext enable="true" />
    <dllMainReturnsFalse />
    <exceptionSwallowedOnCallFromCom enable="true" />
    <failedQI />
    <fatalExecutionEngineError />
    <gcManagedToUnmanaged />
    <gcUnmanagedToManaged />
    <illegalPrepareConstrainedRegion />
    <invalidApartmentStateChange />
    <invalidCERCall />
    <invalidFunctionPointerInDelegate enable="true" />
    <invalidGCHandleCookie />
    <invalidIUnknown />
    <invalidMemberDeclaration />
    <invalidOverlappedToPinvoke />
    <invalidVariant />
    <jitCompilationStart>
      <methods>
        <match name="*" />
      </methods>
    </jitCompilationStart>
    <loaderLock />
    <loadFromContext />
    <marshalCleanupError enable="true" />
    <marshaling>
      <methodFilter>
        <match name="*" />
      </methodFilter>
      <fieldFilter>
        <match name="*" />
      </fieldFilter>
    </marshaling>
    <memberInfoCacheCreation />
    <moduloObjectHashcode modulus="1" />
    <nonComVisibleBaseClass />
    <notMarshalable />
    <openGenericCERCall />
    <overlappedFreeError />
    <pInvokeLog>
      <filter>
        <match dllName="advapi32.dll" />
        <match dllName="advpack.dll" />
        <match dllName="kernel32.dll" />
        <match dllName="mscoree.dll" />
        <match dllName="ntdll.dll" />
        <match dllName="shell32.dll" />
        <match dllName="user32.dll" />
        <match dllName="wintrust.dll" />
      </filter>
    </pInvokeLog>
    <pInvokeStackImbalance />
    <raceOnRCWCleanup />
    <reentrancy />
    <releaseHandleFailed />
    <reportAvOnComRelease allowAv="true" />
    <streamWriterBufferedDataLost />
    <virtualCERCall />
    -->
  </assistants>
</mdaConfig>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































Deleted Externals/Eagle/lib/Eagle1.0/embed.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
###############################################################################
#
# embed.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Application Embedding Initialization File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

#
# STUB: This script file is a placeholder.  This file, when present, is always
#       evaluated when an interpreter is initialized.  Applications embedding
#       Eagle can place custom application-specific, interpreter-specific
#       initialization and/or customizations in here.  Additionally, this file
#       may contain per-interpreter customizations required when porting to
#       new platforms, operating systems, etc.
#

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































Deleted Externals/Eagle/lib/Eagle1.0/init.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
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
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
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
###############################################################################
#
# init.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Interpreter Initialization File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

#
# NOTE: Use our own namespace here because even though we do not directly
#       support namespaces ourselves, we do not want to pollute the global
#       namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
  #
  # NOTE: This is the procedure that detects whether or not we are
  #       running in Eagle (otherwise, we are running in vanilla Tcl).
  #       This procedure must function correctly in both Tcl and Eagle
  #       and must return non-zero only when running in Eagle.
  #
  proc isEagle {} {
    #
    # NOTE: Nothing too fancy or expensive should be done in here.  In
    #       theory, use of this routine should be rare; however, in
    #       practice, this routine is actually used quite a bit (e.g.
    #       by the test suite).
    #
    return [expr {[info exists ::tcl_platform(engine)] && \
        [string compare -nocase eagle $::tcl_platform(engine)] == 0}]
  }

  proc haveGaruda { {varName ""} } {
    #
    # NOTE: Check for a variable name to place the Garuda package Id into.
    #
    if {[string length $varName] > 0} then {
      upvar 1 $varName packageId
    }

    #
    # NOTE: Is the Eagle Package for Tcl (Garuda) available?  This check
    #       is different in Eagle and Tcl.
    #
    if {[isEagle]} then {
      return [expr {[llength [info commands tcl]] > 0 && [tcl ready] && \
          [catch {tcl eval [tcl master] package present Garuda}] == 0 && \
          [catch {tcl eval [tcl master] garuda packageid} packageId] == 0}]
    } else {
      return [expr {[catch {package present Garuda}] == 0 && \
          [catch {garuda packageid} packageId] == 0}]
    }
  }

  #
  # NOTE: This is the procedure that detects whether or not we are
  #       running in Eagle on Mono (otherwise, we are running in Tcl
  #       or in Eagle on .NET).  This procedure must function correctly
  #       in both Tcl and Eagle and must return non-zero only when
  #       running in Eagle on Mono.
  #
  proc isMono {} {
    return [expr {[info exists ::eagle_platform(runtime)] && \
        [string compare -nocase mono $::eagle_platform(runtime)] == 0}]
  }

  proc getEnvironmentVariable { name } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    return [expr {[info exists ::env($name)] ? $::env($name) : ""}]
  }

  proc getCompileInfo {} {
    #
    # NOTE: Return the important compile-time information for use by the
    #       setup or other callers.
    #
    return [expr {[isEagle] ? [lappend result \
        TimeStamp $::eagle_platform(timeStamp) \
        ImageRuntimeVersion $::eagle_platform(imageRuntimeVersion) \
        ModuleVersionId $::eagle_platform(moduleVersionId) \
        CompileOptions $::eagle_platform(compileOptions)] : ""}]
  }

  proc getPlatformInfo { name {default ""} } {
    #
    # NOTE: Return the important platform information for use by the test
    #       suite or other callers.
    #
    return [expr {[isEagle] && [info exists ::eagle_platform($name)] && \
        [string length [string trim $::eagle_platform($name)]] > 0 ? \
        $::eagle_platform($name) : $default}]
  }

  proc getPluginPath { pattern } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    foreach loaded [info loaded] {
      if {[regexp -- $pattern [lindex $loaded end]]} then {
        return [lindex $loaded 0]
      }
    }

    return ""
  }

  proc appendArgs { args } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set result ""; eval append result $args
  }

  proc lappendArgs { args } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    eval lappend result $args
  }

  proc getDictionaryValue { dictionary name {default ""} {wrap ""} } {
    #
    # NOTE: Locate the named value we are interested in.  The dictionary must
    #       be a list with an even number of elements in the following format:
    #
    #       <name1> <value1> <name2> <value2> ... <nameN> <valueN>
    #
    foreach {pairName pairValue} $dictionary {
      #
      # NOTE: Does this name match the one specified by the caller?
      #
      if {$pairName eq $name} then {
        #
        # NOTE: Return the value, optionally wrapped.
        #
        return [appendArgs $wrap $pairValue $wrap]
      }
    }

    #
    # NOTE: Return the default value.
    #
    return $default
  }

  proc getColumnValue { row column {default ""} {wrap ""} } {
    #
    # NOTE: Start with the default value.
    #
    set result $default

    #
    # NOTE: Locate the index of the named column we are interested in.
    #       This requires Tcl 8.5 or Eagle.
    #
    set index [lsearch -exact -index 0 $row $column]

    #
    # NOTE: Did we find the column name in the row?
    #
    if {$index != -1} then {
      #
      # NOTE: Grab the column value.
      #
      set result [appendArgs $wrap [lindex [lindex $row $index] end] $wrap]
    }

    return $result
  }

  proc getRowColumnValue { varName id column {default ""} {wrap ""} } {
    #
    # NOTE: Start with the default value.
    #
    set result $default

    #
    # NOTE: We need acccess to the result array (from the context of the
    #       caller).
    #
    upvar 1 $varName rows

    #
    # NOTE: Make sure we have the first result row.
    #
    if {[info exists rows($id)]} then {
      #
      # NOTE: Grab the entire row we are interested in.
      #
      set row $rows($id)

      #
      # NOTE: Grab the value at the specified column.
      #
      set result [getColumnValue $row $column $default $wrap]
    }

    return $result
  }

  proc readFile { fileName } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set file_id [open $fileName RDONLY]
    fconfigure $file_id -encoding binary -translation binary; # BINARY DATA
    set result [read $file_id]
    close $file_id
    return $result
  }

  proc readSharedFile { fileName } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set command [list open $fileName RDONLY]

    #
    # HACK: Tcl appears to do this by default; however Eagle does not and
    #       will not.  Therefore, manually add the -share option to the
    #       command if running in Eagle.
    #
    if {[isEagle]} then {
      lappend command 0 file -share readWrite
    }

    #
    # NOTE: Open the file using the command constructed above, configure
    #       the channel for binary data, and output the data to it.
    #
    set file_id [eval $command]
    fconfigure $file_id -encoding binary -translation binary; # BINARY DATA
    set result [read $file_id]
    close $file_id
    return $result
  }

  proc writeFile { fileName data } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set file_id [open $fileName {WRONLY CREAT TRUNC}]
    fconfigure $file_id -encoding binary -translation binary; # BINARY DATA
    puts -nonewline $file_id $data
    close $file_id
    return ""
  }

  proc appendFile { fileName data } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set file_id [open $fileName {WRONLY CREAT APPEND}]
    fconfigure $file_id -encoding binary -translation binary; # BINARY DATA
    puts -nonewline $file_id $data
    close $file_id
    return ""
  }

  proc appendLogFile { fileName data } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set file_id [open $fileName {WRONLY CREAT APPEND}]
    fconfigure $file_id -encoding binary -translation \
        [expr {[isEagle] ? "protocol" : "auto"}]; # LOG DATA
    puts -nonewline $file_id $data
    close $file_id
    return ""
  }

  proc appendSharedFile { fileName data } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set command [list open $fileName {WRONLY CREAT APPEND}]

    #
    # HACK: Tcl appears to do this by default; however Eagle does not and
    #       will not.  Therefore, manually add the -share option to the
    #       command if running in Eagle.
    #
    if {[isEagle]} then {
      lappend command 0 file -share readWrite
    }

    #
    # NOTE: Open the file using the command constructed above, configure
    #       the channel for binary data, and output the data to it.
    #
    set file_id [eval $command]
    fconfigure $file_id -encoding binary -translation binary; # BINARY DATA
    puts -nonewline $file_id $data; flush $file_id
    close $file_id
    return ""
  }

  proc appendSharedLogFile { fileName data } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set command [list open $fileName {WRONLY CREAT APPEND}]

    #
    # HACK: Tcl appears to do this by default; however Eagle does not and
    #       will not.  Therefore, manually add the -share option to the
    #       command if running in Eagle.
    #
    if {[isEagle]} then {
      lappend command 0 file -share readWrite
    }

    #
    # NOTE: Open the file using the command constructed above, configure
    #       the channel for binary data, and output the data to it.
    #
    set file_id [eval $command]
    fconfigure $file_id -encoding binary -translation \
        [expr {[isEagle] ? "protocol" : "auto"}]; # LOG DATA
    puts -nonewline $file_id $data; flush $file_id
    close $file_id
    return ""
  }

  proc readAsciiFile { fileName } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set file_id [open $fileName RDONLY]
    fconfigure $file_id -encoding ascii -translation auto; # ASCII TEXT
    set result [read $file_id]
    close $file_id
    return $result
  }

  proc writeAsciiFile { fileName data } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set file_id [open $fileName {WRONLY CREAT TRUNC}]
    fconfigure $file_id -encoding ascii -translation auto; # ASCII TEXT
    puts -nonewline $file_id $data
    close $file_id
    return ""
  }

  proc readUnicodeFile { fileName } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set file_id [open $fileName RDONLY]
    fconfigure $file_id -encoding unicode -translation auto; # UNICODE TEXT
    set result [read $file_id]
    close $file_id
    return $result
  }

  proc writeUnicodeFile { fileName data } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    set file_id [open $fileName {WRONLY CREAT TRUNC}]
    fconfigure $file_id -encoding unicode -translation auto; # UNICODE TEXT
    puts -nonewline $file_id $data
    close $file_id
    return ""
  }

  proc getDirResultPath { pattern path } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #       Is the result path itself already absolute?
    #
    if {[file pathtype $path] eq "absolute"} then {
      #
      # NOTE: Ok, the result path is already absolute.
      #       Normalize and return it.
      #
      return [file normalize $path]
    } elseif {[file pathtype $pattern] eq "absolute"} then {
      #
      # NOTE: The pattern refers to an absolute path.  Strip
      #       the final part of the pattern and join it with
      #       the result path (which we already know is not
      #       absolute).
      #
      return [file normalize [file join [file dirname $pattern] $path]]
    } else {
      #
      # NOTE: Neither the result path nor the input pattern
      #       contain an absolute path; therefore, use the
      #       current directory to hang the result path on.
      #
      return [file normalize [file join [pwd] $path]]
    }
  }

  proc addToPath { dir } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    # NOTE: Normalize to an operating system native path.
    #
    set dir [file nativename $dir]

    #
    # NOTE: On Windows, use PATH; otherwise (i.e. Unix), use
    #       LD_LIBRARY_PATH.
    #
    if {$::tcl_platform(platform) eq "windows"} then {
      set name PATH
    } else {
      set name LD_LIBRARY_PATH
    }

    #
    # NOTE: Make sure the directory is not already in the
    #       loader search path.
    #
    if {[info exists ::tcl_platform(pathSeparator)]} then {
      set separator $::tcl_platform(pathSeparator)
    } elseif {$::tcl_platform(platform) eq "windows"} then {
      set separator \;
    } else {
      set separator :
    }

    #
    # NOTE: Does the necessary environment variable exist?
    #
    if {[info exists ::env($name)]} then {
      #
      # NOTE: Grab the value of the environment variable.
      #
      set value $::env($name)

      #
      # BUGBUG: Consider exact case only for now.
      #
      if {[lsearch -exact [split $value $separator] $dir] == -1} then {
        #
        # NOTE: Append the directory to the loader search path.
        #       This allows us to subsequently load DLLs that
        #       implicitly attempt to load other DLLs that are
        #       not in the application directory.
        #
        set ::env($name) [join [list $value $dir] $separator]

        #
        # NOTE: Yes, we altered the search path.
        #
        return true
      }
    } else {
      #
      # NOTE: Create the loader search path with the directory.
      #
      set ::env($name) $dir

      #
      # NOTE: Yes, we created the search path.
      #
      return true
    }

    #
    # NOTE: No, we did not alter the search path.
    #
    return false
  }

  proc removeFromPath { dir } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    # NOTE: Normalize to an operating system native path.
    #
    set dir [file nativename $dir]

    #
    # NOTE: On Windows, use PATH; otherwise (i.e. Unix), use
    #       LD_LIBRARY_PATH.
    #
    if {$::tcl_platform(platform) eq "windows"} then {
      set name PATH
    } else {
      set name LD_LIBRARY_PATH
    }

    #
    # NOTE: Make sure the directory is in the loader search
    #       path.
    #
    if {[info exists ::tcl_platform(pathSeparator)]} then {
      set separator $::tcl_platform(pathSeparator)
    } elseif {$::tcl_platform(platform) eq "windows"} then {
      set separator \;
    } else {
      set separator :
    }

    #
    # NOTE: We need to separate the directories in the path
    #       so that we can selectively remove the one we are
    #       looking for.
    #
    set dirs [split $::env($name) $separator]

    #
    # BUGBUG: Consider exact case only for now.
    #
    set index [lsearch -exact $dirs $dir]

    #
    # NOTE: Is the directory in the loader search path?
    #
    if {$index != -1} then {
      #
      # NOTE: Remove the directory from the loader search path.
      #
      set dirs [lreplace $dirs $index $index]

      #
      # NOTE: Replace the original loader search path with
      #       our modified one.
      #
      set ::env($name) [join $dirs $separator]

      #
      # NOTE: Yes, we altered the search path.
      #
      return true
    }

    #
    # NOTE: No, we did not alter the search path.
    #
    return false
  }

  proc execShell { options args } {
    set command [list exec]

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

    lappend command --

    #
    # HACK: Assume that Mono is somewhere along the PATH.
    #
    if {[isMono]} then {
      lappend command mono \
          [appendArgs \" [file nativename [info nameofexecutable]] \"]
    } else {
      lappend command [info nameofexecutable]
    }

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

    return [uplevel 1 $command]
  }

  proc ldifference { list1 list2 } {
    set result [list]

    foreach element $list1 {
      if {[lsearch -exact $list2 $element] == -1} then {
        lappend result $element
      }
    }

    foreach element $list2 {
      if {[lsearch -exact $list1 $element] == -1} then {
        lappend result $element
      }
    }

    return $result
  }

  proc filter { list script } {
    set result [list]

    foreach item $list {
      if {[uplevel 1 $script [list $item]]} then {
        lappend result $item
      }
    }

    return $result
  }

  proc map { list script } {
    set result [list]

    foreach item $list {
      lappend result [uplevel 1 $script [list $item]]
    }

    return $result
  }

  proc reduce { list script } {
    set result ""

    foreach item $list {
      set result [uplevel 1 $script [list $result] [list $item]]
    }

    return $result
  }

  if {[isEagle]} then {
    ###########################################################################
    ############################ BEGIN Eagle ONLY #############################
    ###########################################################################

    proc isAdministrator {} {
      #
      # NOTE: Returns non-zero if the logged on user has full administrator
      #       rights on this machine.
      #
      return [expr {[info exists ::eagle_platform(administrator)] && \
          $::eagle_platform(administrator)}]
    }

    proc hasRuntimeOption { name } {
      #
      # NOTE: Returns non-zero if the specified runtime option is set.
      #
      return [object invoke Interpreter.GetActive HasRuntimeOption $name]
    }

    proc getPluginFlags { pattern } {
      foreach loaded [info loaded] {
        set plugin [lindex $loaded end]

        if {[regexp -- $pattern $plugin]} then {
          return [string map [list , " "] \
              [getDictionaryValue [info plugin $plugin] flags]]
        }
      }

      return [list]
    }

    proc getProcesses { name } {
      #
      # NOTE: Start with an empty list of process Ids.
      #
      set result [list]

      #
      # NOTE: Does the caller want processes matching a specific name
      #       or all processes on the local machine?
      #
      if {[string length $name] > 0} then {
        #
        # NOTE: Get the managed array of processes with matching names.
        #
        set array [object invoke -alias System.Diagnostics.Process \
            GetProcessesByName $name]
      } else {
        #
        # NOTE: Get the managed array of all processes on the local
        #       machine.
        #
        set array [object invoke -alias System.Diagnostics.Process \
            GetProcesses]
      }

      #
      # NOTE: For each process in the resulting array, grab the Id.
      #
      for {set index 0} {$index < [$array Length]} {incr index} {
        #
        # NOTE: Grab the Nth process array element value using the
        #       accessor method.
        #
        set process [$array -alias GetValue $index]

        #
        # NOTE: Add the Id of the process to the result list.
        #
        lappend result [$process Id]

        #
        # NOTE: Get rid of the process object, we no longer need it.
        #       Technically, it is not a requirement to explicitly
        #       unset variables that contain object references;
        #       however, it is useful in helping to document the
        #       code.
        #
        unset process; # dispose
      }

      #
      # NOTE: Get rid of the managed array of processes, we no longer
      #       need it.
      #
      unset array; # dispose

      #
      # NOTE: Return the list of process Ids, which may be empty.
      #
      return $result
    }

    proc waitForProcesses { ids timeout } {
      #
      # NOTE: Wait for each process in the list to exit.
      #
      foreach id $ids {
        #
        # NOTE: Get the process object by its Id.  If it does not exist,
        #       this will raise an error.
        #
        set result [catch {
          set process [object invoke -alias System.Diagnostics.Process \
              GetProcessById $id]
        }]

        #
        # NOTE: Were we able to grab the process object?
        #
        if {$result == 0 && [info exists process]} then {
          #
          # NOTE: Wait a while for the process to exit.
          #
          $process WaitForExit $timeout
        }

        #
        # NOTE: Get rid of the process (if we actually obtained it to
        #       begin with).
        #
        unset -nocomplain process; # dispose
      }
    }

    #
    # NOTE: This proc can be used to dynamically compile C# code in a script.
    #
    proc compileCSharp {
            string memory symbols strict resultsVarName errorsVarName args } {
      #
      # NOTE: Create the C# code provider object (i.e. the compiler).
      #
      set provider [object create -alias Microsoft.CSharp.CSharpCodeProvider]

      #
      # NOTE: Create the object that provides various parameters to the C#
      #       code provider (i.e. the compiler options).
      #
      set parameters [object create -alias \
          System.CodeDom.Compiler.CompilerParameters]

      #
      # NOTE: Do we not want to persist the generated assembly to disk?
      #
      if {$memory} then {
        $parameters GenerateInMemory true
      }

      #
      # NOTE: Do we want symbols to be generated for the generated assembly?
      #
      if {$symbols} then {
        $parameters IncludeDebugInformation true
      }

      #
      # NOTE: Make sure that the "standard" preprocessor defines match those
      #       for the platform (i.e. the ones used to compile the Eagle core
      #       library assembly).
      #
      set platformOptions [expr { \
          [info exists ::eagle_platform(compileOptions)] ? \
          $::eagle_platform(compileOptions) : [list]}]

      if {[llength $platformOptions] > 0} then {
        #
        # NOTE: Grab the existing compiler options, if any.
        #
        set compilerOptions [$parameters CompilerOptions]

        if {"DEBUG" in $platformOptions} then {
          append compilerOptions " /define:DEBUG"
        }

        if {"TRACE" in $platformOptions} then {
          append compilerOptions " /define:TRACE"
        }

        #
        # NOTE: Reset the compiler options to the pre-existing ones plus the
        #       extra defines we may have added (above).
        #
        $parameters CompilerOptions $compilerOptions
      }

      #
      # NOTE: Process any extra compiler settings the caller may have
      #       provided.
      #
      foreach {name value} $args {
        $parameters -nocase $name $value
      }

      #
      # NOTE: Prepare to transfer the object reference to the caller.  We
      #       must use upvar here because otherwise the object is lost when
      #       the procedure call frame is cleaned up.
      #
      upvar 1 $resultsVarName results

      #
      # NOTE: Attempt to compile the specified string as C# and capture the
      #       results into the variable provided by the caller.
      #
      set results [$provider -alias CompileAssemblyFromSource $parameters \
          $string]

      #
      # NOTE: We no longer need the C# code provider object (i.e. the
      #       compiler); therefore, dispose it now.
      #
      unset provider; # dispose

      #
      # NOTE: Fetch the collection of compiler errors (which may be empty).
      #
      set errors [$results -alias Errors]

      #
      # NOTE: It is assumed that no assembly was generated if there were
      #       any compiler errors.  Ignore all compiler warnings unless
      #       we are in strict mode.
      #
      if {[$errors HasErrors] || ($strict && [$errors HasWarnings])} then {
        #
        # NOTE: Compilation of the assembly failed.
        #
        set code Error

        #
        # NOTE: Prepare to transfer the error messages to the caller.
        #
        upvar 1 $errorsVarName local_errors

        #
        # NOTE: How many compile errors?
        #
        set count [$errors Count]

        #
        # NOTE: Grab each error object and append the string itself to
        #       the overall list of errors.
        #
        for {set index 0} {$index < $count} {incr index} {
          #
          # NOTE: Get the compiler error object at this index.
          #
          set error [$errors -alias Item $index]

          #
          # NOTE: Convert it to a string and append it to the list of
          #       errors.
          #
          lappend local_errors [$error ToString]

          #
          # NOTE: Since the error itself is actually an object, we must
          #       dispose it.
          #
          unset error; # dispose
        }
      } else {
        #
        # NOTE: Compilation of the assembly succeeded.
        #
        set code Ok
      }

      #
      # NOTE: We no longer need the collection of compiler errors;
      #       therefore, dispose it now.
      #
      unset errors; # dispose

      return $code
    }

    proc matchEngineName { name } {
      return [expr {[string length $name] == 0 || \
          $name eq [info engine Name]}]
    }

    proc matchEngineCulture { culture } {
      return [expr {[string length $culture] == 0 || \
          $culture eq [info engine Culture]}]
    }

    proc escapeUpdateNotes { notes } {
      #
      # NOTE: Escape any embedded tab and line-ending characters.
      #
      return [string map \
          [list & &amp\; \t &htab\; \v &vtab\; \n &lf\; \r &cr\;] $notes]
    }

    proc unescapeUpdateNotes { notes } {
      #
      # NOTE: Unescape any embedded tab and line-ending characters.
      #
      return [string map \
          [list &htab\; \t &vtab\; \v &lf\; \n &cr\; \r &amp\; &] $notes]
    }

    proc getFetchUpdateArgs { baseUri patchLevel type directory extension } {
      #
      # NOTE: Initially, set the result to an empty list to indicate
      #       unrecognized input.
      #
      set result [list]

      #
      # NOTE: Make sure the base URI is valid.
      #
      if {[uri isvalid $baseUri]} then {
        #
        # NOTE: Make sure the patch level looks valid.
        #
        if {[regexp -- {^\d+\.\d+\.\d+\.\d+$} $patchLevel]} then {
          #
          # NOTE: Make sure the directory is either empty or an existing
          #       valid directory.
          #
          if {[string length $directory] == 0 || \
              [file isdirectory $directory]} then {
            #
            # NOTE: Make sure the extension is supported.
            #
            if {$extension eq ".exe" || $extension eq ".rar"} then {
              #
              # NOTE: Start with the URI components common to all download
              #       types.
              #
              set components [list $baseUri releases $patchLevel]

              #
              # NOTE: Next, figure out what type of download is being
              #       requested.
              #
              switch -exact -nocase -- $type {
                source {
                  #
                  # NOTE: Source code download.  This may be a RAR or an EXE
                  #       file.  Append the appropriate file name and then
                  #       join all the URI components to form the final URI.
                  #
                  set fileName [appendArgs EagleSource $patchLevel $extension]
                  lappend components $fileName

                  set result [list [eval uri join $components] \
                      [file join $directory $fileName]]
                }
                setup {
                  #
                  # NOTE: Windows setup download.  Always append an ".exe"
                  #       extension because we never distribute the setup as
                  #       a RAR file.  Append the appropriate file name and
                  #       then join all the URI components to form the final
                  #       URI.
                  #
                  set fileName [appendArgs EagleSetup $patchLevel .exe]
                  lappend components $fileName

                  set result [list [eval uri join $components] \
                      [file join $directory $fileName]]
                }
                binary {
                  #
                  # NOTE: Binary file download.  This may be a RAR or an EXE
                  #       file.  Append the appropriate file name and then
                  #       join all the URI components to form the final URI.
                  #
                  set fileName [appendArgs EagleBinary $patchLevel $extension]
                  lappend components $fileName

                  set result [list [eval uri join $components] \
                      [file join $directory $fileName]]
                }
              }
            }
          }
        }
      }

      return $result
    }

    proc fetchUpdate { baseUri patchLevel type directory } {
      #
      # NOTE: Figure out the appropriate file extension to download for
      #       this platform.
      #
      set extension [expr {$::tcl_platform(platform) eq "windows" ? \
          ".exe" : ".rar"}]

      #
      # NOTE: Build the necessary arguments for the download.
      #
      set args [getFetchUpdateArgs $baseUri $patchLevel $type \
          $directory $extension]

      if {[llength $args] > 0} then {
        #
        # NOTE: Temporarily start trusting ONLY our self-signed certificate
        #       which is used primarily for "software updates".
        #
        uri softwareupdates true

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

        #
        # NOTE: Return a result indicating what was done.
        #
        return [appendArgs "downloaded URI " [lindex $args 0] \
            " to directory \"" $directory \"]
      } else {
        return "cannot fetch update, the URI is invalid"
      }
    }

    proc runUpdateAndExit {} {
      set directory [file dirname [info nameofexecutable]]

      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.

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

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

      #
      # NOTE: Read all the data out of the downloaded text file.
      #
      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.
      #
      set data [string map [list \r\n \n] $data]; # Unix.

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

      #
      # NOTE: Check each line to find the build information...
      #
      foreach line $lines {
        #
        # NOTE: Remove excess whitespace.
        #
        set line [string trim $line]

        #
        # NOTE: Skip blank lines.
        #
        if {[string length $line] > 0} then {
          #
          # 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:
            #
            # protocolId <tab> publicKeyToken <tab> name <tab> culture
            # <tab> patchLevel <tab> timeStamp <tab> uri <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]

            #
            # NOTE: Grab the public key token field.
            #
            set publicKeyToken [lindex $fields 1]

            #
            # NOTE: Grab the name field.
            #
            set name [lindex $fields 2]

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

            #
            # 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" && \
                $publicKeyToken eq [info engine PublicKeyToken] && \
                [matchEngineName $name] && \
                [matchEngineCulture $culture]} then {
              #
              # NOTE: Grab the patch level field.
              #
              set patchLevel [lindex $fields 4]

              if {[string length $patchLevel] == 0} then {
                set patchLevel 0.0.0.0; # no patch level?
              }

              #
              # NOTE: Grab the patch level for the running engine.
              #
              set enginePatchLevel [info engine PatchLevel]

              #
              # 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 {
                #
                # 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 {
                  set baseUri [info engine Uri]; # primary site.
                }

                #
                # NOTE: Grab the notes field (which may be empty).
                #
                set notes [lindex $fields 10]

                if {[string length $notes] > 0} then {
                  set notes [unescapeUpdateNotes $notes]
                }

                #
                # NOTE: Does it look like the number of seconds since the
                #       epoch or some kind of date/time string?
                #
                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.
                #
                return [list [appendArgs "newer build " $patchLevel \
                    " is available as of " $dateTime] [list $baseUri \
                    $patchLevel] [list $notes]]
              } elseif {$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 "your build " $enginePatchLevel \
                    " is newer than the latest build " $patchLevel]]
              } else {
                #
                # NOTE: The patch levels are equal, we are up-to-date.
                #
                return [list "you have the latest build"]
              }
            }
          }
        }
      }

      return [list "cannot determine if your build is the latest"]
    }

    proc getReturnType { object member } {
      if {[string length $object] == 0 || [string length $member] == 0} then {
        return ""
      }

      set code [catch {
        object foreach -alias memberInfo \
            [object invoke -noinvoke $object $member] {
          #
          # NOTE: Use the member type to determine which property contains
          #       the type information we want to return.
          #
          switch -exact -- [$memberInfo MemberType] {
            Field {
              return [$memberInfo FieldType.AssemblyQualifiedName]
            }
            Method {
              return [$memberInfo ReturnType.AssemblyQualifiedName]
            }
            Property {
              return [$memberInfo PropertyType.AssemblyQualifiedName]
            }
            default {
              return ""
            }
          }
        }
      } result]

      #
      # NOTE: If no error was raised above, return the result; otherwise,
      #       return an empty string to indicate a general failure.
      #
      return [expr {$code == 2 ? $result : ""}]
    }

    proc getDefaultValue { typeName } {
      if {[string length $typeName] == 0} then {
        return ""
      }

      set type [object invoke -alias Type GetType $typeName]

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

      return [expr {[$type IsValueType] ? 0 : "null"}]
    }

    proc parray { a {pattern *} } {
      upvar 1 $a array

      if {![array exists array]} {
        error "\"$a\" isn't an array"
      }

      set names [lsort [array names array $pattern]]
      set maxLength 0

      foreach name $names {
        set length [string length $name]

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

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

      foreach name $names {
        #
        # NOTE: Format the array element name for display.
        #
        set nameString [appendArgs $a ( $name )]

        #
        # NOTE: If the value by itself is too long to fit on one host
        #       line, just truncate and ellipsis it.
        #
        set valueString $array($name)

        if {[string length $valueString] > $valueLength} then {
          set valueString [appendArgs [string range $valueString 0 \
              [expr {$valueLength - 4}]] " ..."]
        }

        #
        # HACK: Mono does not currently support calling the String.Format
        #       overload that takes a variable number of arguments via
        #       reflection (Mono bug #636939).
        #
        if {![isMono]} then {
          set line [string format -verbatim -- "{0,-$maxLength} = {1}" \
              $nameString $valueString]
        } else {
          set line [object invoke String Format "{0,-$maxLength} = {1}" \
              $nameString $valueString]
        }

        puts stdout $line
      }
    }

    proc pdict { d } {
      foreach {name value} $d {
        puts stdout "$name = $value"
      }
    }

    proc test { name description args } {
      #
      # NOTE: Determine if the caller is trying to run an old style or
      #       new style test and use the appropriate command.
      #
      if {[string index [lindex $args 0] 0] eq "-"} then {
        #
        # NOTE: New style test, use [test2] command.
        #
        set command test2
      } else {
        #
        # NOTE: Old style test, use [test1] command.
        #
        set command test1
      }

      return [uplevel 1 [list $command $name $description] $args]
    }

    proc unknown { name args } {
      #
      # NOTE: This is a stub unknown procedure that simply produces an
      #       appropriate error message.
      #
      # TODO: Add support for auto-loading packages here in the future?
      #
      return -code error "invalid command name \"$name\""
    }

    #
    # TODO: Revise or remove this procedure when full [namespace]
    #       support has been added.
    #
    proc ::tcl::tm::UnknownHandler { original name args } {
      #
      # NOTE: Do nothing except call the original handler.
      #
      uplevel 1 $original [::linsert $args 0 $name]
    }

    proc tclPkgUnknown { name args } {
      #
      # NOTE: Force a rescan of "pkgIndex" files.  This must be done in
      #       the global scope so that the special global variable 'dir'
      #       set by the package index loading subsystem can be accessed.
      #
      uplevel #0 [list package scan -host -normal -refresh]
    }

    proc tclLog { string } {
      #
      # NOTE: This should work properly in both Tcl and Eagle.
      #
      catch {puts stderr $string}
    }

    proc findDirectories { pattern } {
      #
      # NOTE: This should work properly in Eagle only.
      #
      set result [list]

      foreach dir [split [exec $::env(ComSpec) /c dir /ad /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
        set dir [string trim $dir]

        if {[string length $dir] > 0} then {
          set dir [getDirResultPath $pattern $dir]

          if {[lsearch -exact -nocase $result $dir] == -1} then {
            lappend result $dir
          }
        }
      }

      foreach dir [split [exec $::env(ComSpec) /c dir /ahd /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
        set dir [string trim $dir]

        if {[string length $dir] > 0} then {
          set dir [getDirResultPath $pattern $dir]

          if {[lsearch -exact -nocase $result $dir] == -1} then {
            lappend result $dir
          }
        }
      }

      return $result
    }

    proc findFiles { pattern } {
      #
      # NOTE: This should work properly in Eagle only.
      #
      set result [list]

      foreach fileName [split [exec $::env(ComSpec) /c dir /a-d /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
        set fileName [string trim $fileName]

        if {[string length $fileName] > 0} then {
          set fileName [getDirResultPath $pattern $fileName]

          if {[lsearch -exact -nocase $result $fileName] == -1} then {
            lappend result $fileName
          }
        }
      }

      foreach fileName [split [exec $::env(ComSpec) /c dir /ah-d /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
        set fileName [string trim $fileName]

        if {[string length $fileName] > 0} then {
          set fileName [getDirResultPath $pattern $fileName]

          if {[lsearch -exact -nocase $result $fileName] == -1} then {
            lappend result $fileName
          }
        }
      }

      return $result
    }

    proc findFilesRecursive { pattern } {
      #
      # NOTE: This should work properly in Eagle only.
      #
      set result [list]

      foreach fileName [split [exec $::env(ComSpec) /c dir /a-d /s /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
        set fileName [string trim $fileName]

        if {[string length $fileName] > 0} then {
          set fileName [getDirResultPath $pattern $fileName]

          if {[lsearch -exact -nocase $result $fileName] == -1} then {
            lappend result $fileName
          }
        }
      }

      foreach fileName [split [exec $::env(ComSpec) /c dir /ah-d /s /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
        set fileName [string trim $fileName]

        if {[string length $fileName] > 0} then {
          set fileName [getDirResultPath $pattern $fileName]

          if {[lsearch -exact -nocase $result $fileName] == -1} then {
            lappend result $fileName
          }
        }
      }

      return $result
    }

    ###########################################################################
    ############################# END Eagle ONLY ##############################
    ###########################################################################
  } else {
    ###########################################################################
    ############################# BEGIN Tcl ONLY ##############################
    ###########################################################################

    proc getLengthModifier { value } {
      #
      # NOTE: This should work properly in both Tcl and Eagle.
      #
      return [expr {int($value) != wide($value) ? "l" : ""}]
    }

    proc debug { args } {
      #
      # NOTE: This should work properly in both Tcl and Eagle.
      #
      puts stdout [lrange $args 2 end]
    }

    proc findDirectories { pattern } {
      #
      # NOTE: This should work properly in Tcl only.
      #
      eval lappend result [glob -nocomplain -types {d} \
          [file normalize $pattern]]

      eval lappend result [glob -nocomplain -types {d hidden} \
          [file normalize $pattern]]

      return $result
    }

    proc findFiles { pattern } {
      #
      # NOTE: This should work properly in Tcl only.
      #
      eval lappend result [glob -nocomplain -types {f} \
          [file normalize $pattern]]

      eval lappend result [glob -nocomplain -types {f hidden} \
          [file normalize $pattern]]

      return $result
    }

    proc findFilesRecursive { pattern } {
      #
      # NOTE: This should work properly in Tcl only.
      #
      set result [list]

      catch {
        foreach fileName [split [exec $::env(ComSpec) /c dir /a-d /s /b \
            [file nativename $pattern]] \n] {
          set fileName [string trim $fileName]

          if {[string length $fileName] > 0} then {
            set fileName [getDirResultPath $pattern $fileName]

            if {[lsearch -exact -nocase $result $fileName] == -1} then {
              lappend result $fileName
            }
          }
        }
      }

      catch {
        foreach fileName [split [exec $::env(ComSpec) /c dir /ah-d /s /b \
            [file nativename $pattern]] \n] {
          set fileName [string trim $fileName]

          if {[string length $fileName] > 0} then {
            set fileName [getDirResultPath $pattern $fileName]

            if {[lsearch -exact -nocase $result $fileName] == -1} then {
              lappend result $fileName
            }
          }
        }
      }

      return $result
    }

    proc exportAndImportPackageCommands { namespace exports forget force } {
      #
      # NOTE: This should work properly in Tcl only.
      #
      # NOTE: Forget any previous commands that were imported from this
      #       namespace into the global namespace?
      #
      if {$forget} then {
        namespace eval :: [list namespace forget [appendArgs $namespace ::*]]
      }

      #
      # NOTE: Process each command to be exported from the specified
      #       namespace and import it into the global namespace, if
      #       necessary.
      #
      foreach export $exports {
        #
        # NOTE: Force importing of our exported commands into the global
        #       namespace?  Otherwise, see if the command is already
        #       present in the global namespace before trying to import
        #       it.
        #
        if {$force || \
            [llength [info commands [appendArgs :: $export]]] == 0} then {
          #
          # NOTE: Export the specified command from the specified namespace.
          #
          namespace eval $namespace [list namespace export $export]

          #
          # NOTE: Import the specified command into the global namespace.
          #
          set namespaceExport [appendArgs $namespace :: $export]

          if {$force} then {
            namespace eval :: [list namespace import -force $namespaceExport]
          } else {
            namespace eval :: [list namespace import $namespaceExport]
          }
        }
      }
    }

    #
    # NOTE: Exports the necessary commands from this package and import them
    #       into the global namespace.
    #
    exportAndImportPackageCommands [namespace current] [list \
        exportAndImportPackageCommands isEagle isMono getEnvironmentVariable \
        getPluginPath getDictionaryValue getColumnValue getRowColumnValue \
        appendArgs haveGaruda lappendArgs readFile filter map reduce \
        getPlatformInfo execShell] false false

    ###########################################################################
    ############################## END Tcl ONLY ###############################
    ###########################################################################
  }

  #
  # NOTE: Provide the Eagle library package to the interpreter.
  #
  package provide EagleLibrary \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Externals/Eagle/lib/Eagle1.0/pkgIndex.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
###############################################################################
#
# pkgIndex.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Package Index File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

if {![package vsatisfies [package provide Tcl] 8.4]} {return}
if {![package vsatisfies [package provide Eagle] 1.0]} {return}

package ifneeded EagleLibrary 1.0 [list source [file join $dir init.eagle]]
package ifneeded EagleSafe 1.0 [list source [file join $dir safe.eagle]]
package ifneeded EagleShell 1.0 [list source [file join $dir shell.eagle]]
package ifneeded EagleTest 1.0 [list source [file join $dir test.eagle]]
package ifneeded NativeTcl 1.0 [list error "not native Tcl"]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted Externals/Eagle/lib/Eagle1.0/pkgIndex.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
###############################################################################
#
# pkgIndex.tcl --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Package Index File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

if {![package vsatisfies [package provide Tcl] 8.4]} {return}
if {[string length [package provide Eagle]] > 0} then {return}

package ifneeded EagleLibrary 1.0 [list source [file join $dir init.eagle]]
package ifneeded EagleSafe 1.0 [list source [file join $dir safe.eagle]]
package ifneeded EagleShell 1.0 [list source [file join $dir shell.eagle]]
package ifneeded EagleTest 1.0 [list source [file join $dir test.eagle]]
package ifneeded NativeTcl 1.0 [list package provide NativeTcl 1.0]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted Externals/Eagle/lib/Eagle1.0/safe.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
###############################################################################
#
# safe.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Safe Interpreter Initialization File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

#
# NOTE: Use our own namespace here because even though we do not directly
#       support namespaces ourselves, we do not want to pollute the global
#       namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
  #
  # NOTE: This is the procedure that detects whether or not we are
  #       running in Eagle (otherwise, we are running in vanilla Tcl).
  #       This procedure must function correctly in both Tcl and Eagle
  #       and must return non-zero only when running in Eagle.
  #
  proc isEagle {} {
    #
    # NOTE: Nothing too fancy or expensive should be done in here.  In
    #       theory, use of this routine should be rare; however, in
    #       practice, this routine is actually used quite a bit (e.g.
    #       by the test suite).
    #
    return [expr {[info exists ::tcl_platform(engine)] && \
        [string compare -nocase eagle $::tcl_platform(engine)] == 0}]
  }

  if {[isEagle]} then {
    ###########################################################################
    ############################ BEGIN Eagle ONLY #############################
    ###########################################################################

    proc unknown { name args } {
      #
      # NOTE: This is a stub unknown procedure that simply produces an
      #       appropriate error message.
      #
      # TODO: Add support for auto-loading packages here in the future?
      #
      return -code error "invalid command name \"$name\""
    }

    #
    # TODO: Revise or remove this procedure when full [namespace] support has
    #       been added.
    #
    proc ::tcl::tm::UnknownHandler { original name args } {
      #
      # NOTE: Do nothing except call the original handler.
      #
      uplevel 1 $original [::linsert $args 0 $name]
    }

    proc tclPkgUnknown { name args } {
      #
      # NOTE: Do nothing since this is [most likely] a safe
      #       interpreter.
      #
      return
    }

    ###########################################################################
    ############################# END Eagle ONLY ##############################
    ###########################################################################
  }

  #
  # NOTE: Provide the Eagle "safe" package to the interpreter.
  #
  package provide EagleSafe \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































Deleted Externals/Eagle/lib/Eagle1.0/shell.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
###############################################################################
#
# shell.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Shell Initialization File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

#
# NOTE: Use our own namespace here because even though we do not directly
#       support namespaces ourselves, we do not want to pollute the global
#       namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
  if {[isEagle]} then {
    ###########################################################################
    ############################ BEGIN Eagle ONLY #############################
    ###########################################################################

    #
    # NOTE: Commands specific to initializing the Eagle interactive shell
    #       environment should be placed here.
    #

    ###########################################################################
    ############################# END Eagle ONLY ##############################
    ###########################################################################
  } else {
    ###########################################################################
    ############################# BEGIN Tcl ONLY ##############################
    ###########################################################################

    #
    # NOTE: Commands specific to initializing the Tcl interactive shell
    #       environment should be placed here.
    #

    ###########################################################################
    ############################## END Tcl ONLY ###############################
    ###########################################################################
  }

  #
  # NOTE: Provide the Eagle shell package to the interpreter.
  #
  package provide EagleShell \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































Deleted Externals/Eagle/lib/Eagle1.0/test.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
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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
###############################################################################
#
# test.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Test Initialization File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

#
# NOTE: Use our own namespace here because even though we do not directly
#       support namespaces ourselves, we do not want to pollute the global
#       namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
  proc tputs { channel string } {
    #
    # NOTE: If an output channel was provided, use it; otherwise,
    #       ignore the message.
    #
    if {[string length $channel] > 0} then {
      #
      # NOTE: Check if output is being actively intercepted by us.
      #
      if {![isEagle] && \
          [llength [info commands ::tcl::save::puts]] > 0} then {
        ::tcl::save::puts -nonewline $channel $string
      } else {
        puts -nonewline $channel $string
      }
    }

    tlog $string
  }

  proc tlog { string } {
    #
    # NOTE: If a log file was configured, use it; otherwise,
    #       ignore the message.
    #
    set fileName [getTestLog]

    if {[string length $fileName] > 0} then {
      appendSharedLogFile $fileName $string
    }
  }

  proc haveConstraint { name } {
    if {[isEagle]} then {
      return [expr {
          [info exists ::eagle_tests(constraints)] && \
          [lsearch -exact $::eagle_tests(constraints) $name] != -1}]
    } else {
      return [expr {
          [info exists ::tcltest::testConstraints($name)] && \
          $::tcltest::testConstraints($name)}]
    }
  }

  proc addConstraint { name {value 1} } {
    if {[isEagle]} then {
      if {[info exists ::eagle_tests(constraints)] && \
          [lsearch -exact $::eagle_tests(constraints) $name] == -1 && \
          $value} then {
        lappend ::eagle_tests(constraints) $name
      }
    } else {
      ::tcltest::testConstraint $name $value
    }

    return ""
  }

  proc haveOrAddConstraint { name {value ""} } {
    if {[isEagle]} then {
      if {[llength [info level 0]] == 2} then {
        return [haveConstraint $name]
      }

      return [addConstraint $name [expr {bool($value)}]]
    } else {
      return [::tcltest::testConstraint $name $value]
    }
  }

  proc getConstraints {} {
    set result [list]

    if {[isEagle]} then {
      if {[catch {set ::eagle_tests(constraints)} constraints] == 0} then {
        eval lappend result $constraints
      }
    } else {
      foreach name [array names ::tcltest::testConstraints] {
        if {$::tcltest::testConstraints($name)} then {
          lappend result $name
        }
      }
    }

    return $result
  }

  proc fixConstraints { constraints } {
    set result [string trim $constraints]

    if {[string length $result] > 0} then {
      #
      # HACK: Fixup for the magic expression (via [expr]) test
      #       constraint syntax supported by Tcltest and not by
      #       EagleTest.  This needs to happen for Tcl in test
      #       constraints that contain any characters that are
      #       not alphanumeric, not a period, and not a colon
      #       (e.g. in this case, the exclamation point);
      #       however, it should only be required when the
      #       number of test constraints is greater than one.
      #
      if {![isEagle]} then {
        if {[string first ! $result] != -1} then {
          #
          # HACK: All of our test constraints assume they are
          #       "logically and-ed" together.
          #
          set result [join [split $result] " && "]
        }
      }
    }

    return $result
  }

  proc calculateRelativePerformance { type value } {
    #
    # NOTE: Adjust the expected performance number based on the
    #       relative performance of this machine, if available.
    #
    if {[info exists ::test_base_cops] && [info exists ::test_cops]} then {
      #
      # NOTE: Calibrate the expected performance numbers based
      #       on the ratio of the baseline performace to the
      #       current performance.
      #
      switch -exact -- $type {
        elapsed {
          if {$::test_cops != 0} then {
            return [expr {double($value) * \
                ($::test_base_cops / $::test_cops)}]
          }
        }
        iterations {
          if {$::test_base_cops != 0} then {
            return [expr {double($value) * \
                ($::test_cops / $::test_base_cops)}]
          }
        }
      }
    }

    return $value
  }

  proc sourceIfValid { type fileName } {
    if {[string length $fileName] > 0} then {
      if {[file exists $fileName]} then {
        tputs $::test_channel [appendArgs \
            "---- evaluating $type file: \"" $fileName \"\n]

        if {[catch {uplevel 1 [list source $fileName]} error]} then {
          tputs $::test_channel [appendArgs \
              "---- error during $type file: " $error \n]

          #
          # NOTE: The error has been logged, now re-throw it.
          #
          error $error $::errorInfo $::errorCode
        }
      } else {
        tputs $::test_channel [appendArgs \
            "---- skipped $type file: \"" $fileName \
            "\", it does not exist\n"]
      }
    }
  }

  proc processTestArguments { varName args } {
    #
    # NOTE: We are going to place the configured options in
    #       the variable identified by the name provided by
    #       the caller.
    #
    upvar 1 $varName array

    #
    # TODO: Add more support for standard tcltest options here.
    #
    set options [list -configuration -constraints -exitOnComplete -file \
        -logFile -match -no -notFile -postTest -preTest -skip -stopOnFailure \
        -suffix -threshold]

    foreach {name value} $args {
      if {[lsearch -exact $options $name] != -1} then {
        set array($name) $value

        tputs $::test_channel [appendArgs \
            "---- overrode test option \"" $name "\" with value \"" $value \
            \"\n]
      } else {
        tputs $::test_channel [appendArgs \
            "---- unknown test option \"" $name "\" with value \"" $value \
            "\" ignored\n"]
      }
    }
  }

  proc getTemporaryPath {} {
    #
    # NOTE: Build the list of "temporary directory" override
    #       environment variables to check.
    #
    set names [list]

    foreach name [list TEMP TMP] {
      #
      # NOTE: Make sure we handle all the reasonable "cases" of
      #       the environment variable names.
      #
      lappend names [string toupper $name] [string tolower $name] \
          [string totitle $name]
    }

    #
    # NOTE: Check if we can use any of the environment variables.
    #
    foreach name $names {
      set value [getEnvironmentVariable $name]

      if {[string length $value] > 0} then {
        return [file normalize $value]
      }
    }

    if {[isEagle]} then {
      #
      # NOTE: Eagle fallback, use whatever is reported by the
      #       underlying framework and/or operating system.
      #
      return [file normalize [object invoke System.IO.Path GetTempPath]]
    } else {
      #
      # NOTE: Tcl fallback, *assume* that we can use the
      #       directory where the executable is running for
      #       temporary storage.
      #
      return [file normalize [file dirname [info nameofexecutable]]]
    }
  }

  proc getFiles { directory pattern } {
    if {[isEagle]} then {
      return [lsort -dictionary [file list $directory $pattern]]
    } else {
      return [lsort -dictionary [glob -directory $directory -types \
          {b c f p s} -nocomplain -- $pattern]]
    }
  }

  proc getTestFiles { directories matchFilePatterns skipFilePatterns } {
    set result [list]

    foreach directory $directories {
      set matchFileNames [list]

      foreach pattern $matchFilePatterns {
        eval lappend matchFileNames [getFiles $directory $pattern]
      }

      set skipFileNames [list]

      foreach pattern $skipFilePatterns {
        eval lappend skipFileNames [getFiles $directory $pattern]
      }

      foreach fileName $matchFileNames {
        if {[lsearch -exact $skipFileNames $fileName] == -1} then {
          lappend result $fileName
        }
      }
    }

    return $result
  }

  proc getTestRunId {} {
    #
    # HACK: Yes, this is a bit ugly; however, it creates a nice unique
    #       identifier to represent the test run, which makes analyzing
    #       the test log files a lot easier.
    #
    if {[isEagle]} 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 {random()}

      #
      # NOTE: Include the host name to make the result more unique in both
      #       time and space.  Also, hash the entire constructed string.
      #
      if {![isMono]} then {
        #
        # NOTE: When running on the .NET Framework, we can simply use the
        #       [string format] command.
        #
        return [hash normal sha256 [string format \
            "{0}{1:X8}{2:X8}{3:X16}{4:X16}{5:X16}" [info host] [pid] \
            [info tid] [clock now] [clock clicks] [expr $expr]]]
      } else {
        #
        # HACK: Mono does not currently support calling the String.Format
        #       overload that takes a variable number of arguments via
        #       reflection (Mono bug #636939).  Also, strip any leading
        #       minus signs for cleanliness.
        #
        return [hash normal sha256 [appendArgs [info host] [string trimleft \
            [pid] -] [string trimleft [info tid] -] [string trimleft \
            [clock now] -] [string trimleft [clock clicks] -] [string trimleft \
            [expr $expr] -]]]
      }
    } else {
      #
      # NOTE: Generate a random number using [expr] and then convert it
      #       to hexadecimal.
      #
      binary scan [binary format d* [expr {rand()}]] w* random

      #
      # NOTE: Convert the host name to a hexadecimal string and include
      #       it in the result in an attempt to make it more unique in
      #       both time and space.
      #
      binary scan [info host] c* host
      set host [eval [list format [string repeat %X [llength $host]]] $host]

      #
      # NOTE: Build the final result with the [format] command, converting
      #       all the pieces to hexadecimal (except the host, which is
      #       already hexadecimal).
      #
      set pid [pid]; set seconds [clock seconds]; set clicks [clock clicks]

      return [appendArgs $host [format [appendArgs % [getLengthModifier $pid] \
          X% [getLengthModifier $seconds] X% [getLengthModifier $clicks] X% \
          [getLengthModifier $random] X] $pid $seconds $clicks $random]]
    }
  }

  proc getTestLogId {} {
    return [expr {[info exists ::test_log_id] ? \
        [append result . $::test_log_id] : ""}]
  }

  proc getTestLog {} {
    return [expr {[info exists ::test_log] ? $::test_log : ""}]
  }

  proc testExec { commandName options args } {
    set command [list exec]

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

    lappend command -- $commandName

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

    tputs $::test_channel [appendArgs "---- running command: " $command \n]

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

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

    lappend command --

    #
    # HACK: Assume that Mono is somewhere along the PATH.
    #
    if {[isMono]} then {
      lappend command mono \
          [appendArgs \" [file nativename $commandName] \"]
    } else {
      lappend command $commandName
    }

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

    tputs $::test_channel [appendArgs "---- running command: " $command \n]

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

    return [uplevel 1 execShell [list $options] $args]
  }

  proc isStopOnFailure {} {
    return [expr {[info exists ::test_stop_on_failure] && \
                  [string is boolean -strict $::test_stop_on_failure] && \
                  $::test_stop_on_failure}]
  }

  proc isExitOnComplete {} {
    return [expr {[info exists ::test_exit_on_complete] && \
                  [string is boolean -strict $::test_exit_on_complete] && \
                  $::test_exit_on_complete}]
  }

  proc returnInfoScript {} {
    return [info script]
  }

  proc runTestPrologue {} {
    #
    # HACK: We do not want to force every third-party test suite
    #       to come up with a half-baked solution to finding its
    #       own files.
    #
    if {![info exists ::no(prologue.eagle)] && ![info exists ::path]} then {
      set ::path [file normalize [file dirname [info script]]]
    }

    #
    # NOTE: Evaluate the standard test prologue in the context of
    #       the caller.
    #
    uplevel 1 [list source [file join $::test_path prologue.eagle]]
  }

  proc runTestEpilogue {} {
    #
    # NOTE: Evaluate the standard test epilogue in the context of
    #       the caller.
    #
    uplevel 1 [list source [file join $::test_path epilogue.eagle]]

    #
    # HACK: We do not want to force every third-party test suite
    #       to come up with a half-baked solution to finding its
    #       own files.
    #
    if {![info exists ::no(epilogue.eagle)] && [info exists ::path]} then {
      unset ::path
    }
  }

  proc hookPuts {} {
    #
    # NOTE: This code was stolen from tcltest and heavily modified to work
    #       with Eagle.
    #
    proc [namespace current]::testPuts { args } {
      switch [llength $args] {
        1 {
          #
          # NOTE: Only the string to be printed is specified (stdout).
          #
          return [tputs $::test_channel [lindex $args 0]]
        }
        2 {
          #
          # NOTE: Either -nonewline or channelId has been specified.
          #
          if {[lindex $args 0] eq "-nonewline"} then {
            return [tputs $::test_channel [lindex $args end]]
          } else {
            set channel [lindex $args 0]
            set newLine \n
          }
        }
        3 {
          #
          # NOTE: Both -nonewline and channelId are specified, unless
          #       it's an error.  The -nonewline option is supposed to
          #       be argv[0].
          #
          if {[lindex $args 0] eq "-nonewline"} then {
            set channel [lindex $args 1]
            set newLine ""
          }
        }
      }

      if {[info exists channel]} then {
        if {$channel eq "stdout"} then {
          #
          # NOTE: Write output for stdout to the test channel.
          #
          return [tputs $::test_channel [appendArgs [lindex $args end] \
              $newLine]]
        }
      }

      #
      # NOTE: If we haven't returned by now, we don't know how to
      #       handle the input.  Let puts handle it.
      #
      return [eval ::tcl::save::puts $args]
    }

    rename ::puts ::tcl::save::puts; # save Tcl command
    rename [namespace current]::testPuts ::puts; # insert our proc
  }

  proc unhookPuts {} {
    rename ::puts ""; # remove our proc
    rename ::tcl::save::puts ::puts; # restore Tcl command
  }

  proc runTest { script } {
    #
    # NOTE: This should work properly in both Tcl and Eagle as long as the
    #       "init" script has been evaluated first.
    #
    if {![isEagle]} then {
      hookPuts
    }

    set code [catch {uplevel 1 $script} result]
    set error [expr {$code == 0 ? false : true}]

    if {[isEagle]} then {
      if {$code == 0 && [regexp -- {\s==== (.*?) FAILED\s} $result]} then {
        set code 1
      }

      #
      # NOTE: Display and log the result of the test we just completed.
      #
      host result $code $result
      tlog $result

      #
      # NOTE: If the test failed with an actual error (i.e. not just a
      #       test failure), make sure we do not obscure the error
      #       message with test suite output.
      #
      if {$error} then {
        tputs $::test_channel \n; # emit a blank line.
      }

      #
      # NOTE: If this test failed and the stop-on-failure flag is set,
      #       raise an error now.  If we are being run from inside
      #       runAllTests, this will also serve to signal it to stop
      #       processing further test files.
      #
      if {$code != 0 && [isStopOnFailure]} then {
        host result Error "OVERALL RESULT: STOP-ON-FAILURE\n"
        tlog "OVERALL RESULT: STOP-ON-FAILURE\n"

        error ""; # no message
      }
    } else {
      if {$error} then {
        tputs $::test_channel [appendArgs "ERROR (runTest): " $result \n]
      }

      unhookPuts
    }
  }

  proc testShim { args } {
    #
    # NOTE: Call the original (saved) [test] command, wrapping it in
    #       our standard test wrapper.
    #
    uplevel 1 [list runTest [concat ::savedTest $args]]
  }

  proc tsource { fileName {prologue true} {epilogue true} } {
    #
    # NOTE: Run the test prologue in the context of the caller (which
    #       must be global)?
    #
    if {$prologue} then {
      uplevel 1 runTestPrologue
    }

    #
    # NOTE: Save the original [test] command and setup our test shim in
    #       its place.
    #
    rename ::test ::savedTest
    interp alias {} ::test {} testShim

    #
    # NOTE: Source the specified test file in the context of the caller
    #       (which should be global).
    #
    set code [catch {uplevel 1 [list source $fileName]} result]
    set error [expr {$code == 0 ? false : true}]

    #
    # NOTE: Remove our test shim and restore the original (saved) [test]
    #       command.
    #
    interp alias {} ::test {}
    rename ::savedTest ::test

    #
    # NOTE: Run the test epilogue in the context of the caller (which
    #       must be global)?
    #
    if {$epilogue} then {
      uplevel 1 runTestEpilogue
    }

    #
    # NOTE: If the test raised an error, re-raise it now; otherwise,
    #       just return the result.
    #
    if {$error} then {
      error $result
    } else {
      return $result
    }
  }

  proc recordTestStatistics { varName index } {
    #
    # NOTE: Record counts of all object types that we track.
    #
    upvar 1 $varName array

    set array(time,$index) [clock seconds]
    set array(afters,$index) [llength [after info]]
    set array(variables,$index) [llength [info globals]]
    set array(commands,$index) [llength [info commands]]
    set array(procedures,$index) [llength [info procs]]
    set array(files,$index) [llength [getFiles $::test_path *]]
    set array(temporaryFiles,$index) [llength [getFiles [getTemporaryPath] *]]
    set array(channels,$index) [llength [file channels]]
    set array(aliases,$index) [llength [interp aliases]]
    set array(interpreters,$index) [llength [interp slaves]]
    set array(environment,$index) [llength [array names env]]

    if {[isEagle]} then {
      set array(scopes,$index) [llength [scope list]]
      set array(objects,$index) [llength [info objects]]
      set array(callbacks,$index) [llength [info callbacks]]
      set array(types,$index) [llength [object types]]
      set array(interfaces,$index) [llength [object interfaces]]
      set array(namespaces,$index) [llength [object namespaces]]
      set array(processes,$index,list) [getProcesses ""]; # volatile, external
      set array(processes,$index) [llength $array(processes,$index,list)]
      set array(assemblies,$index) [llength [object assemblies]]

      #
      # NOTE: Support for some of all of these entity types may not be
      #       present in the interpreter, initialize all these counts
      #       to zero and then try to query each one individually below
      #       wrapped in a catch.
      #
      set array(connections,$index) 0
      set array(transactions,$index) 0
      set array(modules,$index) 0
      set array(delegates,$index) 0
      set array(tcl,$index) 0
      set array(tclinterps,$index) 0
      set array(tclthreads,$index) 0
      set array(tclcommands,$index) 0

      catch {set array(connections,$index) [llength [info connections]]}
      catch {set array(transactions,$index) [llength [info transactions]]}
      catch {set array(modules,$index) [llength [info modules]]}
      catch {set array(delegates,$index) [llength [info delegates]]}

      if {[llength [info commands tcl]] > 0} then {
        set array(tcl,$index) [tcl ready]
      }

      catch {set array(tclinterps,$index) [llength [tcl interps]]}
      catch {set array(tclthreads,$index) [llength [tcl threads]]}
      catch {set array(tclcommands,$index) [llength [tcl command list]]}
    }
  }

  proc reportTestStatistics { channel fileName statsVarName filesVarName } {
    set statistics [list afters variables commands procedures files \
        temporaryFiles channels aliases interpreters environment]

    if {[isEagle]} then {
      #
      # TODO: For now, tracking "leaked" assemblies is meaningless because
      #       the .NET Framework has no way to unload them without tearing
      #       down the entire application domain.
      #
      lappend statistics scopes objects callbacks types interfaces \
          namespaces processes connections transactions modules \
          delegates tcl tclinterps tclthreads tclcommands; # assemblies
    }

    #
    # NOTE: Show what leaked, if anything.
    #
    set count 0; upvar 1 $statsVarName array

    foreach statistic $statistics {
      if {$array($statistic,after) > $array($statistic,before)} then {
        incr count

        tputs $channel [appendArgs "==== \"" $fileName "\" LEAKED " \
            $statistic \n]

        if {[info exists array($statistic,before,list)]} then {
          tputs $channel [appendArgs "---- " $statistic " BEFORE: " \
              $array($statistic,before,list) \n]
        }

        if {[info exists array($statistic,after,list)]} then {
          tputs $channel [appendArgs "---- " $statistic " AFTER: " \
              $array($statistic,after,list) \n]
        }
      }
    }

    #
    # NOTE: Make sure this file name is recorded in the list of file names with
    #       leaking tests.
    #
    upvar 1 $filesVarName fileNames

    if {$count > 0 && \
        [lsearch -exact $fileNames [file tail $fileName]] == -1} then {
      lappend fileNames [file tail $fileName]
    }
  }

  proc formatList { list {default ""} {columns 1} } {
    set count 1
    set result ""

    foreach item $list {
      if {[incr count -1] == 0} then {
        set count $columns
        append result \n
      }

      append result \t

      if {[string length $item] > 0} then {
        append result $item
      } else {
        append result <noItem>
      }
    }

    return [expr {[string length $result] > 0 ? $result : $default}]
  }

  proc formatListAsDict { list {default ""} } {
    set result ""

    foreach {name value} $list {
      append result \n\t

      if {[string length $name] > 0} then {
        append result $name
      } else {
        append result <noName>
      }

      append result ": "

      if {[string length $value] > 0} then {
        append result $value
      } else {
        append result <noValue>
      }
    }

    return [expr {[string length $result] > 0 ? $result : $default}]
  }

  proc inverseLsearchGlob { noCase patterns element } {
    #
    # NOTE: Perform the inverse of [lsearch -glob], attempt
    #       to match an element against a list of patterns.
    #
    set command [list string match]
    if {$noCase} then {lappend command -nocase}

    for {set index 0} {$index < [llength $patterns]} {incr index} {
      set pattern [lindex $patterns $index]
      if {[eval $command [list $pattern] [list $element]]} then {return $index}
    }

    return -1
  }

  proc removePathFromFileNames { path fileNames } {
    set result [list]

    foreach fileName $fileNames {
      if {[file normalize [file dirname $fileName]] eq \
          [file normalize $path]} then {
        #
        # NOTE: Strip the path name from this file name.
        #
        lappend result [file tail $fileName]
      } else {
        lappend result $fileName
      }
    }

    return $result
  }

  proc formatDecimal { value {places 4} } {
    if {[isEagle]} 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]]]

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

    return $result
  }

  proc clearTestPercent { channel } {
    if {[isEagle]} then {
      host title ""
    }
  }

  proc reportTestPercent { channel percent failed leaked } {
    set status [appendArgs "---- test suite running, about " $percent \
        "% complete (" $failed " failed, " $leaked " leaked)..."]

    tputs $channel [appendArgs $status \n]

    if {[isEagle]} then {
      host title $status
    }
  }

  proc runAllTests { channel path fileNames skipFileNames } {
    #
    # NOTE: Show the exact arguments we received since they may not
    #       have been displayed by the caller (or anybody else).
    #
    tputs $channel [appendArgs "---- test run path: \"" $path \"\n]

    tputs $channel [appendArgs "---- test run file names: " \
        [list [removePathFromFileNames $path $fileNames]] \n]

    tputs $channel [appendArgs "---- test run skip file names: " \
        [list $skipFileNames] \n]

    #
    # NOTE: Keep going unless this becomes true (i.e. if one of the
    #       test files signals us to stop).
    #
    set stop false

    #
    # NOTE: So far, we have run no tests.
    #
    set count 0

    #
    # NOTE: So far, no files have had failing or leaking tests.
    #
    set failed [list]
    set leaked [list]

    #
    # NOTE: Process each file name we have been given by the caller...
    #
    set total [llength $fileNames]; set lastPercent -1

    foreach fileName $fileNames {
      #
      # NOTE: In terms of files, not tests, what percent done are we now?
      #
      set percent [formatDecimal \
          [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]]

      if {$percent != $lastPercent} then {
        reportTestPercent $channel $percent \
            [llength $failed] [llength $leaked]

        set lastPercent $percent
      }

      #
      # NOTE: Skipping over any file name that matches a pattern in the
      #       list of file names to skip.
      #
      if {[inverseLsearchGlob false $skipFileNames \
          [file tail $fileName]] == -1} then {
        #
        # NOTE: Does the file name contain directory information?
        #
        if {[string length [file dirname $fileName]] <= 1} then {
          #
          # NOTE: If not, assume it is under the supplied test path.
          #
          set fileName [file join $path $fileName]
        }

        #
        # NOTE: The "magic" pattern we are looking for to determine if a
        #       given file is part of the formal test suite.
        #
        set pattern {^(\s)*runTest .*$}

        #
        # NOTE: Skip files that are not part of the test suite.
        #
        set data [readFile $fileName]

        #
        # NOTE: Check for a match.
        #
        set match [regexp -line -- $pattern $data]

        #
        # NOTE: Failing that, in Eagle only, check if the data, when
        #       interpreted as Unicode, matches the pattern.
        #
        if {!$match && [isEagle]} then {
          set match [regexp -line -- $pattern \
              [encoding convertfrom unicode $data]]
        }

        #
        # NOTE: Does this "look" like an actual test suite file?
        #
        if {$match} then {
          #
          # BUGFIX: Unset the current test file name so that variable
          #         accounting works correctly.  It will be reset below
          #         prior to running any actual test(s).
          #
          unset -nocomplain ::test_file

          #
          # NOTE: Is resource leak checking explicitly disabled?
          #
          if {![info exists ::no(leak)]} then {
            #
            # NOTE: Get "before" resource counts for leak tracking.
            #
            recordTestStatistics leaks before
          }

          #
          # NOTE: Let the test prologue code know which file we are
          #       evaluating.
          #
          set ::test_file $fileName

          #
          # NOTE: Record failed test count before this file.
          #
          if {[isEagle]} then {
            set before $::eagle_tests(failed)
          } else {
            set before $::tcltest::numTests(Failed)
          }

          #
          # NOTE: Evaluate the file in the context of the caller,
          #       catching any errors.  If an error is raised and the
          #       stop-on-failure flag is set, assume it was a test
          #       failure and that we need to stop any and all further
          #       processing of test files.
          #
          if {[catch {uplevel 1 [list source $fileName]} error]} then {
            #
            # NOTE: Most likely, this error was caused by malformed or
            #       incorrect code in-between the tests themselves.  We
            #       need to report this.
            #
            tputs $channel [appendArgs "==== \"" $fileName "\" ERROR \"" \
                $error \"\n]

            #
            # NOTE: Stop further processing after this loop iteration?
            #
            if {[isStopOnFailure]} then {
              #
              # NOTE: This will terminate the loop right after the test
              #       file cleanup code (i.e. at the bottom of the loop).
              #
              set stop true
            }
          }

          #
          # NOTE: We evaluated another test file.
          #
          incr count

          #
          # NOTE: In terms of files, not tests, what percent done are we now?
          #
          set percent [formatDecimal \
              [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]]

          if {$percent != $lastPercent} then {
            reportTestPercent $channel $percent \
                [llength $failed] [llength $leaked]

            set lastPercent $percent
          }

          #
          # NOTE: Record failed test count after this file.
          #
          if {[isEagle]} then {
            set after $::eagle_tests(failed)
          } else {
            set after $::tcltest::numTests(Failed)
          }

          #
          # NOTE: Did this file have any failing tests?
          #
          if {$after > $before} then {
            lappend failed [file tail $fileName]
          }

          #
          # NOTE: Unset the current test file name, it is no longer
          #       needed.
          #
          unset -nocomplain ::test_file

          #
          # NOTE: Is resource leak checking explicitly disabled?
          #
          if {![info exists ::no(leak)]} then {
            #
            # NOTE: Get "after" resource counts for leak tracking.
            #
            recordTestStatistics leaks after

            #
            # NOTE: Determine if any resource leaks have occurred and
            #       output diagnostics as necessary if they have.
            #
            reportTestStatistics $channel $fileName leaks leaked
          }
        } else {
          #
          # NOTE: This file does not actually count towards the total (i.e.
          #       it contains no actual tests).
          #
          incr total -1
        }

        #
        # NOTE: In terms of files, not tests, what percent done are we now?
        #
        set percent [formatDecimal \
            [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]]

        if {$percent != $lastPercent} then {
          reportTestPercent $channel $percent \
              [llength $failed] [llength $leaked]

          set lastPercent $percent
        }

        #
        # NOTE: If the test file raised an error (i.e. to indicate a
        #       test failure with the stop-on-failure flag enabled),
        #       break out of the test loop now.
        #
        if {$stop} then {
          break
        }
      } else {
        #
        # NOTE: This file does not actually count towards the total (i.e.
        #       it is part of the test suite infrastructure).
        #
        incr total -1
      }

      #
      # NOTE: In terms of files, not tests, what percent done are we now?
      #
      set percent [formatDecimal \
          [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]]

      if {$percent != $lastPercent} then {
        reportTestPercent $channel $percent \
            [llength $failed] [llength $leaked]

        set lastPercent $percent
      }
    }

    #
    # NOTE: Reset the host title because we may have changed it in the for
    #       loop (above).
    #
    clearTestPercent $channel

    tputs $channel [appendArgs "---- sourced " $count " test " \
        [expr {$count > 1 ? "files" : "file"}] \n]

    #
    # NOTE: Show the files that had failing and/or leaking tests.
    #
    if {[llength $failed] > 0} then {
      tputs $channel [appendArgs "---- files with failing tests: " $failed \n]
    }

    if {[llength $leaked] > 0} then {
      tputs $channel [appendArgs "---- files with leaking tests: " $leaked \n]
    }
  }

  proc configureTcltest { imports force } {
    if {[isEagle]} then {
      #
      # HACK: Flag the "test" and "runTest" script library procedures so
      #       that they use the script location of their caller and not
      #       their own.
      #
      # BUGBUG: This does not yet fix the script location issues in the
      #         test suite.
      #
      # debug procedureflags test +ScriptLocation
      # debug procedureflags runTest +ScriptLocation

      #
      # HACK: Compatibility shim(s) for use with various tests in the Tcl
      #       test suite.
      #
      interp alias {} testConstraint {} haveOrAddConstraint
      interp alias {} ::tcltest::testConstraint {} haveOrAddConstraint

      #
      # NOTE: This is needed by most tests in the Tcl test suite.
      #
      proc ::tcltest::cleanupTests { args } {}

      #
      # NOTE: Fake having the tcltest package.
      #
      package provide tcltest 2.2.10; # Tcl 8.4
    } else {
      #
      # NOTE: Load the tcltest package.
      #
      package require tcltest

      #
      # NOTE: Configure tcltest for our use.
      #
      ::tcltest::configure -verbose bpste

      #
      # NOTE: We need the [test] command in the global namespace.
      #
      if {[llength $imports] > 0} then {
        set command [list namespace import]

        if {$force} then {
          lappend command -force
        }

        foreach import $imports {
          lappend command [appendArgs ::tcltest:: $import]
        }

        namespace eval :: $command
      }
    }
  }

  if {[isEagle]} then {
    ###########################################################################
    ############################ BEGIN Eagle ONLY #############################
    ###########################################################################

    proc initializeTests {} {
      uplevel #0 {
        #
        # NOTE: Reset the information in the global "tests" array, which is
        #       used to interface with the internal test tracking information
        #       in the interpreter via a variable trace.
        #
        set eagle_tests(total) 0
        set eagle_tests(skipped) 0
        set eagle_tests(passed) 0
        set eagle_tests(failed) 0

        #
        # NOTE: Setup the lists of patterns to match test names against.  In
        #       Eagle, these originate from the command line arguments and are
        #       passed to the interpreter via this virtual array.
        #
        if {[info exists test_flags(-match)]} then {
          set eagle_tests(matchNames) $test_flags(-match); # run these tests.
        } else {
          set eagle_tests(matchNames) [list *]; # default to running all tests.
        }

        if {[info exists test_flags(-skip)]} then {
          set eagle_tests(skipNames) $test_flags(-skip); # skip these tests.
        } else {
          set eagle_tests(skipNames) [list]; # default to skipping no tests.
        }

        #
        # NOTE: What tests have been skipped, if any?
        #
        set eagle_tests(skippedNames) [list]

        #
        # NOTE: What tests have failed, if any?
        #
        set eagle_tests(failedNames) [list]

        #
        # NOTE: Initialize the list of active test constraints from the
        #       environment variable and/or the test flags.
        #
        set eagle_tests(constraints) [getEnvironmentVariable testConstraints]

        if {[info exists test_flags(-constraints)]} then {
            eval lappend eagle_tests(constraints) $test_flags(-constraints)
        }
      }
    }

    proc getPassPercentage {} {
      if {$::eagle_tests(total) > 0} then {
        return [expr \
            {100.0 * (($::eagle_tests(passed) + \
            $::eagle_tests(skipped)) / \
            double($::eagle_tests(total)))}]
      }

      return 0; # no tests were run, etc.
    }

    proc getSkipPercentage {} {
      if {$::eagle_tests(total) > 0} then {
        return [expr \
            {100.0 * ($::eagle_tests(skipped) / \
            double($::eagle_tests(total)))}]
      }

      return 0; # no tests were run, etc.
    }

    proc cleanupThread { thread {timeout 2000} } {
      if {[$thread IsAlive]} then {
        if {[catch {$thread Interrupt} error]} then {
          tputs $::test_channel [appendArgs \
              "---- failed to interrupt test thread \"" $thread "\": " $error \
              \n]
        } else {
          tputs $::test_channel [appendArgs "---- test thread \"" $thread \
              "\" interrupted\n"]
        }

        if {[$thread IsAlive]} then {
          if {[catch {$thread Join $timeout} error]} then {
            tputs $::test_channel [appendArgs \
                "---- failed to join test thread \"" $thread "\": " $error \n]
          } elseif {$error} then {
            tputs $::test_channel [appendArgs "---- joined test thread \"" \
                $thread \"\n]
          } else {
            tputs $::test_channel [appendArgs \
                "---- timeout joining test thread \"" $thread " (" $timeout \
                " milliseconds)\"\n"]
          }

          if {[$thread IsAlive]} then {
            if {[catch {$thread Abort} error]} then {
              tputs $::test_channel [appendArgs \
                  "---- failed to abort test thread \"" $thread "\": " $error \
                  \n]
            } else {
              tputs $::test_channel [appendArgs "---- test thread \"" $thread \
                  "\" aborted\n"]
            }

            if {[$thread IsAlive]} then {
              tputs $::test_channel [appendArgs "---- test thread \"" $thread \
                  "\" appears to be a zombie\n"]
            } else {
              return true; # aborted?
            }
          } else {
            return true; # joined?
          }
        } else {
          return true; # interrupted?
        }
      } else {
        return true; # already dead?
      }

      return false; # still alive (or error).
    }

    proc calculateBogoCops { {milliseconds 2000} } {
      #
      # NOTE: Save the current background error handler for later restoration
      #       and then reset the current background error handler to nothing.
      #
      set bgerror [interp bgerror {}]
      interp bgerror {} ""

      try {
        #
        # NOTE: Save the current [after] flags for later restoration and then
        #       reset them to process events immediately.
        #
        set flags [after flags]
        after flags =Immediate

        try {
          set code [catch {
            #
            # NOTE: Schedule the event to cancel the script we are about to
            #       evaluate, capturing the name so we can cancel it later, if
            #       necessary.
            #
            set event [after $milliseconds [list interp cancel]]

            #
            # HACK: There is the potential for a "race condition" here.  If the
            #       specified number of milliseconds elapses before (or after)
            #       entering the [catch] script block (below) then the resulting
            #       script cancellation error will not be caught and we will be
            #       unable to return the correct result to the caller.
            #
            set before [info cmdcount]
            catch {time {nop} -1}; # uses the [time] internal busy loop.
            set after [info cmdcount]

            #
            # HACK: Mono has a bug that results in excessive trailing zeros
            #       here (Mono bug #655780).
            #
            if {[isMono]} then {
              expr {double(($after - $before) / ($milliseconds / 1000.0))}
            } else {
              expr {($after - $before) / ($milliseconds / 1000.0)}
            }
          } result]

          #
          # NOTE: If we failed to calculate the number of commands-per-second
          #       due to some subtle race condition [as explained above], return
          #       an obviously invalid result instead.
          #
          if {$code == 0} then {
            return $result
          } else {
            return 0
          }
        } finally {
          if {[info exists event]} then {
            catch {after cancel $event}
          }

          after flags =$flags
        }
      } finally {
        interp bgerror {} $bgerror
      }
    }

    proc evalWithTimeout { script {milliseconds 2000} {resultVarName ""} } {
      #
      # NOTE: Save the current background error handler for later restoration
      #       and then reset the current background error handler to nothing.
      #
      set bgerror [interp bgerror {}]
      interp bgerror {} ""

      try {
        #
        # NOTE: Save the current [after] flags for later restoration and then
        #       reset them to process events immediately.
        #
        set flags [after flags]
        after flags =Immediate

        try {
          #
          # NOTE: Evaluate the specified script in the context of the caller,
          #       returning the result to the caller.
          #
          if {[string length $resultVarName] > 0} then {
            upvar 1 $resultVarName result
          }

          return [catch {
            #
            # NOTE: Schedule the event to cancel the script we are about to
            #       evaluate, capturing the name so we can cancel it later, if
            #       necessary.
            #
            set event [after $milliseconds [list interp cancel]]

            #
            # NOTE: Evaluate the script in the context of the caller.
            #
            uplevel 1 $script
          } result]
        } finally {
          if {[info exists event]} then {
            catch {after cancel $event}
          }

          after flags =$flags
        }
      } finally {
        interp bgerror {} $bgerror
      }
    }

    proc testExecTclScript { script } {
      try {
        #
        # NOTE: Get a temporary file name for the script we are going to
        #       use to query the machine type for the native Tcl shell.
        #
        set fileName [file tempname]

        #
        # NOTE: Since the native Tcl shell cannot simply evaluate a string
        #       supplied via the command line, write the script to be
        #       evaluated to the temporary file.
        #
        writeFile $fileName $script

        #
        # NOTE: Evaluate the script using the native Tcl shell, trim the
        #       excess whitespace from the output, and return it to the
        #       caller.
        #
        if {[catch {string trim \
            [testExec $::test_tclsh [list -success Success] \
            [appendArgs \" $fileName \"]]} result] == 0} then {
          #
          # NOTE: Success, return the result to the caller.
          #
          return $result
        } else {
          #
          # NOTE: We could not execute the native Tcl shell (perhaps one
          #       is not available?).
          #
          return error
        }
      } finally {
        #
        # NOTE: Did we create a temporary file?
        #
        if {[info exists fileName] && \
            [string length $fileName] > 0 && \
            [file exists $fileName]} then {
          #
          # NOTE: Delete the temporary file we used to query the machine
          #       type for the native Tcl shell.
          #
          catch {file delete $fileName}
        }
      }
    }

    proc getMachineForTclShell {} {
      return [testExecTclScript {
        puts -nonewline stdout $tcl_platform(machine)
      }]
    }

    proc getTkVersion {} {
      return [testExecTclScript {
        puts -nonewline stdout [package require Tk]; exit
      }]
    }

    proc machineToPlatform { machine } {
      switch -exact -nocase -- $machine {
        amd64 {
          return x64
        }
        intel {
          if {$::tcl_platform(platform) eq "windows"} then {
            return Win32
          } else {
            return x86
          }
        }
        default {
          return unknown
        }
      }
    }

    proc getGarudaDll {} {
      #
      # NOTE: Get the Garuda DLL of the same platform (i.e. machine type)
      #       as the native Tcl shell.
      #
      if {[info exists ::base_path]} then {
        #
        # NOTE: If the test configuration is available, use it.  Failing that,
        #       use the build configuration of Eagle itself.
        #
        if {[info exists ::test_configuration]} then {
          #
          # NOTE: Use the test configuration.  The default value is "Release",
          #       as set by the test suite prologue; however, this may have
          #       been overridden.
          #
          set configuration $::test_configuration
        } elseif {[info exists ::eagle_platform(configuration)]} then {
          #
          # NOTE: Use the build configuration of Eagle itself.  This value will
          #       always be "Debug" or "Release".
          #
          set configuration $::eagle_platform(configuration)
        } else {
          #
          # NOTE: We are missing the configuration, return nothing.
          #
          return ""
        }

        #
        # NOTE: Build the full path and file name of the Garuda DLL, using
        #       the Eagle base path.  Currently, this will only work
        #       correctly if the test suite is being run from inside the
        #       source tree.
        #
        return [file join $::base_path bin \
            [machineToPlatform [getMachineForTclShell]] [appendArgs \
            $configuration Dll] [appendArgs Garuda [info sharedlibextension]]]
      } else {
        #
        # NOTE: We are missing the base path, return nothing.
        #
        return ""
      }
    }

    proc cleanupExcel {} {
      #
      # TODO: These may need to be changed in later Excel versions.
      #
      object undeclare -declarepattern Microsoft.Office.Interop.Excel*
      object unimport -importpattern Microsoft.Office.Interop.Excel
    }

    proc cleanupVisualBasic {} {
      #
      # TODO: These may need to be changed in later framework versions.
      #
      object unimport -importpattern Microsoft.VisualBasic*
    }

    proc cleanupXml {} {
      #
      # TODO: These may need to be changed in later framework versions.
      #
      object unimport -importpattern System.Xml*
    }

    proc cleanupWinForms {} {
      #
      # TODO: These may need to be changed in later framework versions.
      #
      object unimport -importpattern System.Resources
      object unimport -importpattern System.Windows.Forms

      object unimport -importpattern \
          System.Windows.Forms.ComponentModel.Com2Interop

      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
    }

    #
    # 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.
      #
      set ::test_path [file join [file normalize [file dirname [file dirname \
          [info library]]]] Library Tests]

      if {![file exists $::test_path] || \
          ![file isdirectory $::test_path]} then {
        #
        # NOTE: Try for the test package directory.
        #
        set ::test_path [file join [file normalize [file dirname \
            [file dirname [info script]]]] Test1.0]
      }

      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".
        #
        set ::test_path [file join [file normalize [file dirname [file dirname \
            [info library]]]] Tests]
      }
    }

    #
    # NOTE: Fake having the tcltest package unless we are prevented.
    #
    if {![info exists ::no(configureTcltest)]} then {
      configureTcltest [list] false
    }

    ###########################################################################
    ############################# END Eagle ONLY ##############################
    ###########################################################################
  } else {
    ###########################################################################
    ############################# BEGIN Tcl ONLY ##############################
    ###########################################################################

    proc getPassPercentage {} {
      if {$::tcltest::numTests(Total) > 0} then {
        return [expr \
            {100.0 * (($::tcltest::numTests(Passed) + \
            $::tcltest::numTests(Skipped)) / \
            double($::tcltest::numTests(Total)))}]
      }

      return 0; # no tests were run, etc.
    }

    proc getSkipPercentage {} {
      if {$::tcltest::numTests(Total) > 0} then {
        return [expr \
            {100.0 * ($::tcltest::numTests(Skipped) / \
            double($::tcltest::numTests(Total)))}]
      }

      return 0; # no tests were run, etc.
    }

    #
    # NOTE: Setup the test path relative to the path of this file.
    #
    if {![info exists ::test_path]} then {
      #
      # NOTE: Try the source release directory structure.
      #
      set ::test_path [file join [file normalize [file dirname \
          [file dirname [file dirname [info script]]]]] Library Tests]

      if {![file exists $::test_path] || \
          ![file isdirectory $::test_path]} then {
        #
        # NOTE: Try for the test package directory.
        #
        set ::test_path [file join [file normalize [file dirname \
            [file dirname [info script]]]] Test1.0]
      }

      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".
        #
        set ::test_path [file join [file normalize [file dirname \
            [file dirname [file dirname [info script]]]]] Tests]
      }
    }

    #
    # NOTE: Load and configure the tcltest package unless we are prevented.
    #
    if {![info exists ::no(configureTcltest)]} then {
      configureTcltest [list test testConstraint] false
    }

    #
    # NOTE: We need several of our test related commands in the global
    #       namespace as well.
    #
    exportAndImportPackageCommands [namespace current] [list addConstraint \
        calculateRelativePerformance haveConstraint haveOrAddConstraint \
        processTestArguments getTemporaryPath getTestLog getTestLogId getFiles \
        getConstraints getTestFiles getTestRunId execTestShell runTestPrologue \
        runTestEpilogue runTest runAllTests fixConstraints sourceIfValid \
        isExitOnComplete getPassPercentage getSkipPercentage testExec tlog \
        returnInfoScript tputs formatDecimal formatList configureTcltest \
        tsource testShim] false false

    ###########################################################################
    ############################## END Tcl ONLY ###############################
    ###########################################################################
  }

  #
  # NOTE: Provide the Eagle test package to the interpreter.
  #
  package provide EagleTest \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Externals/Eagle/lib/Eagle1.0/vendor.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
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
###############################################################################
#
# vendor.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Vendor Initialization File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

#
# STUB: This script file is a placeholder.  This file, when present, is always
#       evaluated when an interpreter is initialized.  Vendors distributing
#       Eagle can place custom application-specific, interpreter-specific
#       initialization and/or customizations in here.  Additionally, this file
#       may contain per-interpreter customizations required when porting to
#       new platforms, operating systems, etc.
#

###############################################################################
############################## BEGIN VENDOR CODE ##############################
###############################################################################
#
# NOTE: Use our own namespace here because even though we do not directly
#       support namespaces ourselves, we do not want to pollute the global
#       namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
  if {[isEagle]} then {
    proc checkForTestOverrides { channel varNames quiet } {
      set result 0

      foreach varName $varNames {
        if {[uplevel 1 [list info exists $varName]]} then {
          incr result

          if {!$quiet} then {
            puts -nonewline $channel [appendArgs \
                "Found vendor-specific test override \"" $varName "\".\n"]
          }
        }
      }

      return $result
    }

    proc addTestSuiteToAutoPath { channel varName quiet } {
      #
      # NOTE: Start with the directory containing this file.
      #
      set dir [file normalize [file dirname [info script]]]

      #
      # NOTE: Keep going until the directory name is empty OR is actually the
      #       root of the associated volume.
      #
      while {[string length $dir] > 0 && \
          [lsearch -exact -nocase -- [file volumes] $dir] == -1} {
        #
        # NOTE: Does this directory have the necessary sub-directory that
        #       contains a package index file?
        #
        if {[file exists [file join $dir Tests]] && \
            [file isdirectory [file join $dir Tests]] && \
            [file exists [file join $dir Tests pkgIndex.eagle]] && \
            [file isfile [file join $dir Tests pkgIndex.eagle]]} then {
          #
          # NOTE: If requested, give the caller access to the name of the
          #       directory we just found.
          #
          if {[string length $varName] > 0} then {
            upvar 1 $varName dir2
          }

          #
          # NOTE: Ok, show the directory we found.
          #
          set dir2 [file join $dir Tests]

          #
          # NOTE: We found the necessary directory to add to the auto-path;
          #       However, we cannot simply add it to the auto-path directly
          #       because the auto-path is dynamically constructed after this
          #       script is evaluated; therefore, set the Eagle library path
          #       environment variable and force the appropriate internal path
          #       list to be refreshed.
          #
          if {![info exists ::env(EAGLELIBPATH)] || \
              [lsearch -exact $::env(EAGLELIBPATH) $dir2] == -1} then {
            #
            # NOTE: If we have NOT been instructed to be quiet, report now.
            #
            if {!$quiet} then {
              puts -nonewline $channel [appendArgs \
                  "Found vendor-specific test package directory \"" $dir2 \
                  "\", adding...\n"]
            }

            #
            # NOTE: Append the directory to the necessary environment variable
            #       so that it will get picked up when Eagle actually rebuilds
            #       the auto-path list (below).
            #
            lappend ::env(EAGLELIBPATH) $dir2

            #
            # NOTE: Force Eagle to rebuild the auto-path list for the current
            #       interpreter right now.
            #
            object invoke Utility RefreshAutoPathList
          }

          #
          # NOTE: We are done, return success.
          #
          return true
        }

        #
        # NOTE: Keep going up the directory tree...
        #
        set dir [file dirname $dir]
      }

      #
      # NOTE: If we have NOT been instructed to be quiet, report now.
      #
      if {!$quiet} then {
        puts -nonewline $channel \
            "Could not find vendor-specific test package directory.\n"
      }

      #
      # NOTE: Directory not found, return failure.
      #
      return false
    }

    proc setupInterpreterTestPath { channel dir quiet } {
      set testPath [object invoke -flags +NonPublic Interpreter.GetActive \
          TestPath]

      if {$dir ne $testPath} then {
        object invoke -flags +NonPublic Interpreter.GetActive TestPath $dir

        if {!$quiet} then {
          puts -nonewline $channel [appendArgs \
              "Set interpreter test path to \"" $dir \".\n]
        }
      }
    }

    checkForTestOverrides stdout \
        [list binary_directory build_base_directory build_directory \
              common_directory database_directory datetime_format \
              test_configuration test_year] false

    #
    # NOTE: This variable will contain the name of the directory containing the
    #       vendor-specific testing infrastructure.
    #
    set ::vendor_directory ""

    #
    # NOTE: This procedure will attempt to find the vendor-specific testing
    #       infrastructure directory and add it to the auto-path for the
    #       current interpreter.
    #
    addTestSuiteToAutoPath stdout ::vendor_directory false

    #
    # NOTE: If we actually found a vendor-specific testing infrastructure
    #       directory then modify the TestPath property of the current
    #       interpreter to point directly to it.
    #
    if {[string length $::vendor_directory] > 0} then {
      setupInterpreterTestPath stdout $::vendor_directory false
    }
  }
}

###############################################################################
############################### END VENDOR CODE ###############################
###############################################################################
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































Deleted Externals/Eagle/lib/Test1.0/constraints.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
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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
###############################################################################
#
# constraints.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Test Constraints File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

#
# NOTE: Use our own namespace here because even though we do not directly
#       support namespaces ourselves, we do not want to pollute the global
#       namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
  proc checkForPlatform { channel } {
    tputs $channel "---- checking for platform... "

    addConstraint $::tcl_platform(platform)

    if {![isEagle]} then {
      #
      # BUGFIX: We do not want to skip any Mono bugs in Tcl.
      #         Also, fake the culture.
      #
      set constraints [list monoToDo monoBug monoCrash culture.en_US]

      #
      # NOTE: Add the necessary constraints for each version
      #       of Mono we know about.
      #
      foreach version [list 20 22 24 26 28 210 30] {
        addConstraint [appendArgs monoToDo $version]
        addConstraint [appendArgs monoBug $version]
        addConstraint [appendArgs monoCrash $version]
      }

      foreach constraint $constraints {
        addConstraint $constraint; # running in Tcl.
      }
    }

    tputs $channel [appendArgs $::tcl_platform(platform) \n]
  }

  proc checkForEagle { channel } {
    tputs $channel "---- checking for Eagle... "

    if {[isEagle]} then {
      #
      # NOTE: We are running inside Eagle.
      #
      addConstraint eagle

      #
      # NOTE: We do not want to skip bugs or crashing
      #       issues for Tcl since we are not running
      #       in Tcl.
      #
      addConstraint tclBug
      addConstraint tclCrash

      #
      # NOTE: Add the necessary constraints for each
      #       version of Tcl we know about.
      #
      foreach version [list 84 85 86] {
        addConstraint [appendArgs tclBug $version]
        addConstraint [appendArgs tclCrash $version]
      }

      tputs $channel yes\n
    } else {
      #
      # NOTE: We are running inside Tcl.
      #
      addConstraint tcl

      #
      # NOTE: Each Tcl bug and crash constraint is set
      #       based on the exact Tcl version (i.e. not
      #       greater than or equal to).
      #
      if {[info exists ::tcl_version]} then {
        #
        # NOTE: For each Tcl version we know about,
        #       check it against the currently running
        #       Tcl version.  If the two are not equal,
        #       add the test constraints that prevent
        #       skipping those tests that are buggy
        #       only for the particular version of Tcl.
        #
        foreach dotVersion [list 8.4 8.5 8.6] {
          if {$::tcl_version ne $dotVersion} then {
            set version [string map [list . ""] $dotVersion]

            addConstraint [appendArgs tclBug $version]
            addConstraint [appendArgs tclCrash $version]
          }
        }
      }

      #
      # NOTE: We do not want to skip bugs or crashing
      #       issues for Eagle since we are not running
      #       in Eagle.
      #
      addConstraint eagleBug
      addConstraint eagleCrash

      #
      # HACK: Needed by tests "socket-*.*".
      #
      if {![info exists ::no(compileNetwork)]} then {
        addConstraint compile.NETWORK
      }

      tputs $channel no\n
    }
  }

  proc checkForSymbols { channel name {constraint ""} } {
    set fileName [file normalize [appendArgs [file rootname $name] .pdb]]

    tputs $channel [appendArgs "---- checking for symbols \"" $fileName \
        "\"... "]

    if {[file exists $fileName]} then {
      #
      # NOTE: The file appears to have associated symbols available.
      #
      if {[string length $constraint] > 0} then {
        addConstraint [appendArgs symbols_ $constraint]
      } else {
        addConstraint [appendArgs symbols_ [file tail $name]]
      }

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForLogFile { channel } {
    tputs $channel "---- checking for log file... "

    if {[info exists ::test_log] && \
        [string length $::test_log] > 0 && \
        [file exists $::test_log]} then {
      #
      # NOTE: The log file appears to be available.
      #
      addConstraint logFile

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

    if {[haveGaruda packageId]} then {
      #
      # NOTE: We are running with or via Garuda.
      #
      addConstraint garuda

      tputs $channel [appendArgs "yes (" $packageId ")\n"]
    } else {
      tputs $channel no\n
    }
  }

  proc checkForShell { channel } {
    tputs $channel "---- checking for shell... "

    set name [file rootname [file tail [info nameofexecutable]]]

    if {[isEagle]} then {
      if {$name eq "EagleShell"} then {
        #
        # NOTE: We are running in Eagle via the EagleShell.
        #
        addConstraint shell

        tputs $channel "yes (Eagle)\n"

        #
        # NOTE: We are done here, return now.
        #
        return
      }
    } else {
      if {[string match tclsh* $name]} then {
        #
        # NOTE: We are running in Tcl via tclsh.
        #
        addConstraint shell

        tputs $channel "yes (Tcl)\n"

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

    tputs $channel no\n
  }

  proc checkForDebug { channel } {
    tputs $channel "---- checking for debug... "

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

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

    #
    # HACK: For now, disable testing Tk 8.4/8.5 when running in Eagle.
    #
    if {![isEagle] || [haveConstraint tclLibrary86]} then {
      addConstraint tk

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForVersion { channel } {
    tputs $channel "---- checking for language version... "

    if {[info exists ::tcl_version]} then {
      #
      # TODO: Cleanup the semantics for adding test
      #       constraints here.
      #
      if {$::tcl_version eq "8.4"} then {
        #
        # NOTE: Baseline reported language and feature
        #       version.
        #
        addConstraint tcl84
        addConstraint tcl84OrHigher
        addConstraint tcl84Feature

        if {[isEagle]} then {
          #
          # NOTE: *EAGLE* We do want to include any
          #       tests that target "Tcl 8.5 or higher"
          #       features and/or "Tcl 8.6 or higher"
          #       features because they would not be in
          #       the test suite if we did not support
          #       that particular feature, regardless
          #       of the language version.
          #
          addConstraint tcl85Feature
          addConstraint tcl86Feature
        }
      } elseif {$::tcl_version eq "8.5"} then {
        #
        # NOTE: Baseline reported language and feature
        #       version.  Tcl 8.5 includes all the
        #       features from itself and Tcl 8.4.
        #
        addConstraint tcl85
        addConstraint tcl84OrHigher
        addConstraint tcl85OrHigher
        addConstraint tcl84Feature
        addConstraint tcl85Feature

        if {[isEagle]} then {
          #
          # NOTE: *EAGLE* We do want to include any
          #       tests that target "Tcl 8.5 or higher"
          #       features and/or "Tcl 8.6 or higher"
          #       features because they would not be in
          #       the test suite if we did not support
          #       that particular feature, regardless
          #       of the language version.
          #
          addConstraint tcl86Feature
        }
      } elseif {$::tcl_version eq "8.6"} then {
        #
        # NOTE: Baseline reported language and feature
        #       version.  Tcl 8.6 includes all the
        #       features from itself Tcl 8.4, and Tcl
        #       8.5.
        #
        addConstraint tcl86
        addConstraint tcl84OrHigher
        addConstraint tcl85OrHigher
        addConstraint tcl86OrHigher
        addConstraint tcl84Feature
        addConstraint tcl85Feature
        addConstraint tcl86Feature
      }

      tputs $channel [appendArgs $::tcl_version \n]
    } else {
      tputs $channel no\n
    }
  }

  proc checkForCommand { channel name } {
    tputs $channel [appendArgs "---- checking for command \"" $name \
        "\"... "]

    #
    # NOTE: Is the command available?
    #
    if {[llength [info commands $name]] > 0} then {
      #
      # NOTE: Yes, it appears that it is available.
      #
      addConstraint [appendArgs command. $name]

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForFile { channel name {constraint ""} } {
    tputs $channel [appendArgs "---- checking for file \"" $name \
        "\"... "]

    if {[file exists $name]} then {
      #
      # NOTE: Yes, it appears that it is available.
      #
      if {[string length $constraint] > 0} then {
        addConstraint [appendArgs file_ $constraint]
      } else {
        addConstraint [appendArgs file_ [file tail $name]]
      }

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForPathFile { channel name {constraint ""} } {
    tputs $channel [appendArgs "---- checking for file \"" $name \
        "\" along PATH... "]

    if {[file exists $name]} then {
      #
      # NOTE: Yes, it appears that it is available [in the exact location they
      #       specified].
      #
      if {[string length $constraint] > 0} then {
        addConstraint [appendArgs file_ $constraint]
      } else {
        addConstraint [appendArgs file_ [file tail $name]]
      }

      tputs $channel yes\n

      #
      # NOTE: We are done here, return now.
      #
      return
    } else {
      #
      # NOTE: Use the appropriate environment variable for the platform.
      #
      if {$::tcl_platform(platform) eq "windows"} then {
        set pathName PATH
      } else {
        #
        # HACK: For shared libraries, use the LD_LIBRARY_PATH.
        #
        if {[file extension $name] eq [info sharedlibextension]} then {
          set pathName LD_LIBRARY_PATH
        } else {
          set pathName PATH
        }
      }

      #
      # NOTE: Is the required environment variable available?
      #
      if {[info exists ::env($pathName)]} then {
        #
        # NOTE: Ok, grab it now.
        #
        set path $::env($pathName)

        #
        # NOTE: Use the appropriate path separator for the platform.
        #
        if {[info exists ::tcl_platform(pathSeparator)]} then {
          set separator $::tcl_platform(pathSeparator)
        } elseif {$::tcl_platform(platform) eq "windows"} then {
          set separator \;
        } else {
          set separator :
        }

        #
        # NOTE: Grab just the file name from the possibly fully qualified file
        #       name provided by the caller.
        #
        set tail [file tail $name]

        #
        # NOTE: Check each directory in the PATH for the file.
        #
        foreach directory [split $path $separator] {
          #
          # NOTE: Check for the file in this directory contained in the PATH.
          #       This strips the directory portion off the file name specified
          #       by the caller, if any, before joining that file name to the
          #       current directory of the PATH being searched.
          #
          if {[file exists [file join $directory $tail]]} then {
            #
            # NOTE: Yes, it appears that it is available in the PATH.
            #
            if {[string length $constraint] > 0} then {
              addConstraint [appendArgs file_ $constraint]
            } else {
              addConstraint [appendArgs file_ [file tail $name]]
            }

            tputs $channel yes\n

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

    tputs $channel no\n
  }

  proc checkForNativeCode { channel } {
    tputs $channel "---- checking for native code... "

    if {[isEagle]} then {
      if {[info exists ::eagle_platform(compileOptions)] && \
          [info exists ::tcl_platform(platform)] && \
          [lsearch -exact -nocase $::eagle_platform(compileOptions) \
          $::tcl_platform(platform)] != -1} then {
        #
        # NOTE: Yes, the binary matches the current platform,
        #       native code can be used.
        #
        addConstraint native

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    } else {
      #
      # NOTE: Tcl is always native code and can always execute native code.
      #
      addConstraint native

      #
      # HACK: Needed by test "benchmark-1.22".
      #
      if {![info exists ::no(compileNative)]} then {
        addConstraint compile.NATIVE
      }

      tputs $channel yes\n
    }
  }

  proc checkForTip127 { channel } {
    tputs $channel "---- checking for TIP #127... "

    #
    # NOTE: Is the interpreter TIP #127 ready?
    #
    if {[catch {lsearch -index 0 0 0}] == 0} then {
      addConstraint tip127

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTip194 { channel } {
    tputs $channel "---- checking for TIP #194... "

    #
    # NOTE: Is the interpreter TIP #194 ready?
    #
    catch {apply} error

    if {$error ne {invalid command name "apply"}} then {
      addConstraint tip194

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTip241 { channel } {
    tputs $channel "---- checking for TIP #241... "

    #
    # NOTE: Is the interpreter TIP #241 ready?
    #
    if {[catch {lsearch -nocase 0 0}] == 0} then {
      addConstraint tip241

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTip285 { channel } {
    tputs $channel "---- checking for TIP #285... "

    #
    # NOTE: Is the interpreter TIP #285 ready?
    #
    catch {interp cancel} error

    if {$error eq "eval canceled"} then {
      addConstraint tip285

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTiming { channel threshold {constraint ""} {tries 1} } {
    tputs $channel [appendArgs \
        "---- checking for precision timing (" $threshold " 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 difference unknown

    for {} {$try < $tries} {incr try} {
      #
      # NOTE: Attempt to block for exactly one second.
      #
      set start [expr {[clock clicks -milliseconds] & 0x7fffffff}]
      after 1000; # wait for "exactly" one second.
      set stop [expr {[clock clicks -milliseconds] & 0x7fffffff}]

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

      #
      # 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 {
          addConstraint $constraint
        } else {
          addConstraint timing
        }

        tputs $channel [appendArgs "yes (0 <= " $difference " <= " \
            $threshold " milliseconds, tried " [expr {$try + 1}] \
            " " [expr {$try + 1 > 1 ? "times" : "time"}] ")\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"]
  }

  proc checkForPerformance { channel } {
    tputs $channel "---- checking for performance testing... "

    #
    # NOTE: Are we allowed to do performance testing?
    #
    if {![info exists ::no(performance)]} then {
      addConstraint performance

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForInteractive { channel } {
    tputs $channel "---- checking for interactive user... "

    #
    # NOTE: Is there an interactive user?
    #
    if {[info exists ::tcl_interactive] && $::tcl_interactive} then {
      addConstraint interactive

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForUserInteraction { channel } {
    tputs $channel "---- checking for user interaction... "

    #
    # HACK: For now, do the exact same check as checkForInteractive; however,
    #       this is still useful as a separate constraint because it can be
    #       individually disabled in "prologue.eagle".
    #
    if {[info exists ::tcl_interactive] && $::tcl_interactive} then {
      addConstraint userInteraction

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

    if {[isEagle]} 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}

      #
      # 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
      }
    } else {
      #
      # HACK: Running in Tcl, just assume we have network access.
      #
      addConstraint [appendArgs network_ $host]

      tputs $channel yes\n
    }
  }

  proc checkForCompileOption { channel option } {
    tputs $channel [appendArgs "---- checking for compile option \"" \
        $option "\"... "]

    if {[isEagle]} then {
      if {[info exists ::eagle_platform(compileOptions)] && \
          [lsearch -exact -nocase $::eagle_platform(compileOptions) \
              $option] != -1} then {
        #
        # NOTE: Yes, support for the Eagle compile option is present.
        #
        addConstraint [appendArgs compile. $option]

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    } else {
      #
      # NOTE: We are running inside Tcl; however, we need to check for an
      #       Eagle compile option.  This can now be accomplished via the
      #       [eagle] command supplied by the Eagle Package for Tcl, if
      #       it is actually loaded and available.
      #
      if {[llength [info commands eagle]] > 0} then {
        set options [eagle [list expr {[info exists \
            ::eagle_platform(compileOptions)] ? \
            $::eagle_platform(compileOptions) : [list]}]]

        if {[lsearch -exact $options $option] != -1} then {
          #
          # NOTE: Yes, support for the Eagle compile option is present.
          #
          addConstraint [appendArgs compile. $option]

          tputs $channel yes\n

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

      tputs $channel no\n
    }
  }

  if {[isEagle]} then {
    ###########################################################################
    ############################ BEGIN Eagle ONLY #############################
    ###########################################################################

    proc checkForSoftwareUpdateTrust { channel } {
      tputs $channel "---- checking for software update trust... "

      if {[llength [info commands uri]] > 0 && \
          [catch {uri softwareupdates} result] == 0 && \
          $result eq "software update certificate is trusted"} then {
        #
        # NOTE: Yes, it appears that we trust our software updates.
        #       Since this setting is off by default, the user (or
        #       a script evaluated by the user) must have manually
        #       turned it on.
        #
        addConstraint softwareUpdate

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

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

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

      if {[set code [catch {host isopen} result]] == 0 && $result} then {
        addConstraint hostIsOpen

        tputs $channel open\n
      } elseif {$code == 0} then {
        tputs $channel closed\n
      } else {
        tlog $result; tputs $channel error\n]
      }
    }

    proc checkForPrimaryThread { channel } {
      tputs $channel "---- checking for primary thread... "

      set threadId [object invoke Interpreter.GetActive ThreadId]

      if {[info tid] == $threadId} then {
        addConstraint primaryThread

        tputs $channel [appendArgs "yes (" $threadId ")\n"]
      } else {
        tputs $channel [appendArgs "no (" $threadId ")\n"]
      }
    }

    proc checkForDefaultAppDomain { channel } {
      tputs $channel "---- checking for default application domain... "

      set appDomain [object invoke AppDomain CurrentDomain]

      if {[string length $appDomain] > 0} then {
        if {[object invoke $appDomain IsDefaultAppDomain]} then {
          addConstraint defaultAppDomain

          tputs $channel [appendArgs "yes (" [object invoke $appDomain Id] \
              ")\n"]
        } else {
          tputs $channel [appendArgs "no (" [object invoke $appDomain Id] \
              ")\n"]
        }
      } else {
        tputs $channel [appendArgs "no (null)\n"]
      }
    }

    proc checkForRuntime { channel } {
      tputs $channel "---- checking for runtime... "

      #
      # NOTE: Are we running inside Mono (regardless of operating system)?
      #
      if {[isMono]} then {
        #
        # NOTE: Yes, it appears that we are running inside Mono.
        #
        addConstraint mono; # running on Mono.

        tputs $channel [appendArgs [expr {[info exists \
            ::eagle_platform(runtime)] ? \
            $::eagle_platform(runtime) : "Mono"}] \n]
      } else {
        #
        # NOTE: No, it appears that we are not running inside Mono.
        #
        addConstraint dotNet; # running on .NET.

        #
        # NOTE: We do not want to skip Mono bugs on .NET.
        #
        addConstraint monoToDo; # running on .NET.
        addConstraint monoBug; # running on .NET.
        addConstraint monoCrash; # running on .NET.

        tputs $channel [appendArgs [expr {[info exists \
            ::eagle_platform(runtime)] ? \
            $::eagle_platform(runtime) : "Microsoft.NET"}] \n]
      }
    }

    proc checkForImageRuntimeVersion { channel } {
      tputs $channel "---- checking for image runtime version... "

      if {[info exists ::eagle_platform(imageRuntimeVersion)] && \
          [string length $::eagle_platform(imageRuntimeVersion)] > 0} then {
        #
        # NOTE: Get the major and minor portions of the version only.
        #
        set dotVersion [join [lrange [split \
            $::eagle_platform(imageRuntimeVersion) .] 0 1] .]

        #
        # NOTE: Now create a version string for use in the constraint name
        #       (remove the periods).
        #
        set version [string map [list v "" . ""] $dotVersion]

        #
        # NOTE: Keep track of the specific image runtime version for usage in
        #       test constraints.
        #
        addConstraint [appendArgs imageRuntime $version]

        tputs $channel [appendArgs $::eagle_platform(imageRuntimeVersion) \
            " " ( $dotVersion ) \n]
      } else {
        tputs $channel no\n
      }
    }

    proc checkForRuntimeVersion { channel } {
      tputs $channel "---- checking for runtime version... "

      if {[info exists ::eagle_platform(runtimeVersion)] && \
          [string length $::eagle_platform(runtimeVersion)] > 0} then {
        #
        # NOTE: Get the major and minor portions of the version only.
        #
        set dotVersion [join [lrange [split \
            $::eagle_platform(runtimeVersion) .] 0 1] .]

        #
        # NOTE: Now create a version string for use in the constraint name
        #       (remove the periods).
        #
        set version [string map [list . ""] $dotVersion]

        if {[isMono]} then {
          if {[string length $version] > 0} then {
              #
              # NOTE: We are running on Mono.  Keep track of the specific
              #       version for usage in test constraints.
              #
              addConstraint [appendArgs mono $version]
          }

          if {[string length $dotVersion] > 0 && \
              [regexp -- {^(\d+)\.(\d+)$} $dotVersion dummy \
                  majorVersion minorVersion]} then {
            set monoVersions [list]

            #
            # NOTE: Check for any Mono version 2.x or higher.
            #
            if {$majorVersion >= 2} then {
              #
              # NOTE: Check for any Mono version higher than 2.0.
              #
              if {$majorVersion > 2 || $minorVersion > 0} then {
                lappend monoVersions 20
              }

              #
              # NOTE: Check for any Mono version higher than 2.2.
              #
              if {$majorVersion > 2 || $minorVersion > 2} then {
                lappend monoVersions 22
              }

              #
              # NOTE: Check for any Mono version higher than 2.4.
              #
              if {$majorVersion > 2 || $minorVersion > 4} then {
                lappend monoVersions 24
              }

              #
              # NOTE: Check for any Mono version higher than 2.6.
              #
              if {$majorVersion > 2 || $minorVersion > 6} then {
                lappend monoVersions 26
              }

              #
              # NOTE: Check for any Mono version higher than 2.8.
              #
              if {$majorVersion > 2 || $minorVersion > 8} then {
                lappend monoVersions 28
              }

              #
              # NOTE: Check for any Mono version higher than 2.10.
              #
              if {$majorVersion > 2 || $minorVersion > 10} then {
                lappend monoVersions 210
              }
            }

            #
            # NOTE: Check for any Mono version 3.x or higher.
            #
            if {$majorVersion >= 3} then {
              #
              # NOTE: Check for any Mono version higher than 3.0.
              #
              if {$majorVersion > 3 || $minorVersion > 0} then {
                lappend monoVersions 30
              }
            }

            #
            # NOTE: Add the necessary constraints for each version of Mono we
            #       should NOT skip bugs for.
            #
            foreach monoVersion $monoVersions {
              addConstraint [appendArgs monoToDo $monoVersion]
              addConstraint [appendArgs monoBug $monoVersion]
              addConstraint [appendArgs monoCrash $monoVersion]
            }
          }
        } else {
          if {[string length $version] > 0} then {
            #
            # NOTE: We are running on the .NET Framework.  Keep track of the
            #       specific version for usage in test constraints.
            #
            addConstraint [appendArgs dotNet $version]
          }

          #
          # NOTE: We do not want to skip any Mono bugs on .NET.  Add the
          #       necessary constraints for each version of Mono we know
          #       about.
          #
          foreach monoVersion [list 20 22 24 26 28 210 30] {
            addConstraint [appendArgs monoToDo $monoVersion]
            addConstraint [appendArgs monoBug $monoVersion]
            addConstraint [appendArgs monoCrash $monoVersion]
          }
        }

        tputs $channel [appendArgs $::eagle_platform(runtimeVersion) \
            " " ( $dotVersion ) \n]
      } else {
        tputs $channel no\n
      }
    }

    proc checkForMachine { channel bits machine } {
      tputs $channel [appendArgs "---- checking for machine \"" $bits \
          "-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 {
        #
        # 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 {
          #
          # 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]
      } else {
        tputs $channel "no, unknown\n"
      }
    }

    proc checkForGarudaDll { channel } {
      #
      # NOTE: Check for the Garuda DLL of the same platform (i.e. machine
      #       type) as the native Tcl shell.
      #
      return [checkForFile $channel [getGarudaDll]]
    }

    proc checkForCulture { channel } {
      tputs $channel "---- checking for culture... "

      #
      # NOTE: Grab the current culture.
      #
      set culture [info culture]

      if {[string length $culture] > 0} then {
        #
        # NOTE: The culture information is present, use it and show it.
        #
        addConstraint [appendArgs culture. [string map [list - _] $culture]]

        tputs $channel [appendArgs $culture \n]
      } else {
        tputs $channel [appendArgs unknown \n]
      }
    }

    proc checkForThreadCulture { channel } {
      tputs $channel "---- checking for thread culture... "

      #
      # NOTE: Grab the current thread culture.
      #
      set culture [object invoke System.Threading.Thread.CurrentThread \
          CurrentCulture]

      set culture [object invoke Eagle._Components.Private.FormatOps \
          CultureName $culture false]

      if {[string length $culture] > 0} then {
        #
        # NOTE: The culture information is present, use it and show it.
        #
        addConstraint [appendArgs threadCulture. [string map [list - _] \
            $culture]]

        tputs $channel [appendArgs $culture \n]
      } else {
        tputs $channel [appendArgs unknown \n]
      }
    }

    proc checkForQuiet { channel } {
      tputs $channel "---- checking for quiet... "

      if {[object invoke Interpreter.GetActive Quiet]} then {
        #
        # NOTE: Yes, quiet mode is enabled.
        #
        addConstraint quiet

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForReferenceCountTracking { channel } {
      tputs $channel "---- checking for object reference count tracking... "

      if {[info exists ::eagle_platform(compileOptions)] && \
          ([lsearch -exact -nocase $::eagle_platform(compileOptions) \
              NOTIFY] != -1 || \
           [lsearch -exact -nocase $::eagle_platform(compileOptions) \
              NOTIFY_OBJECT] != -1)} then {
        #
        # NOTE: Yes, support for object reference count tracking is present.
        #
        addConstraint refCount

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForRuntimeOption { channel option } {
      tputs $channel [appendArgs "---- checking for runtime option \"" \
          $option "\"... "]

      if {[info exists ::eagle_platform(runtimeOptions)] && \
          [lsearch -exact -nocase $::eagle_platform(runtimeOptions) \
              $option] != -1} then {
        #
        # NOTE: Yes, support for the runtime option is present.
        #
        addConstraint [appendArgs runtime. $option]

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForDynamicLoading { channel } {
      tputs $channel "---- checking for dynamic loading... "

      #
      # NOTE: As far as we know, dynamic loading always works on Windows.
      #       On some Unix systems, dlopen does not work (e.g. because
      #       Mono is statically linked, etc).
      #
      if {$::tcl_platform(platform) eq "windows" || \
          ([llength [info commands library]] > 0 && \
           [catch {library test}] == 0)} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint dynamic

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForWindowsForms { channel } {
      tputs $channel "---- checking for Windows Forms... "

      #
      # HACK: When running on Windows, we do not need to do any other
      #       special checks here; however, on Unix (and Mac OS X?),
      #       we should check for the DISPLAY environment variable as
      #       some basic indication that the X server is available.
      #       This appears to be very necessary on Mono because it
      #       crashes after repeated failed attempts to create a
      #       Windows Form when the X server is unavailable (e.g. on
      #       OpenBSD).
      #
      if {$::tcl_platform(platform) eq "windows" || \
          [info exists ::env(DISPLAY)]} then {
        #
        # NOTE: Is the Windows Forms assembly available?
        #
        if {[catch {object resolve System.Windows.Forms} assembly] == 0} then {
          #
          # NOTE: Yes, it appears that it is available.
          #
          addConstraint winForms

          tputs $channel yes\n

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

      tputs $channel no\n
    }

    proc checkForStaThread { channel } {
      tputs $channel "---- checking for STA thread... "

      if {[catch {object invoke System.Threading.Thread.CurrentThread \
              GetApartmentState} apartmentState] == 0 && \
          $apartmentState eq "STA"} then {
        #
        # NOTE: Yes, we are running in an STA thread.
        #
        addConstraint staThread

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForWindowsPresentationFoundation { channel } {
      tputs $channel "---- checking for Windows Presentation Foundation... "

      #
      # NOTE: Is the Windows Presentation Foundation available?
      #
      if {[catch {object resolve PresentationFramework} assembly] == 0} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint wpf

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForDatabase { channel string } {
      tputs $channel "---- checking for database... "

      #
      # HACK: Disable database connectivity testing on Mono because
      #       it fails to timeout (unless special test suite hacks
      #       for Mono have been disabled by the user).
      #
      if {[info exists ::no(mono)] || ![isMono]} then {
        #
        # NOTE: Can we access the local database?
        #
        if {[catch {sql open $string} connection] == 0} then {
          #
          # NOTE: Yes, it appears that we can connect to the local database.
          #
          addConstraint sql

          #
          # NOTE: Cleanup the database connection we just opened.
          #
          sql close $connection

          tputs $channel yes\n
        } else {
          tputs $channel no\n
        }
      } else {
        tputs $channel disabled\n
      }
    }

    proc checkForAssembly { channel name } {
      tputs $channel [appendArgs "---- checking for assembly \"" $name \
          "\"... "]

      #
      # NOTE: Can the assembly be loaded?
      #
      if {[catch {object resolve $name} assembly] == 0} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint $name

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForObjectMember { channel object member {constraint ""} } {
      tputs $channel [appendArgs "---- checking for object member \"" \
          $object . $member "\"... "]

      if {[catch {object members -flags +NonPublic -pattern $member $object} \
          members] == 0 && [llength $members] > 0} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        if {[string length $constraint] > 0} then {
          addConstraint [appendArgs member_ $constraint]
        } else {
          addConstraint [appendArgs $object. [string trim $member *?]]
        }

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForTclInstalls { channel } {
      tputs $channel "---- checking for Tcl installs... "

      #
      # NOTE: Check for dynamically loadable Tcl libraries (for this
      #       architecture only).
      #
      if {[catch {tcl select -architecture} tcl] == 0} then {
        #
        # NOTE: Did we find one?  Attempt to grab the index
        #       of the version field from the list.
        #
        set index [lsearch -exact $tcl version]

        if {$index != -1} then {
          #
          # NOTE: The very next list index contains the value
          #       (i.e. like a Tcl 8.5+ dict).
          #
          set dotVersion [lindex $tcl [incr index]]

          #
          # NOTE: Do we know the version?
          #
          if {[string length $dotVersion] > 0 && \
              [regexp -- {^\d+\.\d+$} $dotVersion]} then {
            #
            # NOTE: Yes, some version of Tcl is available.
            #
            addConstraint tclLibrary

            #
            # NOTE: Is the version 8.x or higher?
            #
            if {$dotVersion >= 8.6} then {
              addConstraint tclLibrary86
            } elseif {$dotVersion >= 8.5} then {
              addConstraint tclLibrary85
            } elseif {$dotVersion >= 8.4} then {
              addConstraint tclLibrary84
            }

            tputs $channel [appendArgs $dotVersion \n]

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

      tputs $channel no\n
    }

    proc checkForTclReady { channel } {
      tputs $channel "---- checking for Tcl readiness... "

      if {[catch {tcl ready} result] == 0 && $result} then {
        #
        # NOTE: Yes, native Tcl is loaded and ready.
        #
        addConstraint tclReady

        tputs $channel yes\n
      } 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).
      #
      if {[catch {getMachineForTclShell} result] == 0 && \
          $result ne "error"} then {
        #
        # NOTE: Yes, a native Tcl shell appears to be available.
        #
        addConstraint tclShell

        tputs $channel [appendArgs "---- checking for Tcl shell... yes (" \
            $result ")\n"]
      } else {
        tputs $channel "---- checking for Tcl shell... 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).
      #
      if {[catch {getTkVersion} 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 (" \
            $result ")\n"]
      } else {
        tputs $channel "---- checking for Tk package... no\n"
      }
    }

    proc checkForPowerShell { channel } {
      tputs $channel "---- checking for PowerShell... "

      #
      # NOTE: Can the PowerShell assembly be loaded?
      #
      if {[catch {object resolve System.Management.Automation} \
              assembly] == 0} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint powerShell

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

      #
      # NOTE: Platform must be Windows for this constraint to
      #       even be checked (i.e. we require the registry).
      #
      if {$::tcl_platform(platform) eq "windows"} then {
        #
        # NOTE: Indicate that we have not found it yet.
        #
        set directory ""

        #
        # NOTE: Have we not found the directory yet?
        #
        #       Yes, this is somewhat redundant because we just set
        #       the directory to an empty string (above); however,
        #       maintaining a uniform pattern is more important.
        #
        if {[string length $directory] == 0} then {
          #
          # NOTE: Check for the WIX environment variable.
          #
          if {[info exists ::env(WIX)]} then {
            set directory [file normalize [string trimright $::env(WIX)]]

            if {[string length $directory] > 0} then {
              #
              # NOTE: We need the directory containing the binaries.
              #
              set directory [file join $directory bin]

              #
              # NOTE: Does the directory actually exist?
              #
              if {[file isdirectory $directory]} then {
                #
                # NOTE: The file name of the primary WiX assembly.
                #
                set fileName [file join $directory wix.dll]

                #
                # NOTE: We do not know the file version yet.
                #
                set version ""

                #
                # NOTE: Attempt to query the version of the file.
                #
                if {[catch {file version $fileName} version] == 0 && \
                    [string length $version] > 0} then {
                  #
                  # NOTE: Indicate where we found the file.
                  #
                  set where environment
                } else {
                  #
                  # NOTE: The file does not exist or is not properly
                  #       versioned.
                  #
                  set directory ""
                }
              } else {
                #
                # NOTE: The directory does not exist.
                #
                set directory ""
              }
            }
          }
        }

        #
        # NOTE: Have we not found the directory yet?
        #
        if {[string length $directory] == 0} then {
          #
          # NOTE: Registry hive where WiX install information
          #       is stored.
          #
          set key {HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Installer XML}

          #
          # NOTE: The versions of WiX that we support.
          #
          set versions [list 3.5 3.0]

          #
          # NOTE: Check each version, stopping when one is found.
          #
          foreach version $versions {
            #
            # NOTE: Attempt to fetch the WiX install directory
            #       value from the registry, removing the
            #       trailing backslash, if any.
            #
            set directory [file normalize [string trimright [object invoke \
                Microsoft.Win32.Registry GetValue \
                [appendArgs $key \\ $version] InstallRoot \
                null] \\]]

            #
            # NOTE: Does the directory name look valid and
            #       does it actually exist?
            #
            if {[string length $directory] > 0 && \
                [file isdirectory $directory]} then {
              #
              # NOTE: The file name of the primary WiX assembly.
              #
              set fileName [file join $directory wix.dll]

              #
              # NOTE: We do not know the file version yet.
              #
              set version ""

              #
              # NOTE: Attempt to query the version of the file.
              #
              if {[catch {file version $fileName} version] == 0 && \
                  [string length $version] > 0} then {
                #
                # NOTE: Indicate where we found the file.
                #
                set where registry

                #
                # NOTE: We found it, bail out now.
                #
                break
              } else {
                #
                # NOTE: The file does not exist or is not properly
                #       versioned.
                #
                set directory ""
              }
            }
          }
        }

        #
        # NOTE: Did we find the directory?
        #
        if {[string length $directory] > 0 && \
            [file isdirectory $directory]} then {
          #
          # NOTE: Yes, it appears that it is available.
          #
          addConstraint wix

          #
          # NOTE: Save the directory for later usage by
          #       the test itself.
          #
          set ::test_wix $directory

          #
          # NOTE: Show where we found it.
          #
          tputs $channel [appendArgs "yes (" $version ", via " $where ", \"" \
              $directory "\")\n"]

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

      tputs $channel no\n
    }

    proc checkForVisualStudio { channel } {
      tputs $channel "---- checking for Visual Studio... "

      #
      # NOTE: Platform must be Windows for this constraint to even be
      #       checked (i.e. we require the registry).
      #
      set visualStudioVersions [list]

      if {$::tcl_platform(platform) eq "windows"} then {
        #
        # NOTE: Registry hive where Visual Studio install information
        #       is stored.
        #
        set key {HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio}

        #
        # NOTE: The versions of Visual Studio that we support.
        #
        set versions [list [list 8.0 2005] [list 9.0 2008] [list 10.0 2010]]

        #
        # NOTE: Check each version and keep track of the ones we find.
        #
        foreach version $versions {
          #
          # NOTE: Attempt to fetch the Visual Studio install directory
          #       value from the registry, removing the trailing backslash,
          #       if any.
          #
          set fileName [file normalize [file join [string trimright [object \
              invoke Microsoft.Win32.Registry GetValue [appendArgs $key \\ \
              [lindex $version 0]] InstallDir null] \\] msenv.dll]]

          #
          # NOTE: Does the directory name look valid and does it actually
          #       exist?
          #
          if {[string length $fileName] > 0 && [file isfile $fileName]} then {
            #
            # NOTE: Yes, it appears that it is available.
            #
            addConstraint [appendArgs visualStudio [lindex $version 1]]

            #
            # NOTE: Keep track of all the versions that we find.
            #
            lappend visualStudioVersions [lindex $version 1]

            #
            # NOTE: Save the directory for later usage by
            #       the test itself.
            #
            set ::test_visual_studio [file dirname $fileName]
          }
        }
      }

      if {[llength $visualStudioVersions] > 0} then {
        #
        # NOTE: Show where we found the latest version.
        #
        tputs $channel [appendArgs "yes (" $visualStudioVersions ", \"" \
            $::test_visual_studio "\")\n"]
      } else {
        tputs $channel no\n
      }
    }

    proc checkForManagedDebugger { channel } {
      tputs $channel "---- checking for managed debugger... "

      #
      # NOTE: Is the managed debugger attached?
      #
      if {[object invoke System.Diagnostics.Debugger IsAttached]} then {
        #
        # NOTE: Yes, it appears that it is attached.
        #
        addConstraint managedDebugger

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForScriptDebugger { channel } {
      tputs $channel "---- checking for script debugger... "

      #
      # NOTE: Is the script debugger available?
      #
      if {[catch {object invoke -flags +NonPublic Interpreter.GetActive \
              Debugger} debugger] == 0} then {
        #
        # NOTE: We do not own this, do not dispose it.
        #
        if {[string length $debugger] > 0} then {
          object flags $debugger +NoDispose
        }

        if {[regexp -- {^Debugger#\d+$} $debugger]} then {
          #
          # NOTE: Yes, it appears that it is available.
          #
          addConstraint scriptDebugger

          tputs $channel yes\n

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

      tputs $channel no\n
    }

    proc checkForScriptDebuggerInterpreter { channel } {
      tputs $channel "---- checking for script debugger interpreter... "

      #
      # NOTE: Is the script debugger interpreter available?
      #
      if {[catch {object invoke -flags +NonPublic Interpreter.GetActive \
              Debugger} debugger] == 0} then {
        #
        # NOTE: We do not own this, do not dispose it.
        #
        if {[string length $debugger] > 0} then {
          object flags $debugger +NoDispose
        }

        if {[regexp -- {^Debugger#\d+$} $debugger] && \
            [catch {object invoke $debugger Interpreter} interp] == 0} then {
          #
          # NOTE: We do not own this, do not dispose it.
          #
          if {[string length $interp] > 0} then {
            object flags $interp +NoDispose
          }

          if {[regexp -- {^Interpreter#\d+$} $interp]} then {
            #
            # NOTE: Yes, it appears that it is available.
            #
            addConstraint scriptDebuggerInterpreter

            tputs $channel yes\n

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

      tputs $channel no\n
    }

    ###########################################################################
    ############################# END Eagle ONLY ##############################
    ###########################################################################
  } else {
    ###########################################################################
    ############################# BEGIN Tcl ONLY ##############################
    ###########################################################################

    #
    # NOTE: We need several of our test constraint related commands in the
    #       global namespace.
    #
    exportAndImportPackageCommands [namespace current] [list checkForPlatform \
        checkForEagle checkForGaruda checkForShell checkForDebug checkForTk \
        checkForVersion checkForCommand checkForFile checkForNativeCode \
        checkForTip127 checkForTip194 checkForTip241 checkForTip285 \
        checkForPerformance checkForTiming checkForInteractive checkForSymbols \
        checkForLogFile checkForNetwork checkForCompileOption \
        checkForUserInteraction] false false

    ###########################################################################
    ############################## END Tcl ONLY ###############################
    ###########################################################################
  }

  #
  # NOTE: Provide the Eagle test constraints package to the interpreter.
  #
  package provide EagleTestConstraints \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Externals/Eagle/lib/Test1.0/epilogue.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
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
###############################################################################
#
# epilogue.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Test Epilogue File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

if {![info exists no([file tail [info script]])]} then {
  if {[info level] > 0} then {
    error "cannot run, current level is not global"
  }

  if {[isEagle]} then {
    #
    # NOTE: Show the current state of the memory.
    #
    catch {debug memory} memory

    tputs $test_channel [appendArgs "---- ending memory: " \
        [formatListAsDict $memory] \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]

    unset stack
  }

  #
  # NOTE: Show when the tests actually ended (now).
  #
  tputs $test_channel [appendArgs "---- tests ended at " \
      [clock format [clock seconds]] \n]

  if {[isEagle]} then {
    #
    # 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
    #       the test statistics and/or restarting Eagle; however, duplicate
    #       test names must be avoided and this is considered a good trade-off.
    #
    foreach {name count} $eagle_tests(counts) {
      if {$count > 1} then {
        tputs $test_channel [appendArgs \
            "==== test name \"" $name "\" DUPLICATED (" $count ")\n"]
      } elseif {$count <= 0} then {
        tputs $test_channel [appendArgs \
            "==== test name \"" $name "\" BAD COUNT (" $count ")\n"]
      }
    }

    unset -nocomplain name count

    tputs $test_channel \n; # NOTE: Blank line.

    if {$eagle_tests(passed) > 0} then {
      host result Ok [appendArgs "PASSED: " $eagle_tests(passed) \n]
      tlog [appendArgs "PASSED: " $eagle_tests(passed) \n]
    }

    if {$eagle_tests(failed) > 0} then {
      host result Error [appendArgs "FAILED: " $eagle_tests(failed) \n]
      tlog [appendArgs "FAILED: " $eagle_tests(failed) \n]

      if {[llength $eagle_tests(failedNames)] > 0} then {
        host result Error [appendArgs "FAILED: " $eagle_tests(failedNames) \n]
        tlog [appendArgs "FAILED: " $eagle_tests(failedNames) \n]
      }
    }

    if {$eagle_tests(skipped) > 0} then {
      host result Break [appendArgs "SKIPPED: " $eagle_tests(skipped) \n]
      tlog [appendArgs "SKIPPED: " $eagle_tests(skipped) \n]

      if {[llength $eagle_tests(skippedNames)] > 0} then {
        host result Break [appendArgs "SKIPPED: " $eagle_tests(skippedNames) \n]
        tlog [appendArgs "SKIPPED: " $eagle_tests(skippedNames) \n]
      }
    }

    if {$eagle_tests(total) > 0} then {
      host result Return [appendArgs "TOTAL: " $eagle_tests(total) \n]
      tlog [appendArgs "TOTAL: " $eagle_tests(total) \n]

      if {$eagle_tests(skipped) > 0} then {
        set percent [getSkipPercentage]
        host result Break [appendArgs "SKIP PERCENTAGE: " \
            [formatDecimal $percent] %\n]

        tlog [appendArgs "SKIP PERCENTAGE: " [formatDecimal $percent] %\n]
      }

      set percent [getPassPercentage]
      host result Return [appendArgs "PASS PERCENTAGE: " \
          [formatDecimal $percent] %\n]

      tlog [appendArgs "PASS PERCENTAGE: " [formatDecimal $percent] %\n]
    } else {
      #
      # NOTE: No tests.
      #
      set percent 0
    }

    #
    # NOTE: Has the test pass threshold been set?  If so, is it set to
    #       the default value?
    #
    if {![info exists test_threshold] || $test_threshold == 100} then {
      #
      # NOTE: The test pass threshold is set to the default value (100%).
      #       Check to make sure that all tests pass and then set the
      #       exit code to success; otherwise, we set it to failure.
      #
      set passedOrSkipped [expr {$eagle_tests(passed) + \
          $eagle_tests(skipped)}]

      if {$passedOrSkipped == $eagle_tests(total)} then {
        set exitCode Success

        host result Ok "OVERALL RESULT: SUCCESS\n"
        tlog "OVERALL RESULT: SUCCESS\n"
      } else {
        set exitCode Failure

        host result Error "OVERALL RESULT: FAILURE\n"
        tlog "OVERALL RESULT: FAILURE\n"
      }

      unset passedOrSkipped
    } else {
      #
      # NOTE: They specified a non-default test pass threshold.  Check to
      #       make sure that we meet or exceed the requirement and then
      #       set the exit code to success; otherwise, set it to failure.
      #
      if {$percent >= $test_threshold} then {
        set exitCode Success

        host result Ok [appendArgs "OVERALL RESULT: SUCCESS (" \
            $percent "% >= " $test_threshold %)\n]

        tlog [appendArgs "OVERALL RESULT: SUCCESS (" \
            $percent "% >= " $test_threshold %)\n]
      } else {
        set exitCode Failure

        host result Error [appendArgs \
            "OVERALL RESULT: FAILURE (" $percent "% < " $test_threshold %)\n]

        tlog [appendArgs \
            "OVERALL RESULT: FAILURE (" $percent "% < " $test_threshold %)\n]
      }
    }

    unset percent

    tputs $test_channel \n; # NOTE: Blank line.
  } else {
    tputs $test_channel \n; # NOTE: Blank line.

    if {$::tcltest::numTests(Passed) > 0} then {
      tputs $test_channel \
          [appendArgs "PASSED: " $::tcltest::numTests(Passed) \n]
    }

    if {$::tcltest::numTests(Failed) > 0} then {
      tputs $test_channel \
          [appendArgs "FAILED: " $::tcltest::numTests(Failed) \n]

      if {[llength $::tcltest::failFiles] > 0} then {
        tputs $test_channel \
            [appendArgs "FAILED: " $::tcltest::failFiles \n]
      }
    }

    if {$::tcltest::numTests(Skipped) > 0} then {
      tputs $test_channel \
          [appendArgs "SKIPPED: " $::tcltest::numTests(Skipped) \n]
    }

    if {$::tcltest::numTests(Total) > 0} then {
      tputs $test_channel \
          [appendArgs "TOTAL: " $::tcltest::numTests(Total) \n]

      if {$::tcltest::numTests(Skipped) > 0} then {
        set percent [getSkipPercentage]
        tputs $test_channel [appendArgs "SKIP PERCENTAGE: " \
            [formatDecimal $percent] %\n]
      }

      set percent [getPassPercentage]
      tputs $test_channel [appendArgs "PASS PERCENTAGE: " \
          [formatDecimal $percent] %\n]
    } else {
      #
      # NOTE: No tests.
      #
      set percent 0
    }

    #
    # NOTE: Has the test pass threshold been set?  If so, is it set to
    #       the default value?
    #
    if {![info exists test_threshold] || $test_threshold == 100} then {
      #
      # NOTE: The test pass threshold is set to the default value (100%).
      #       Check to make sure that all tests pass and then set the
      #       exit code to success; otherwise, we set it to failure.
      #
      set passedOrSkipped [expr {$::tcltest::numTests(Passed) + \
          $::tcltest::numTests(Skipped)}]

      if {$passedOrSkipped == $::tcltest::numTests(Total)} then {
        set exitCode 0; # Success.

        tputs $test_channel "OVERALL RESULT: SUCCESS\n"
      } else {
        set exitCode 1; # Failure.

        tputs $test_channel "OVERALL RESULT: FAILURE\n"
      }

      unset passedOrSkipped
    } else {
      #
      # NOTE: They specified a non-default test pass threshold.  Check to
      #       make sure that we meet or exceed the requirement and then
      #       set the exit code to success; otherwise, set it to failure.
      #
      if {$percent >= $test_threshold} then {
        set exitCode 0; # Success.

        tputs $test_channel [appendArgs "OVERALL RESULT: SUCCESS (" \
            $percent "% >= " $test_threshold %)\n]
      } else {
        set exitCode 1; # Failure.

        tputs $test_channel [appendArgs "OVERALL RESULT: FAILURE (" \
            $percent "% < " $test_threshold %)\n]
      }
    }

    unset percent

    tputs $test_channel \n; # NOTE: Blank line.

    #
    # NOTE: Call the Tcl test cleanup procedure now to give it a chance to do
    #       any custom cleanup that has been registered.
    #
    ::tcltest::cleanupTests
  }

  #
  # NOTE: Check for and process any custom test epilogue script that may
  #       be set in the environment.
  #
  sourceIfValid epilogue [getEnvironmentVariable testEpilogue]

  #
  # NOTE: Are we being prevented from evaluating the "post-test" script?
  #
  if {![info exists no(postTest)]} then {
    #
    # NOTE: Evaluate the specified post-test script now, if any.
    #
    if {[info exists test_flags(-postTest)] && \
        [string length $test_flags(-postTest)] > 0} then {
      #
      # TODO: Perhaps use [uplevel] here instead of [eval].  For now, it does
      #       not matter since we enforce this file being evaluated at the
      #       top-level.
      #
      eval $test_flags(-postTest)
    }
  }

  #
  # NOTE: Do we need to exit now?
  #
  if {[isExitOnComplete]} then {
    #
    # NOTE: Exit now.  In Eagle, this will not exit the entire process.
    #       Zero (0) will be the exit code if all the selected tests have
    #       succeeded or the test success threshold has been met or
    #       exceeded; otherwise, one (1) will be the exit code.
    #
    exit $exitCode
  } else {
    #
    # NOTE: For Eagle, even when not exiting, we still set the ExitCode
    #       property of the interpreter.
    #
    if {[isEagle]} then {
      object invoke -alias Interpreter.GetActive ExitCode $exitCode
    }

    unset exitCode
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































Deleted Externals/Eagle/lib/Test1.0/pkgIndex.eagle.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
###############################################################################
#
# pkgIndex.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Package Index File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

if {![package vsatisfies [package provide Tcl] 8.4]} {return}
if {![package vsatisfies [package provide Eagle] 1.0]} {return}

package ifneeded EagleTestConstraints 1.0 [list source [file join $dir \
    constraints.eagle]]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted Externals/Eagle/lib/Test1.0/pkgIndex.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
###############################################################################
#
# pkgIndex.tcl --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Package Index File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

if {![package vsatisfies [package provide Tcl] 8.4]} {return}
if {[string length [package provide Eagle]] > 0} then {return}

package ifneeded EagleTestConstraints 1.0 [list source [file join $dir \
    constraints.eagle]]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted Externals/Eagle/lib/Test1.0/prologue.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
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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
###############################################################################
#
# prologue.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Test Prologue File
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

if {![info exists no([file tail [info script]])]} then {
  if {[info level] > 0} then {
    error "cannot run, current level is not global"
  }

  #
  # NOTE: Set the location of the test suite, if necessary.
  #
  if {![info exists test_path]} then {
    set test_path [file normalize [file dirname [info script]]]
  }

  #
  # NOTE: Set the location of the base Eagle directory, if
  #       necessary.
  #
  if {![info exists base_path]} then {
    #
    # NOTE: Start out going up one level and check for a "lib"
    #       sub-directory.  If not found, go up another level
    #       because we will always be two levels down from the
    #       base directory when running inside the source tree.
    #
    set base_path [file normalize [file dirname $test_path]]

    #
    # HACK: We must verify that the "init.eagle" file can eventually
    #       be found under the "lib" directory since Visual Studio
    #       insists on creating a superfluous (and empty) "lib\Eagle1.0"
    #       sub-directory inside of the "Library" project directory
    #       simply due to the links contained in the project file that
    #       actually point to the "lib\Eagle1.0" sub-directory under the
    #       solution directory.
    #
    # WARNING: The Eagle package name and version are hard-coded here.
    #
    set pkg_dir Eagle1.0; # TODO: Change me.

    if {![file exists [file join $base_path lib]] || \
        ![file isdirectory [file join $base_path lib]] || \
        ![file exists [file join $base_path lib $pkg_dir]] || \
        ![file isdirectory [file join $base_path lib $pkg_dir]] || \
        ![file exists [file join $base_path lib $pkg_dir init.eagle]] || \
        ![file isfile [file join $base_path lib $pkg_dir init.eagle]]} then {
      #
      # NOTE: We do not bother to check if the "lib" sub-directory actually
      #       exists as a child of this one.  This is the previous (legacy)
      #       behavior (i.e. where we always went up two levels to the base
      #       directory).
      #
      set base_path [file dirname $base_path]
    }

    unset pkg_dir
  }

  #
  # NOTE: Set the local root directory of the source checkout (i.e. of
  #       Eagle or whatever project the Eagle binaries are being used by).
  #
  if {![info exists root_path]} 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
      #       value will probably be wrong for any project(s) other than Eagle.
      #       In that case, this value should be overridden by that project to
      #       relfect the actual local root directory of the source checkout
      #       for that project.
      #
      set root_path $base_path
    } else {
      #
      # NOTE: We extracted the local root directory of the source checkout
      #       from Fossil.  Now, make sure it is fully normalized and has no
      #       trailing slashes.
      #
      set root_path [file normalize $directory]
    }

    unset -nocomplain directory dummy exec pattern
  }

  #
  # NOTE: Set the executable file name for the process, if
  #       necessary.
  #
  if {![info exists bin_file]} then {
    set bin_file [info nameofexecutable]
  }

  #
  # NOTE: Set the location of the directory containing the
  #       executable file for the process, if necessary.
  #
  if {![info exists bin_path]} then {
    set bin_path [file normalize [file dirname $bin_file]]
  }

  #
  # NOTE: Set the location of the [non-script] library directory
  #       (i.e. the directory where the plugins are located), if
  #       necessary.
  #
  if {![info exists lib_path]} then {
    #
    # NOTE: This should go one directory up from the directory
    #       containing the executable file for the process (e.g.
    #       the shell) and then into the "lib" directory just
    #       beneath that.
    #
    set lib_path [file normalize [file join [file dirname $bin_path] lib]]
  }

  #
  # NOTE: Set the web host to test against, if necessary.
  #
  if {![info exists test_host]} then {
    set test_host eagle.to
  }

  #
  # NOTE: Set the port to use for server sockets, if necessary.
  #
  if {![info exists test_port]} then {
    set test_port 12346; # IANA, 12346-12752 Unassigned
  }

  #
  # NOTE: Set the network timeout, if necessary.
  #
  if {![info exists test_timeout]} then {
    set test_timeout 2000; # in milliseconds.
  }

  #
  # NOTE: Set the channel to use for test output, if necessary.
  #
  if {![info exists test_channel]} then {
    set test_channel stdout
  }

  #
  # NOTE: Set the primary package path, if necessary.
  #
  if {![info exists test_package_path]} then {
    set test_package_path [file join $base_path lib]
  }

  #
  # NOTE: Make sure our primary package path is part of the auto path.
  #
  if {[lsearch -exact $auto_path $test_package_path] == -1} then {
    lappend auto_path $test_package_path
  }

  #
  # NOTE: Make sure our test package path is part of the auto path.
  #
  if {[lsearch -exact $auto_path $test_path] == -1} then {
    lappend auto_path $test_path
  }

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

  #
  # NOTE: Check for and load the Eagle library package, if necessary.
  #
  if {[catch {package present EagleLibrary}]} then {
    package require EagleLibrary
  }

  #
  # NOTE: Check for and load the Eagle test package, if necessary.
  #
  if {[catch {package present EagleTest}]} then {
    package require EagleTest
  }

  #
  # NOTE: Check for and load the Eagle test constraints package, if
  #       necessary.
  #
  if {[catch {package present EagleTestConstraints}]} then {
    package require EagleTestConstraints
  }

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

  #
  # NOTE: If command line arguments were supplied, process them now.
  #
  set test_flags(-configuration) ""; # build configuration, default to empty.
  set test_flags(-suffix) ""; # build suffix, default to empty.
  set test_flags(-file) [list *.eagle]; # default to running all test files.
  set test_flags(-notFile) [list l.*.eagle]; # COMPAT: Tcl.
  set test_flags(-match) [list *]; # default to running all tests.
  set test_flags(-skip) [list]; # default to skipping no tests.
  set test_flags(-constraints) [list]; # default to no manual constraints.
  set test_flags(-logFile) ""; # default to using standard log file naming.
  set test_flags(-threshold) ""; # default to requiring all tests to pass.
  set test_flags(-stopOnFailure) ""; # default to continue on failure.
  set test_flags(-exitOnComplete) ""; # default to not exit after complete.
  set test_flags(-preTest) ""; # default to not evaluating anything.
  set test_flags(-postTest) ""; # default to not evaluating anything.

  #
  # NOTE: Check for and process any command line arguments.
  #
  if {[info exists argv]} then {
    eval processTestArguments test_flags $argv

    if {[info exists test_flags(-no)] && \
        [string length $test_flags(-no)] > 0} then {
      #
      # NOTE: Set the test run restrictions based on the provided command line
      #       argument value (which is assumed to be a "dictionary-style" list
      #       containing name/value pairs to add to the global "no" array).
      #
      foreach {name value} $test_flags(-no) {
        set no($name) $value
      }

      unset name value
    }

    if {[info exists test_flags(-logFile)] && \
        [string length $test_flags(-logFile)] > 0} then {
      #
      # NOTE: Set the log file name to the one provided by the command line.
      #
      set test_log $test_flags(-logFile)
    }

    if {[info exists test_flags(-threshold)] && \
        [string is integer -strict $test_flags(-threshold)]} then {
      #
      # NOTE: Set the test pass threshold to the one provided by the command
      #       line.
      #
      set test_threshold $test_flags(-threshold)
    }

    if {[info exists test_flags(-stopOnFailure)] && \
        [string is boolean -strict $test_flags(-stopOnFailure)]} then {
      #
      # NOTE: Set the test stop-on-failure flag to the one provided by the
      #       command line.
      #
      set test_stop_on_failure $test_flags(-stopOnFailure)
    }

    if {[info exists test_flags(-exitOnComplete)] && \
        [string is boolean -strict $test_flags(-exitOnComplete)]} then {
      #
      # NOTE: Set the test exit-on-complete flag to the one provided by the
      #       command line.
      #
      set test_exit_on_complete $test_flags(-exitOnComplete)
    }
  }

  #
  # NOTE: Set the default test configuration (i.e. Debug or Release), if
  #       necessary.
  #
  if {![info exists test_configuration]} then {
    set test_configuration [getPlatformInfo configuration Release]
  }

  #
  # NOTE: Set the Tcl shell executable to use for those specialized
  #       tests that may require it, if necessary.
  #
  if {![info exists test_tclsh]} then {
    if {[isEagle] || ![string match tclsh* $bin_file]} then {
      set test_tclsh tclsh
    } else {
      set test_tclsh $bin_file
    }
  }

  #
  # NOTE: Has automatic log file naming been disabled?
  #
  if {![info exists no(logFileName)]} then {
    #
    # NOTE: Set the log to use for test output, if necessary.
    #
    if {![info exists test_log]} then {
      set test_log [file join [getTemporaryPath] [appendArgs [file tail [info \
          nameofexecutable]] [getTestLogId] .test. [pid] .log]]
    }
  }

  #
  # NOTE: Are we being prevented from evaluating the "pre-test" script?
  #
  if {![info exists no(preTest)]} then {
    #
    # NOTE: Evaluate the specified pre-test script now, if any.
    #
    if {[info exists test_flags(-preTest)] && \
        [string length $test_flags(-preTest)] > 0} then {
      #
      # TODO: Perhaps use [uplevel] here instead of [eval].  For now, it does
      #       not matter since we enforce this file being evaluated at the
      #       top-level.
      #
      eval $test_flags(-preTest)
    }
  }

  #
  # NOTE: Check for and process any custom test prologue script that may be set
  #       in the environment.  This must be done after the Eagle test package
  #       has been made available and after the log file has been setup.
  #
  sourceIfValid prologue [getEnvironmentVariable testPrologue]

  #
  # NOTE: Show the name of the executable and the command line arguments, if
  #       any.  This must be done after the log file has been setup; otherwise,
  #       this information will not be visible in the log file.
  #
  tputs $test_channel [appendArgs "---- testRunId: " \
      [getTestRunId] \n]

  tputs $test_channel [appendArgs "---- processId: " \
      [pid] \n]

  tputs $test_channel [appendArgs "---- test channel: " \
      $test_channel \n]

  tputs $test_channel [appendArgs "---- test configuration: " \
      [expr {[info exists test_configuration] ? \
          $test_configuration : "<none>"}] \n]

  if {[isEagle]} then {
    catch {info engine PublicKeyToken} publicKeyToken

    if {[string length $publicKeyToken] == 0} then {
      #
      # NOTE: The Eagle core library is not strong name signed.  This is not an
      #       error, per se; however, it may cause some tests to fail and it
      #       should be reported to the user and noted in the test suite log
      #       file.
      #
      tputs $test_channel [appendArgs \
          "==== WARNING: running without any strong name signature...\n"]
    } else {
      #
      # BUGBUG: Tcl 8.4 does not like this expression because it contains the
      #         "ni" operator (and Tcl tries to compile it even though it will
      #         only actually ever be evaluated in Eagle).
      #
      set expr {$publicKeyToken ni "29c6297630be05eb 1e22ec67879739a2"}

      if {[expr $expr]} then {
        #
        # NOTE: The Eagle core library is strong name signed with a key that is
        #       not official.  This is also not an error, per se; however, it
        #       may cause some tests to fail and it should be reported to the
        #       user and noted in the test suite log file.
        #
        tputs $test_channel [appendArgs \
            "==== WARNING: running without official strong name signature: " \
            $publicKeyToken \n]
      }

      unset expr
    }

    unset publicKeyToken

    tputs $test_channel [appendArgs "---- original command line: " \
        [info cmdline] \n]

    tputs $test_channel [appendArgs "---- threadId: " \
        [info tid] \n]

    tputs $test_channel [appendArgs "---- processors: " \
        [info processors] \n]

    catch {object invoke Console.InputEncoding WebName} encoding

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

    catch {object invoke Console.OutputEncoding WebName} encoding

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

    unset encoding
    catch {debug memory} memory

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

    unset memory
    catch {debug stack true} stack

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

    unset stack
    catch {file drive} drive

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

    unset drive
  }

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

  tputs $test_channel [appendArgs "---- command line: " \
      [expr {[info exists argv] && [string length $argv] > 0 ? \
          $argv : "<none>"}] \n]

  tputs $test_channel [appendArgs "---- logging to: " \
      [expr {[info exists test_log] && [string length $test_log] > 0 ? \
          [appendArgs \" $test_log \"] : "<none>"}] \n]

  tputs $test_channel [appendArgs "---- pass threshold: " \
      [expr {[info exists test_threshold] && \
          [string is integer -strict $test_threshold] ? \
              [appendArgs $test_threshold %] : "<none>"}] \n]

  tputs $test_channel [appendArgs "---- stop on failure: " \
      [expr {[info exists test_stop_on_failure] && \
          [string is boolean -strict $test_stop_on_failure] ? \
              $test_stop_on_failure : "<none>"}] \n]

  tputs $test_channel [appendArgs "---- exit on complete: " \
      [expr {[info exists test_exit_on_complete] && \
          [string is boolean -strict $test_exit_on_complete] ? \
              $test_exit_on_complete : "<none>"}] \n]

  #
  # NOTE: Show the information about which tests and files are being run and/or
  #       skipped (COMPAT: Tcl).
  #
  if {[llength $test_flags(-file)] > 0} then {
    tputs $test_channel [appendArgs "---- running test files that match: " \
        $test_flags(-file) \n]
  }

  if {[llength $test_flags(-notFile)] > 0} then {
    tputs $test_channel [appendArgs "---- skipping test files that match: " \
        $test_flags(-notFile) \n]
  }

  if {[llength $test_flags(-match)] > 0} then {
    tputs $test_channel [appendArgs "---- running tests that match: " \
        $test_flags(-match) \n]
  }

  if {[llength $test_flags(-skip)] > 0} then {
    tputs $test_channel [appendArgs "---- skipping tests that match: " \
        $test_flags(-skip) \n]
  }

  tputs $test_channel [appendArgs "---- path: " \
      [expr {[info exists path] && [string length $path] > 0 ? \
          [appendArgs \" $path \"] : "<none>"}] \n]

  tputs $test_channel [appendArgs "---- base path: \"" \
      $base_path \"\n]

  tputs $test_channel [appendArgs "---- root path: \"" \
      $root_path \"\n]

  tputs $test_channel [appendArgs "---- binary path: \"" \
      $bin_path \"\n]

  tputs $test_channel [appendArgs "---- library path: \"" \
      $lib_path \"\n]

  tputs $test_channel [appendArgs "---- tests located in: \"" \
      $test_path \"\n]

  tputs $test_channel [appendArgs "---- tests running in: \"" \
      [pwd] \"\n]

  tputs $test_channel [appendArgs "---- temporary files stored in: \"" \
      [getTemporaryPath] \"\n]

  tputs $test_channel [appendArgs "---- native Tcl shell: \"" \
      $test_tclsh \"\n]

  tputs $test_channel [appendArgs "---- disabled options: " \
      [formatList [lsort [array names no]] <none>] \n]

  #
  # NOTE: Initialize the Eagle test constraints.
  #
  if {[isEagle]} then {
    initializeTests

    #
    # NOTE: If the "no(mono)" variable is set (to anything) then any
    #       special test suite hacks for Mono will be disabled. This
    #       does not control or change any hacks for Mono that may
    #       be present in the library itself.
    #
    # if {![info exists no(mono)] && [isMono]} then {
    #   set no(mono) true
    # }

    #
    # NOTE: Has administrator detection support been disabled?  We do
    #       this check [nearly] first as it may [eventually] be used
    #       to help determine if other constraints should be skipped.
    #
    if {![info exists no(administrator)]} then {
      checkForAdministrator $test_channel
    }

    #
    # NOTE: Has host detection support been disabled?
    #
    if {![info exists no(host)]} then {
      checkForHost $test_channel
    }

    #
    # NOTE: Has primary thread detection support been disabled?  We do
    #       this check [nearly] first as it may [eventually] be used
    #       to help determine if other constraints should be skipped.
    #
    if {![info exists no(primaryThread)]} then {
      checkForPrimaryThread $test_channel
    }

    #
    # NOTE: Has default application domain detection support been
    #       disabled?  We do this check [nearly] first as it may
    #       [eventually] be used to help determine if other
    #       constraints should be skipped.
    #
    if {![info exists no(defaultAppDomain)]} then {
      checkForDefaultAppDomain $test_channel
    }

    #
    # NOTE: Has runtime detection support been disabled?  We do this
    #       checking [nearly] first as it may skip other constraints.
    #
    if {![info exists no(runtime)]} then {
      checkForRuntime $test_channel
    }

    #
    # NOTE: Check the runtime version (i.e. what version of the runtime
    #       are we currently running on?).
    #
    if {![info exists no(runtimeVersion)]} then {
      checkForRuntimeVersion $test_channel
    }

    #
    # NOTE: Check the image runtime version (i.e. what version of the
    #       runtime was this assembly compiled against?).
    #
    if {![info exists no(imageRuntimeVersion)]} then {
      checkForImageRuntimeVersion $test_channel
    }

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

    #
    # NOTE: Has culture detection support been disabled?
    #
    if {![info exists no(culture)]} then {
      checkForCulture $test_channel
    }

    #
    # NOTE: Has thread culture detection support been disabled?
    #
    if {![info exists no(threadCulture)]} then {
      checkForThreadCulture $test_channel
    }

    #
    # NOTE: Has software update trust detection support been disabled?
    #
    if {![info exists no(softwareUpdate)]} then {
      checkForSoftwareUpdateTrust $test_channel
    }

    #
    # NOTE: Has database testing support been disabled?
    #
    if {![info exists no(sql)]} then {
      #
      # NOTE: Set the server name, if necessary.
      #
      if {![info exists server]} then {
        set server .
      }

      #
      # NOTE: Set the database name, if necessary.
      #
      if {![info exists database]} then {
        set database master
      }

      #
      # NOTE: Set the connection timeout, if necessary.
      #
      if {![info exists timeout]} then {
        set timeout [expr {$test_timeout / 1000}]; # milliseconds to seconds.
      }

      #
      # NOTE: Set the test user name, if necessary.
      #
      if {![info exists user]} then {
        set user [getEnvironmentVariable user]
      }

      #
      # NOTE: Set the test password, if necessary.
      #
      if {![info exists password]} then {
        set password [getEnvironmentVariable password]
      }

      #
      # NOTE: Set the database connection string, if necessary.
      #
      if {![info exists test_database]} then {
        #
        # NOTE: Mono does not have support for trusted connections;
        #       therefore, we must create a slightly different
        #       connection string.
        #
        set test_database [subst \
            {Data Source=${server};Initial Catalog=${database};Connect\
            Timeout=${timeout};[expr {[isMono] ? [subst \
            {User Id=${user};Password=${password};}] : {Integrated\
            Security=SSPI;}}]}]
      }

      #
      # NOTE: Can we access the local database?
      #
      checkForDatabase $test_channel $test_database
      unset password user timeout database server
    }

    #
    # NOTE: Has symbol testing support been disabled?
    #
    if {![info exists no(assemblySymbols)]} then {
      checkForSymbols $test_channel [lindex [info assembly] end]
    }

    #
    # NOTE: Has quiet testing support been disabled?
    #
    if {![info exists no(quiet)]} then {
      #
      # NOTE: For tests "basic-1.36", "debug-1.3", "debug-1.4", "object-10.*",
      #       and "perf-2.2".
      #
      checkForQuiet $test_channel
    }

    #
    # NOTE: Has object handle reference count tracking support been disabled
    #       (at compile-time)?
    #
    if {![info exists no(refCount)]} then {
      #
      # NOTE: For tests "excel-*", "object-2.*", "object-7.1", "object-8.*",
      #       and "object-98.*".
      #
      checkForReferenceCountTracking $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)?
      #
      if {![info exists no(compileCallbackQueue)]} then {
        #
        # NOTE: For test "commands-1.4".
        #
        checkForCompileOption $test_channel CALLBACK_QUEUE
      }

      #
      # NOTE: Has console support been enabled (at compile-time)?
      #
      if {![info exists no(compileConsole)]} then {
        #
        # NOTE: For test "host-1.2".
        #
        checkForCompileOption $test_channel CONSOLE
      }

      #
      # NOTE: Has database support been enabled (at compile-time)?
      #
      if {![info exists no(compileData)]} then {
        #
        # NOTE: For tests "sql-1.1" and "upvar-99.1".
        #
        checkForCompileOption $test_channel DATA
      }

      #
      # NOTE: Has script debugger support been enabled (at compile-time)?
      #
      if {![info exists no(compileDebugger)]} then {
        #
        # NOTE: For tests "debug-1.1", "debug-2.1", "debug-3.1" and
        #       "debug-4.1".
        #
        checkForCompileOption $test_channel DEBUGGER
      }

      #
      # NOTE: Has isolated interpreter support been enabled (at compile-time)?
      #
      if {![info exists no(compileIsolatedInterpreters)]} then {
        #
        # NOTE: For test "xaml-1.2".
        #
        checkForCompileOption $test_channel ISOLATED_INTERPRETERS
      }

      #
      # NOTE: Has isolated plugin support been enabled (at compile-time)?
      #
      if {![info exists no(compileIsolatedPlugins)]} then {
        #
        # NOTE: For test "load-1.1.1".
        #
        checkForCompileOption $test_channel ISOLATED_PLUGINS
      }

      #
      # NOTE: Has PowerShell approved-verbs support been enabled (at
      #       compile-time)?
      #
      if {![info exists no(compileApprovedVerbs)]} then {
        #
        # NOTE: For test "object-4.8".
        #
        checkForCompileOption $test_channel APPROVED_VERBS
      }

      #
      # NOTE: Has Mono support been enabled (at compile-time)?
      #
      if {![info exists no(compileMono)]} then {
        #
        # NOTE: For test "object-4.13".
        #
        checkForCompileOption $test_channel MONO
      }

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

      #
      # 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".
        #
        checkForCompileOption $test_channel NATIVE_PACKAGE
      }

      #
      # NOTE: Has network support been enabled (at compile-time)?
      #
      if {![info exists no(compileNetwork)]} then {
        #
        # NOTE: For tests "commands-1.4", "socket-1.*", "socket-2.1", and
        #       "socket-3.1".
        #
        checkForCompileOption $test_channel NETWORK
      }

      #
      # NOTE: Has native Tcl support been enabled (at compile-time)?
      #
      if {![info exists no(compileTcl)]} then {
        #
        # NOTE: For tests "commands-1.1.*", "excel-2.2", "tclCancel-1.1",
        #       "tclEncoding-1.*", "tclErrorInfo-1.*", "tclLoad-1.*",
        #       "tclResetCancel-1.1", "tclResetCancel-2.1",
        #       "tclResetCancel-2.2", "tclResetCancel-3.1",
        #       "tclResetCancel-4.1", "tclSet-1.1", and "tclSubst-1.1".
        #
        checkForCompileOption $test_channel TCL
      }

      #
      # NOTE: Has xml support been enabled (at compile-time)?
      #
      if {![info exists no(compileXml)]} then {
        #
        # NOTE: For tests "commands-1.4", "object-7.3" and "xml-1.1.*".
        #
        checkForCompileOption $test_channel XML
      }

      #
      # NOTE: Has serialization support been enabled (at compile-time)?
      #
      if {![info exists no(compileSerialization)]} then {
        #
        # NOTE: For test "interp-1.10".
        #
        checkForCompileOption $test_channel SERIALIZATION
      }

      #
      # NOTE: Has dedicated test support been enabled (at compile-time)?
      #
      if {![info exists no(compileTest)]} then {
        #
        # NOTE: For tests "basic-1.20", "basic-1.21", "function-1.1",
        #       "object-2.1", "object-3.1", "object-4.1", "object-7.1",
        #       "object-7.2", "object-7.4", "object-14.4", "object-14.5",
        #       "object-14.6", "remotingServer-1.*", and "debug-5.*".
        #
        checkForCompileOption $test_channel TEST
      }

      #
      # NOTE: Has threading support been enabled (at compile-time)?
      #
      if {![info exists no(compileThreading)]} then {
        #
        # NOTE: For tests "object-10.2" and "object-10.3".
        #
        checkForCompileOption $test_channel THREADING
      }

      #
      # NOTE: Has Tcl threading support been enabled (at compile-time)?
      #
      if {![info exists no(compileTclThreaded)]} then {
        #
        # NOTE: For tests "tclLoad-1.5" and "tclLoad-1.6".
        #
        checkForCompileOption $test_channel TCL_THREADED
      }

      #
      # NOTE: Has Tcl isolated interpreter thread support been enabled (at
      #       compile-time)?
      #
      if {![info exists no(compileTclThreads)]} then {
        #
        # NOTE: For tests "tclLoad-1.5" and "tclLoad-1.6".
        #
        checkForCompileOption $test_channel TCL_THREADS
      }
    }

    #
    # NOTE: Has dynamic loading testing support been disabled?
    #
    if {![info exists no(dynamic)]} then {
      #
      # NOTE: For tests "commands-1.1.*", "library-3.*", and "tcl*-*.*".
      #
      checkForDynamicLoading $test_channel
    }

    #
    # NOTE: Has Tcl testing support been disabled?
    #
    if {![info exists no(tcl)]} then {
      if {![info exists no(tclInstalls)]} then {
        #
        # NOTE: For tests "commands-1.1.*", "library-3.*", and "tcl*-*.*".
        #
        checkForTclInstalls $test_channel
      }

      if {![info exists no(tclReady)]} then {
        checkForTclReady $test_channel
      }

      if {![info exists no(tclShell)]} then {
        #
        # NOTE: For test "garuda-1.1".
        #
        checkForTclShell $test_channel
      }

      if {![info exists no(tkPackage)]} then {
        #
        # NOTE: For test "tclLoad-1.1".
        #
        checkForTkPackage $test_channel
      }
    }

    #
    # NOTE: Has custom test method support been disabled?
    #
    if {![info exists no(test)]} then {
      #
      # NOTE: Has remoting testing support been disabled?
      #
      if {![info exists no(testRemoting)]} then {
        #
        # NOTE: For tests "remotingServer-1.*".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestRemoting*
      }

      #
      # NOTE: Has asynchronous testing support been disabled?
      #
      if {![info exists no(testAsynchronous)]} then {
        #
        # NOTE: For tests "basic-1.20" and "basic-1.21".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestEvaluateAsync*
      }

      #
      # NOTE: Has custom function testing support been disabled?
      #
      if {![info exists no(testFunction)]} then {
        #
        # NOTE: For test "function-1.1".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestAddFunction*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestRemoveFunction*

        #
        # NOTE: For tests "function-5.*".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestAddNamedFunction*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestRemoveNamedFunction*
      }

      #
      # NOTE: Has write-box testing support been disabled?
      #
      if {![info exists no(testWriteBox)]} then {
        #
        # NOTE: For tests "debug-5.*".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestWriteBox*
      }

      #
      # NOTE: Has shell testing support been disabled?
      #
      if {![info exists no(testShell)]} then {
        #
        # NOTE: For test "debug-1.3".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestShellMainCore*

        #
        # NOTE: For tests "basic-1.36" and "debug-1.3".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestSetQuiet*
      }

      #
      # NOTE: Has IDisposable testing support been disabled?
      #
      if {![info exists no(testDisposable)]} then {
        #
        # NOTE: For test "object-2.8".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default+Disposable \
            *ToString* Eagle._Tests.Default.Disposable.ToString
      }

      #
      # NOTE: Has linked variable testing support been disabled?
      #
      if {![info exists no(testLinkedVariables)]} then {
        #
        # NOTE: For tests "basic-1.39", "basic-1.40", "basic-1.41",
        #       "basic-1.42", and "basic-1.43".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestSetVariableLinks*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestUnsetVariableLinks*
      }

      #
      # NOTE: Has field testing support been disabled?
      #
      if {![info exists no(testFields)]} then {
        #
        # NOTE: For tests "basic-1.39", "basic-1.40", "basic-1.41",
        #       "basic-1.42", and "basic-1.43".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *privateField*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *objectField*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *intField*
      }

      #
      # NOTE: Has property testing support been disabled?
      #
      if {![info exists no(testProperties)]} then {
        #
        # NOTE: For tests "basic-1.39", "basic-1.40", "basic-1.41",
        #       "basic-1.42", and "basic-1.43".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *get_SimpleProperty*

        #
        # NOTE: For test "object-3.1".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *get_Item*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *set_Item*
      }

      #
      # NOTE: Has core marshaller testing support been disabled?
      #
      if {![info exists no(testMarshaller)]} then {
        #
        # NOTE: For test "basic-1.29".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestExecuteStaticDelegates*

        #
        # NOTE: For tests "basic-1.30" and "basic-1.31".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestExecuteDelegateCommands*

        #
        # NOTE: For test "object-2.1".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestComplexMethod*

        #
        # NOTE: For test "object-2.3".
        #
        checkForObjectMember $test_channel Eagle._Components.Private.ArrayOps \
            *ToHexadecimalString*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestMulti2Array*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestMulti3Array*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestNestedArray*

        #
        # NOTE: For tests "object-3.6" and "object-3.7".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestStringIListReturnValue*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestStringIListIListIListReturnValue*

        #
        # NOTE: For test "object-3.8".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestByteList*

        #
        # NOTE: For test "object-3.9".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestIntList*

        #
        # NOTE: For test "object-3.10".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestLongList*

        #
        # NOTE: For test "object-3.11".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestDerivedList*

        #
        # NOTE: For tests "object-3.12" and "object-3.13".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestStringIDictionaryReturnValue*

        #
        # NOTE: For test "object-4.1".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestExpr*

        #
        # NOTE: For test "object-7.1".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestByRefValueTypeMethod*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestNullableValueTypeMethod*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestByRefNullableValueTypeMethod*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestIntArrayReturnValue*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestStringArrayReturnValue*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestStringListReturnValue*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestStringListArrayReturnValue*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestByRefStringListArray*

        #
        # NOTE: For tests "object-7.2" and "object-7.4".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestNullArray*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestOutArray*

        #
        # NOTE: For test "object-7.5".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestEnum*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestByRefEnum*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestNullableEnum*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestByRefNullableEnum*

        #
        # NOTE: For tests "object-14.4" and "object-14.5".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *StaticObjectProperty*

        #
        # NOTE: For test "object-14.6".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TypeProperty*
      }
    }

    #
    # NOTE: Has Excel testing support been disabled?
    #
    if {![info exists no(excel)]} then {
      #
      # NOTE: For tests "excel-*.*".
      #
      checkForAssembly $test_channel Microsoft.Office.Interop.Excel
    }

    #
    # NOTE: Has speech testing support been disabled?
    #
    if {![info exists no(speech)]} then {
      #
      # NOTE: Set the audio volume, if necessary.
      #
      if {![info exists test_volume]} then {
        set test_volume 0; # in percent, 0 is silent.
      }

      #
      # NOTE: For test "object-4.5".
      #
      checkForAssembly $test_channel System.Speech
    }

    #
    # NOTE: Has WinForms testing support been disabled?
    #
    if {![info exists no(winForms)]} then {
      #
      # NOTE: For tests "object-13.1.*", "object-13.2.*", and
      #       "winForms-*.*".
      #
      checkForWindowsForms $test_channel
    }

    #
    # NOTE: Are we running in an STA thread?
    #
    if {![info exists no(staThread)]} then {
      #
      # NOTE: For tests "xaml-1.*".
      #
      checkForStaThread $test_channel
    }

    #
    # NOTE: Has WPF testing support been disabled?
    #
    if {![info exists no(wpf)]} then {
      #
      # NOTE: For tests "xaml-1.*".
      #
      checkForWindowsPresentationFoundation $test_channel
    }

    #
    # NOTE: Has PowerShell testing support been disabled?
    #
    if {![info exists no(powerShell)]} then {
      #
      # NOTE: For tests "object-4.7", "object-4.8", and "object-4.9".
      #
      checkForPowerShell $test_channel
    }

    #
    # NOTE: Has Visual Studio testing support been disabled?
    #
    if {![info exists no(visualStudio)]} then {
      checkForVisualStudio $test_channel
    }

    #
    # NOTE: Has WiX testing support been disabled?
    #
    if {![info exists no(wix)]} then {
      #
      # NOTE: For test "object-4.10".
      #
      checkForWix $test_channel
    }

    #
    # NOTE: Has managed debugger testing support been disabled?
    #
    if {![info exists no(managedDebugger)]} then {
      checkForManagedDebugger $test_channel
    }

    #
    # NOTE: Has script debugger testing support been disabled?
    #
    if {![info exists no(scriptDebugger)]} then {
      #
      # NOTE: For tests "debug-1.1", "debug-2.1", "debug-3.1", and
      #       "debug-4.1".
      #
      checkForScriptDebugger $test_channel
    }

    #
    # NOTE: Has script debugger interpreter testing support been
    #       disabled?
    #
    if {![info exists no(scriptDebuggerInterpreter)]} then {
      #
      # NOTE: For test "debug-2.1".
      #
      checkForScriptDebuggerInterpreter $test_channel
    }

    #
    # NOTE: Are we running under the Mono debugger?  If so, several
    #       tests will have to be disabled because they do not appear
    #       to work there.
    #
    if {![info exists no(monoDebugger)]} then {
      tputs $test_channel "---- checking for Mono debugger... "

      if {[haveConstraint mono] && [haveConstraint managedDebugger]} then {
        #
        # NOTE: Add a special test constraint to simplify the Mono debugger
        #       test constraint checking for the tests that need it.
        #
        addConstraint monoDebugger

        tputs $test_channel yes\n
      } else {
        tputs $test_channel no\n
      }
    }

    #
    # NOTE: Has Garuda testing support been disabled?
    #
    if {![info exists no(garudaDll)]} then {
      #
      # NOTE: For test "garuda-1.1".
      #
      checkForGarudaDll $test_channel
    }
  } else {
    #
    # HACK: Reset the test counts for tcltest.
    #
    set ::tcltest::numTests(Total) 0
    set ::tcltest::numTests(Skipped) 0
    set ::tcltest::numTests(Passed) 0
    set ::tcltest::numTests(Failed) 0

    #
    # HACK: Reset the list of failed files.
    #
    set ::tcltest::failFiles [list]

    #
    # NOTE: Has compile/runtime option testing support been disabled?
    #
    if {![info exists no(compileOptions)]} then {
      #
      # NOTE: Has dedicated test support been enabled (at compile-time)?
      #
      if {![info exists no(compileTest)]} then {
        #
        # NOTE: For test "tclLoad-1.16.1".
        #
        checkForCompileOption $test_channel TEST
      }
    }
  }

  #
  # NOTE: Has checking for the extra files needed by various tests been
  #       disabled?
  #
  if {![info exists no(checkForFile)]} then {
    #
    # NOTE: For test "package-1.0".
    #
    if {![info exists no(pkgAll.tcl)]} then {
      checkForFile $test_channel [file join $base_path Package Tests all.tcl] \
          pkgAll.tcl
    }

    #
    # NOTE: For tests "subst-1.*".
    #
    if {![info exists no(bad_subst.txt)]} then {
      checkForFile $test_channel [file join $test_path bad_subst.txt]
    }

    #
    # NOTE: For tests "fileIO-1.*".
    #
    if {![info exists no(file.dat)]} then {
      checkForFile $test_channel [file join $test_path file.dat]
    }

    #
    # NOTE: For test "garbage-1.1".
    #
    if {![info exists no(garbage.txt)]} then {
      checkForFile $test_channel [file join $test_path garbage.txt]
    }

    #
    # NOTE: For tests "xaml-1.*".
    #
    if {![info exists no(test.png)]} then {
      checkForFile $test_channel [file join $test_path test.png]
    }

    #
    # NOTE: For test "socket-1.2".
    #
    if {![info exists no(client.tcl)]} then {
      checkForFile $test_channel [file join $test_path client.tcl]
    }

    #
    # NOTE: For test "tclLoad-1.2".
    #
    if {![info exists no(tcl_unload.tcl)]} then {
      checkForFile $test_channel [file join $test_path tcl_unload.tcl]
    }

    #
    # NOTE: For test "basic-1.4".
    #
    if {![info exists no(read.eagle)]} then {
      checkForFile $test_channel [file join $test_path read.eagle]
    }

    #
    # NOTE: For test "basic-1.5".
    #
    if {![info exists no(read2.eagle)]} then {
      checkForFile $test_channel [file join $test_path read2.eagle]
    }

    #
    # NOTE: For test "basic-1.6".
    #
    if {![info exists no(read3.eagle)]} then {
      checkForFile $test_channel [file join $test_path read3.eagle]
    }

    #
    # NOTE: For test "basic-1.7".
    #
    if {![info exists no(read4.eagle)]} then {
      checkForFile $test_channel [file join $test_path read4.eagle]
    }

    #
    # NOTE: For test "infoScript-1.1".
    #
    if {![info exists no(script.eagle)]} then {
      checkForFile $test_channel [file join $test_path script.eagle]
    }

    #
    # NOTE: For test "basic-1.1".
    #
    if {![info exists no(source.eagle)]} then {
      checkForFile $test_channel [file join $test_path source.eagle]
    }

    #
    # NOTE: For test "basic-1.2".
    #
    if {![info exists no(unbalanced_brace.eagle)]} then {
      checkForFile $test_channel [file join $test_path unbalanced_brace.eagle]
    }

    #
    # NOTE: For test "basic-1.3".
    #
    if {![info exists no(unbalanced_brace2.eagle)]} then {
      checkForFile $test_channel [file join $test_path unbalanced_brace2.eagle]
    }

    #
    # NOTE: For tests "excel-2.*".
    #
    if {![info exists no(test.xls)]} then {
      checkForFile $test_channel [file join $test_path test.xls]
    }

    #
    # NOTE: For test "interp-1.10".
    #
    if {![info exists no(settings.xml)]} then {
      checkForFile $test_channel [file join $test_path settings.xml]
    }

    #
    # NOTE: For tests "load-1.1.*".
    #
    if {![info exists no(Plugin.dll)]} then {
      checkForFile $test_channel [file join $lib_path Plugin1.0 Plugin.dll]
    }

    #
    # NOTE: For test "object-6.1".
    #
    if {![info exists no(Sample.exe)]} then {
      checkForFile $test_channel [file join $bin_path Sample.exe]
    }

    #
    # NOTE: For test "object-4.8".
    #
    if {![info exists no(EagleCmdlets.dll)]} then {
      checkForFile $test_channel [file join $bin_path EagleCmdlets.dll]
    }

    #
    # NOTE: For test "object-4.10".
    #
    if {![info exists no(EagleExtensions.dll)]} then {
      checkForFile $test_channel [file join $bin_path EagleExtensions.dll]
    }

    #
    # NOTE: For test "object-4.10".
    #
    if {![info exists no(test.wxs)]} then {
      checkForFile $test_channel [file join $base_path Installer Tests test.wxs]
    }

    #
    # NOTE: For test "sql-1.2".
    #
    if {![info exists no(sqlite3.dll)]} then {
      checkForFile $test_channel [file join $bin_path sqlite3.dll]
    }

    if {![info exists no(System.Data.SQLite.dll)]} then {
      checkForFile $test_channel [file join $bin_path System.Data.SQLite.dll]
    }

    if {![info exists no(test.sqlite3)]} then {
      checkForFile $test_channel [file join $test_path test.sqlite3]
    }
  }

  #
  # NOTE: Check the core test constraints unless they have been
  #       explicitly disabled.
  #
  if {![info exists no(platform)]} then {
    checkForPlatform $test_channel
  }

  if {![info exists no(version)]} then {
    checkForVersion $test_channel
  }

  if {![info exists no(eagle)]} then {
    checkForEagle $test_channel
  }

  if {![info exists no(noLogFile)]} then {
    checkForLogFile $test_channel
  }

  if {![info exists no(symbols)]} then {
    checkForSymbols $test_channel [info nameofexecutable]
  }

  if {![info exists no(garuda)]} then {
    checkForGaruda $test_channel
  }

  if {![info exists no(shell)]} then {
    checkForShell $test_channel
  }

  if {![info exists no(debug)]} then {
    checkForDebug $test_channel
  }

  #
  # NOTE: Has Tk testing support been disabled?
  #
  if {![info exists no(tk)]} then {
    checkForTk $test_channel
  }

  #
  # NOTE: Has native code detection support been disabled?
  #
  if {![info exists no(native)]} then {
    checkForNativeCode $test_channel
  }

  #
  # NOTE: Check for various extra commands that may be present.
  #
  if {![info exists no(callbackCommand)]} then {
    checkForCommand $test_channel callback
  }

  if {![info exists no(libraryCommand)]} then {
    checkForCommand $test_channel library
  }

  if {![info exists no(socketCommand)]} then {
    checkForCommand $test_channel socket
  }

  if {![info exists no(sqlCommand)]} then {
    checkForCommand $test_channel sql
  }

  if {![info exists no(tclCommand)]} then {
    checkForCommand $test_channel tcl
  }

  if {![info exists no(xmlCommand)]} then {
    checkForCommand $test_channel xml
  }

  #
  # NOTE: Check for various features that were added through
  #       the TIP process.
  #
  if {![info exists no(tip127)]} then {
    checkForTip127 $test_channel
  }

  if {![info exists no(tip194)]} then {
    checkForTip194 $test_channel
  }

  if {![info exists no(tip241)]} then {
    checkForTip241 $test_channel
  }

  if {![info exists no(tip285)]} then {
    checkForTip285 $test_channel
  }

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

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

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

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

  if {![info exists no(userInteraction)]} then {
    checkForUserInteraction $test_channel
  }

  #
  # NOTE: Check for network connectivity to our test host (i.e.
  #       the Eagle distribution site).
  #
  if {![info exists no(network)]} then {
    checkForNetwork $test_channel $test_host $test_timeout
  }

  #
  # NOTE: For Eagle, dump the platform information, including
  #       the compile options.
  #
  if {[isEagle]} then {
    #
    # NOTE: Figure out the approximate relative performance
    #       of this machine.
    #
    if {[haveConstraint performance]} then {
      tputs $test_channel [appendArgs \
          "---- checking for baseline BogoCops (commands-per-second)... "]

      if {![info exists test_base_cops]} then {
        #
        # NOTE: The expected performance numbers for all the
        #       performance tests will be calibrated based on
        #       this number (which is based on the measured
        #       performance of the actual machine that was
        #       used to determine those expected performance
        #       numbers).
        #
        set test_base_cops 36000.0
      }

      tputs $test_channel [appendArgs $test_base_cops \n]
      tputs $test_channel [appendArgs \
          "---- checking for current BogoCops (commands-per-second)... "]

      if {![info exists test_cops]} then {
        set test_cops [calculateBogoCops]
      }

      tputs $test_channel [appendArgs $test_cops \n]

      set percent [expr {[calculateRelativePerformance iterations 1] * 100}]

      tputs $test_channel [appendArgs \
          "---- current BogoCops (commands-per-second) is " [formatDecimal \
          [expr {$percent > 100 ? $percent - 100 : $percent}] 2] "% " \
          [expr {$percent > 100 ? "faster than" : "as fast as"}] \
          " the baseline\n"]

      unset percent
    }

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

    set timeStamp [getPlatformInfo timeStamp ""]

    if {[string length $timeStamp] > 0} then {
      #########################################################################
      # MONO: Bug, see: https://bugzilla.novell.com/show_bug.cgi?id=479061
      #########################################################################

      if {[isMono]} then {
        #
        # HACK: We need something to go into the log file.
        #
        set timeStamp [lindex $timeStamp 0]
      } else {
        set timeStamp [clock format [clock scan $timeStamp] -iso -isotimezone]
      }
    } else {
      set timeStamp <none>
    }

    tputs $test_channel [appendArgs "---- build: " \
        [list [getPlatformInfo engine <none>]] " " \
        [list [getPlatformInfo patchLevel <none>]] " " \
        [list [getPlatformInfo tag <none>]] " " \
        [list [getPlatformInfo release <none>]] " " \
        [list [getPlatformInfo text <none>]] " " \
        [list [getPlatformInfo configuration <none>]] " " \
        [list [getPlatformInfo suffix <none>]] " " \
        [list $timeStamp] \n]

    tputs $test_channel [appendArgs "---- os: " \
        [getPlatformInfo os <none>] \n]

    tputs $test_channel [appendArgs "---- globalAssemblyCache: " \
        [getPlatformInfo globalAssemblyCache <none>] \n]

    tputs $test_channel [appendArgs "---- moduleVersionId: " \
        [getPlatformInfo moduleVersionId <none>] \n]

    tputs $test_channel [appendArgs "---- compileOptions: " \
        [formatList [getPlatformInfo compileOptions <none>]] \n]

    tputs $test_channel [appendArgs "---- strongName: " \
        [getPlatformInfo strongName <none>] \n]

    tputs $test_channel [appendArgs "---- certificate: " \
        [getPlatformInfo certificate <none>] \n]

    unset timeStamp
  }

  #
  # NOTE: Show the current test file name, if any.
  #
  tputs $test_channel [appendArgs "---- test file: " \
      [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]

  #
  # NOTE: Show when the tests actually began (now).
  #
  tputs $test_channel [appendArgs "---- tests began at " \
      [clock format [clock seconds]] \n]
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Externals/HtmlHelp/HelpDocs.zip.

cannot compute difference between binary files

Deleted Externals/HtmlHelp/htmlhelp.exe.

cannot compute difference between binary files

Deleted Externals/HtmlHelp/htmlhelpj.exe.

cannot compute difference between binary files

Deleted Externals/MSVCPP/vcredist_x64_2008_SP1.exe.

cannot compute difference between binary files

Deleted Externals/MSVCPP/vcredist_x64_2010_SP1.exe.

cannot compute difference between binary files

Deleted Externals/MSVCPP/vcredist_x86_2008_SP1.exe.

cannot compute difference between binary files

Deleted Externals/MSVCPP/vcredist_x86_2010_SP1.exe.

cannot compute difference between binary files

Deleted Externals/NDoc3/NDoc3 Beta 4.msi.

cannot compute difference between binary files

Deleted Membership/MembershipProvider/Initialize.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
using System.Web.Security;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System;
using System.Data;
using System.Data.SQLite;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Web.Configuration;

namespace SQLiteProvider
{

    public sealed partial class SQLiteMembership : MembershipProvider
    {
        private bool _initialized = false;
        private Object _InitLock = new Object();
        public override void Initialize(string name, NameValueCollection config)
        {
            bool te = _initialized;
            if (te)
                return;
            
            lock (_InitLock)
            {

                if (config == null)
                    throw new ArgumentNullException("config");

                if (name == null || name.Length == 0)
                    name = "SQLiteMembershipProvider";

                if (String.IsNullOrEmpty(config["description"]))
                {
                    config.Remove("description");
                    config.Add("description", "SQLite Membership provider");
                }

                // Initialize the abstract base class.
                base.Initialize(name, config);


                _MaxInvalidPasswordAttempts = ConfigAsInt32(config["maxInvalidPasswordAttempts"], 5);
                _PasswordAttemptWindow = ConfigAsInt32(config["passwordAttemptWindow"], 10);
                _MinRequiredNonAlphanumericCharacters = ConfigAsInt32(config["minRequiredNonAlphanumericCharacters"], 0);
                _MinRequiredPasswordLength = ConfigAsInt32(config["minRequiredPasswordLength"], 7);
                _PasswordStrengthRegularExpression = ConfigAsString(config["passwordStrengthRegularExpression"], "");
                _EnablePasswordReset = ConfigAsBoolean(config["enablePasswordReset"], true);
                _EnablePasswordRetrieval = ConfigAsBoolean(config["enablePasswordRetrieval"], false);
                _RequiresQuestionAndAnswer = ConfigAsBoolean(config["requiresQuestionAndAnswer"], false);
                _RequiresUniqueEmail = ConfigAsBoolean(config["requiresUniqueEmail"], true);


                string temp_format = Convert.ToString(ConfigAsString(config["passwordFormat"], "Hashed"));
                try
                {
                    _PasswordFormat = (MembershipPasswordFormat)Enum.Parse(typeof(MembershipPasswordFormat), temp_format);
                }
                catch
                {
                    throw new ProviderException("Invalid Password Format.");
                }


                _WriteExceptionsToEventLog = ProviderUtility.GetExceptionDesitination(config["writeExceptionsToEventLog"]);
                connectionString = ProviderUtility.GetConnectionString(config["connectionStringName"]);
                ApplicationName = ProviderUtility.GetApplicationName(config["applicationName"]);


                // Get encryption and decryption key information from the configuration.
                Configuration cfg =
                  WebConfigurationManager.OpenWebConfiguration(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
                machineKey = (MachineKeySection)cfg.GetSection("system.web/machineKey");

                if (machineKey.ValidationKey.Contains("AutoGenerate"))
                    if (PasswordFormat != MembershipPasswordFormat.Clear)
                        throw new ProviderException("Hashed or Encrypted passwords are not supported with auto-generated keys.");
                _initialized = true;
            }

        }


        //
        // A helper function to retrieve config values from the configuration file.
        //

        private string ConfigAsString(string configValue, string defaultValue)
        {
            if (String.IsNullOrEmpty(configValue))
                return defaultValue;

            return configValue;
        }

        private bool ConfigAsBoolean(string configValue, bool defaultValue){
            if (String.IsNullOrEmpty(configValue))
                return defaultValue;

            return Convert.ToBoolean(configValue);
        }

        private Int32 ConfigAsInt32(string configValue, int defaultValue)
        {
            if (String.IsNullOrEmpty(configValue))
                return defaultValue;

            return Convert.ToInt32(configValue);
        }

    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































Deleted Membership/MembershipProvider/Membership.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
using System.Web.Security;
using System.Web.Profile;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System;
using System.Data;
using System.Data.SQLite;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Web.Configuration;




namespace SQLiteProvider
{

    public sealed partial class SQLiteMembership : MembershipProvider
    {

        //
        // Global connection string, generated password length, generic exception message, event log info.
        //

        private int newPasswordLength = 8;
        private string eventSource = "SQLiteMembership";

        private string connectionString;
        private bool _WriteExceptionsToEventLog;
        private MachineKeySection machineKey;
        private string _ApplicationName;
        private long _AppID;
        private bool _EnablePasswordReset;
        private bool _EnablePasswordRetrieval;
        private bool _RequiresQuestionAndAnswer;
        private bool _RequiresUniqueEmail;
        private int _MaxInvalidPasswordAttempts;
        private int _PasswordAttemptWindow;
        private MembershipPasswordFormat _PasswordFormat;
     

        public bool WriteExceptionsToEventLog
        {
            get { return _WriteExceptionsToEventLog; }
            set { _WriteExceptionsToEventLog = value; }
        }






        public override bool ChangePassword(string username, string oldPwd, string newPwd)
        {
            if (!ValidateUser(username, oldPwd))
                return false;


            ValidatePasswordEventArgs args =
              new ValidatePasswordEventArgs(username, newPwd, true);

            OnValidatingPassword(args);

            if (args.Cancel)
                if (args.FailureInformation != null)
                    throw args.FailureInformation;
                else
                    throw new MembershipPasswordException("Change password canceled due to new password validation failure.");

            
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.ChangePassword , conn);

             
            cmd.Parameters.Add("$Password", DbType.String).Value = EncodePassword(newPwd);
            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            int rowsAffected = 0;

            try
            {
                conn.Open();

                rowsAffected = cmd.ExecuteNonQuery();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "ChangePassword", WriteExceptionsToEventLog);

            }
            finally
            {
                conn.Close();
            }

            if (rowsAffected > 0)
            {
                return true;
            }

            return false;
        }
        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPwdQuestion, string newPwdAnswer)
        {
            if (!ValidateUser(username, password))
                return false;

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.ChangePasswordQA, conn);

            cmd.Parameters.Add("$Question", DbType.String).Value = newPwdQuestion;
            cmd.Parameters.Add("$Answer", DbType.String).Value = EncodePassword(newPwdAnswer);
            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;


            int rowsAffected = 0;

            try
            {
                conn.Open();

                rowsAffected = cmd.ExecuteNonQuery();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "ChangePasswordQuestionAndAnswer", WriteExceptionsToEventLog);
            }
            finally
            {
                conn.Close();
            }

            if (rowsAffected > 0)
            {
                return true;
            }

            return false;
        }
        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            ValidatePasswordEventArgs args =
              new ValidatePasswordEventArgs(username, password, true);

            OnValidatingPassword(args);

            if (args.Cancel)
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }



            if (RequiresUniqueEmail && GetUserNameByEmail(email) != "")
            {
                status = MembershipCreateStatus.DuplicateEmail;
                return null;
            }

            MembershipUser u = GetUser(username, false);

            if (u == null)
            {
                DateTime createDate = DateTime.Now;

                if (providerUserKey != null)
                {
                    status = MembershipCreateStatus.InvalidProviderUserKey;
                    return null;
                }

                SQLiteConnection conn = new SQLiteConnection(connectionString);
                SQLiteCommand cmd = new SQLiteCommand(MembershipSql.CreateUser, conn);

                cmd.Parameters.Add("$Username", DbType.String).Value = username;
                cmd.Parameters.Add("$Password", DbType.String).Value = EncodePassword(password);
                cmd.Parameters.Add("$Email", DbType.String).Value = email;
                cmd.Parameters.Add("$PasswordQuestion", DbType.String).Value = passwordQuestion;
                cmd.Parameters.Add("$PasswordAnswer", DbType.String).Value = EncodePassword(passwordAnswer);
                cmd.Parameters.Add("$IsApproved", DbType.Boolean).Value = isApproved;
                cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;
                cmd.Parameters.Add("$IsLockedOut", DbType.Boolean).Value = false;

                try
                {
                    conn.Open();

                    int recAdded = cmd.ExecuteNonQuery();

                    if (recAdded > 0)
                    {
                        status = MembershipCreateStatus.Success;
                    }
                    else
                    {
                        status = MembershipCreateStatus.UserRejected;
                    }
                }
                catch (SQLiteException e)
                {
                    try
                    {
                        ProviderUtility.HandleException(e, eventSource, "CreateUser", WriteExceptionsToEventLog);
                    }
                    catch { }


                    status = MembershipCreateStatus.ProviderError;
                }
                finally
                {
                    conn.Close();
                }


                return GetUser(username, false);
            }
            else
            {
                status = MembershipCreateStatus.DuplicateUserName;
            }


            return null;
        }
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.DeleteUser , conn);

            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            int rowsAffected = 0;

            try
            {
                if (deleteAllRelatedData)
                {
                    Roles.RemoveUserFromRoles(username, Roles.GetRolesForUser(username));
                    
                    // Process commands to delete all data for the user in the database.
                }
                conn.Open();
                rowsAffected = cmd.ExecuteNonQuery();


            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "DeleteUser", WriteExceptionsToEventLog);
                    
            }
            finally
            {
                conn.Close();
            }

            if (rowsAffected > 0)
                return true;

            return false;
        }
        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.GetAppUsers, conn);
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;
            cmd.Parameters.Add("$Count", DbType.Int32).Value = pageSize;
            cmd.Parameters.Add("$Skip", DbType.Int32).Value = pageSize * pageIndex;
            MembershipUserCollection users = new MembershipUserCollection();
            SQLiteDataReader r = null;

            int recordCount = 0;

            try
            {
                conn.Open();
                r = cmd.ExecuteReader();
                while (r.Read())
                {
                    users.Add(this.GetUserFromReader(r));
                    recordCount++;
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetAllUsers", WriteExceptionsToEventLog);
                
            }
            finally
            {
                totalRecords = recordCount;
                if (r != null) { r.Close(); }

                conn.Close();
            }
            return users;
        }
        public override int GetNumberOfUsersOnline()
        {
            TimeSpan onlineSpan = new TimeSpan(0, System.Web.Security.Membership.UserIsOnlineTimeWindow, 0);
            DateTime compareTime = DateTime.Now.Subtract(onlineSpan);

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.GetUsersOnline , conn);

            cmd.Parameters.Add("$CompareDate", DbType.DateTime).Value = compareTime;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            int numOnline = 0;

            try
            {
                conn.Open();

                numOnline = (int)cmd.ExecuteScalar();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetNumberOfUsersOnline", WriteExceptionsToEventLog);
                    
            }
            finally
            {
                conn.Close();
            }

            return numOnline;
        }
        public override string GetPassword(string username, string answer)
        {
            if (!EnablePasswordRetrieval)
            {
                throw new ProviderException("Password Retrieval Not Enabled.");
            }

            if (PasswordFormat == MembershipPasswordFormat.Hashed)
            {
                throw new ProviderException("Cannot retrieve Hashed passwords.");
            }

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.GetPassword , conn);

            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            string password = "";
            string passwordAnswer = "";
            SQLiteDataReader reader = null;

            try
            {
                conn.Open();

                reader = cmd.ExecuteReader(CommandBehavior.SingleRow);

                if (reader.HasRows)
                {
                    reader.Read();

                    if (reader.GetBoolean(2))
                        throw new MembershipPasswordException("The supplied user is locked out.");

                    password = reader.GetString(0);
                    passwordAnswer = reader.GetString(1);
                }
                else
                {
                    throw new MembershipPasswordException("The supplied user name is not found.");
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetPassword", WriteExceptionsToEventLog);
                    
            }
            finally
            {
                if (reader != null) { reader.Close(); }
                conn.Close();
            }


            if (RequiresQuestionAndAnswer && !CheckPassword(answer, passwordAnswer))
            {
                UpdateFailureCount(username, "passwordAnswer");

                throw new MembershipPasswordException("Incorrect password answer.");
            }


            if (PasswordFormat == MembershipPasswordFormat.Encrypted)
            {
                password = UnEncodePassword(password);
            }

            return password;
        }
        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);

            string sql = "Select Count(*) from User where Username = $Username AND AppID = $AppID;";
            SQLiteCommand userExistsCmd = new SQLiteCommand(sql,conn );
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.GetUserByName , conn);
            SQLiteCommand updateCmd = new SQLiteCommand(MembershipSql.UpdateUserAccessTimeByName, conn);

            userExistsCmd.Parameters.Add("$Username", DbType.String).Value = username;
            userExistsCmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            updateCmd.Parameters.Add("$Username", DbType.String).Value = username;
            updateCmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;
            
            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            MembershipUser u = null;
            SQLiteDataReader reader = null;

            try
            {
                conn.Open();

                Object o = userExistsCmd.ExecuteScalar();

                long count = (o == DBNull.Value ? 0 : (long)o);


                reader = cmd.ExecuteReader();
                reader.Read();
                if (count != 0)
                {
                    u = GetUserFromReader(reader);

                    if (userIsOnline)
                    {
                        updateCmd.ExecuteNonQuery();
                    }
                }

            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetUser(String, Boolean)", WriteExceptionsToEventLog);

                    
            }
            finally
            {
                if (reader != null) { reader.Close(); }

                conn.Close();
            }

            return u;
        }
        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.GetUserByID , conn);
            SQLiteCommand updateCmd = new SQLiteCommand(MembershipSql.UpdateAccessTimeByID, conn);


            updateCmd.Parameters.Add("$UserID", DbType.Int64).Value = providerUserKey;
            cmd.Parameters.Add("$UserID", DbType.Int64).Value = providerUserKey;

            MembershipUser u = null;
            SQLiteDataReader reader = null;

            try
            {
                conn.Open();

                reader = cmd.ExecuteReader();

                if (reader.HasRows)
                {
                    reader.Read();
                    u = GetUserFromReader(reader);

                    if (userIsOnline)
                    {

                        updateCmd.ExecuteNonQuery();
                    }
                }

            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetUser(Object, Boolean)", WriteExceptionsToEventLog);

                    

            }
            finally
            {
                if (reader != null) { reader.Close(); }

                conn.Close();
            }

            return u;
        }
        private MembershipUser GetUserFromReader(SQLiteDataReader reader)
        {
            object providerUserKey = reader.GetValue(0);
            string username = reader.GetString(1);
            string email = reader.GetString(2);
            string passwordQuestion = (reader.GetValue(3) != DBNull.Value ? reader.GetString(3) : "");
            string comment = (reader.GetValue(4) != DBNull.Value ? reader.GetString(4) : "");
            bool isApproved = reader.GetBoolean(5);
            bool isLockedOut = reader.GetBoolean(6);
            DateTime creationDate = reader.GetDateTime(7);
            DateTime lastLoginDate = (reader.GetValue(8) != DBNull.Value ? reader.GetDateTime(8) : new DateTime() );
            DateTime lastActivityDate = reader.GetDateTime(9);
            DateTime lastPasswordChangedDate = reader.GetDateTime(10);
            DateTime lastLockedOutDate = (reader.GetValue(11) != DBNull.Value ? reader.GetDateTime(11) : new DateTime() );
            
            MembershipUser u = new MembershipUser(this.Name,
                                                  username,
                                                  providerUserKey,
                                                  email,
                                                  passwordQuestion,
                                                  comment,
                                                  isApproved,
                                                  isLockedOut,
                                                  creationDate,
                                                  lastLoginDate,
                                                  lastActivityDate,
                                                  lastPasswordChangedDate,
                                                  lastLockedOutDate);

            return u;
        }
        public override bool UnlockUser(string username)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.UnlockUser , conn);

            
            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            int rowsAffected = 0;

            try
            {
                conn.Open();

                rowsAffected = cmd.ExecuteNonQuery();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "UnlockUser", WriteExceptionsToEventLog);
                    
            }
            finally
            {
                conn.Close();
            }

            if (rowsAffected > 0)
                return true;

            return false;
        }
        public override string GetUserNameByEmail(string email)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.GetUserNameByEmail , conn);

            cmd.Parameters.Add("$Email", DbType.String).Value = email;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            string username = "";

            try
            {
                conn.Open();
                Object o = cmd.ExecuteScalar();
                username = (o == DBNull.Value ? "" : (string)o);
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetUserNameByEmail", WriteExceptionsToEventLog);
                    
            }
            finally
            {
                conn.Close();
            }

            if (username == null)
                username = "";

            return username;
        }
        public override string ResetPassword(string username, string answer)
        {
            if (!EnablePasswordReset)
            {
                throw new NotSupportedException("Password reset is not enabled.");
            }

            if (answer == null && RequiresQuestionAndAnswer)
            {
                UpdateFailureCount(username, "passwordAnswer");

                throw new ProviderException("Password answer required for password reset.");
            }

            string newPassword =
              System.Web.Security.Membership.GeneratePassword(newPasswordLength, MinRequiredNonAlphanumericCharacters);


            ValidatePasswordEventArgs args =
              new ValidatePasswordEventArgs(username, newPassword, true);

            OnValidatingPassword(args);

            if (args.Cancel)
                if (args.FailureInformation != null)
                    throw args.FailureInformation;
                else
                    throw new MembershipPasswordException("Reset password canceled due to password validation failure.");


            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.QueryPasswordReset , conn);
            SQLiteCommand updateCmd = new SQLiteCommand(MembershipSql.ResetPassword, conn);


            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            updateCmd.Parameters.Add("$Password", DbType.String).Value = EncodePassword(newPassword);
            updateCmd.Parameters.Add("$Username", DbType.String).Value = username;
            updateCmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;


            int rowsAffected = 0;
            string passwordAnswer = "";
            SQLiteDataReader reader = null;

            try
            {
                conn.Open();

                reader = cmd.ExecuteReader(CommandBehavior.SingleRow);

                if (reader.HasRows)
                {
                    reader.Read();

                    if (reader.GetBoolean(1))
                        throw new MembershipPasswordException("The supplied user is locked out.");

                    passwordAnswer = reader.GetString(0);
                }
                else
                {
                    throw new MembershipPasswordException("The supplied user name is not found.");
                }

                if (RequiresQuestionAndAnswer && !CheckPassword(answer, passwordAnswer))
                {
                    UpdateFailureCount(username, "passwordAnswer");

                    throw new MembershipPasswordException("Incorrect password answer.");
                }

                rowsAffected = updateCmd.ExecuteNonQuery();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "ResetPassword", WriteExceptionsToEventLog);

            }
            finally
            {
                if (reader != null) { reader.Close(); }
                conn.Close();
            }

            if (rowsAffected > 0)
            {
                return newPassword;
            }
            else
            {
                throw new MembershipPasswordException("User not found, or user is locked out. Password not Reset.");
            }
        }
        public override void UpdateUser(MembershipUser user)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.UpdateUser, conn);

            cmd.Parameters.Add("$Email", DbType.String).Value = user.Email;
            cmd.Parameters.Add("$Comment", DbType.String).Value = user.Comment;
            cmd.Parameters.Add("$IsApproved", DbType.Boolean).Value = user.IsApproved;
            cmd.Parameters.Add("$Username", DbType.String).Value = user.UserName;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;


            try
            {
                conn.Open();

                cmd.ExecuteNonQuery();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "UpdateUser", WriteExceptionsToEventLog);
                
            }
            finally
            {
                conn.Close();
            }
        }
        public override bool ValidateUser(string username, string password)
        {
            bool isValid = false;

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.ValidateUser , conn);
            SQLiteCommand updateCmd = new SQLiteCommand(MembershipSql.UpdateLastLoginDate, conn);


            updateCmd.Parameters.Add("$Username", DbType.String).Value = username;
            updateCmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID; 

            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            SQLiteDataReader reader = null;
            bool isApproved = false;
            string pwd = "";

            try
            {
                conn.Open();

                reader = cmd.ExecuteReader(CommandBehavior.SingleRow);

                if (reader.HasRows)
                {
                    reader.Read();
                    pwd = reader.GetString(0);
                    isApproved = reader.GetBoolean(1);
                }
                else
                {
                    return false;
                }

                reader.Close();

                if (CheckPassword(password, pwd))
                {
                    if (isApproved)
                    {
                        isValid = true;
                        updateCmd.ExecuteNonQuery();
                    }
                }
                else
                {
                    conn.Close();

                    UpdateFailureCount(username, "password");
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "ValidateUser", WriteExceptionsToEventLog);
                    
            }
            finally
            {
                if (reader != null) { reader.Close(); }
                conn.Close();
            }

            return isValid;
        }
        private void UpdateFailureCount(string username, string failureType)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand queryCmd = new SQLiteCommand(MembershipSql.QueryFailureCount , conn);
            SQLiteCommand updateCmd = new SQLiteCommand();
            SQLiteCommand lockoutCmd = new SQLiteCommand(MembershipSql.LockOutUser, conn);


            updateCmd.Connection = conn;
            updateCmd.Parameters.Add("$Username", DbType.String).Value = username;
            updateCmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;
            updateCmd.Parameters.Add("$Count", DbType.Int32);

            queryCmd.Parameters.Add("$Username", DbType.String).Value = username;
            queryCmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;
            
            lockoutCmd.Parameters.Add("$IsLockedOut", DbType.Boolean).Value = true;
            lockoutCmd.Parameters.Add("$Username", DbType.String).Value = username;
            lockoutCmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            SQLiteDataReader reader = null;
            DateTime windowStart = new DateTime();
            int failureCount = 0;

            try
            {
                conn.Open();

                reader = queryCmd.ExecuteReader(CommandBehavior.SingleRow);

                if (reader.HasRows)
                {
                    reader.Read();

                    if (failureType == "password")
                    {
                        failureCount = reader.GetInt32(0);
                        windowStart = reader.GetDateTime(1);
                    }

                    if (failureType == "passwordAnswer")
                    {
                        failureCount = reader.GetInt32(2);
                        windowStart = reader.GetDateTime(3);
                    }
                }

                reader.Close();

                DateTime windowEnd = windowStart.AddMinutes(PasswordAttemptWindow);

                if (failureCount == 0 || DateTime.Now > windowEnd)
                {
                    // First password failure or outside of PasswordAttemptWindow. 
                    // Start a new password failure count from 1 and a new window starting now.

                    if (failureType == "password")
                        updateCmd.CommandText = MembershipSql.UpdatePasswordFailureCountStart;

                    if (failureType == "passwordAnswer")
                        updateCmd.CommandText = MembershipSql.UpdateAnswerFailureCountStart;

                    updateCmd.Parameters["$Count"].Value = 1;

                    if (updateCmd.ExecuteNonQuery() < 0)
                        throw new ProviderException("Unable to update failure count and window start.");
                }
                else
                {
                    if (failureCount++ >= MaxInvalidPasswordAttempts)
                    {

                        if (lockoutCmd.ExecuteNonQuery() < 0)
                            throw new ProviderException("Unable to lock out user.");
                    }
                    else
                    {
                        // Password attempts have not exceeded the failure threshold. Update
                        // the failure counts. Leave the window the same.

                        if (failureType == "password")
                            updateCmd.CommandText = MembershipSql.UpdatePasswordFailureCount;

                        if (failureType == "passwordAnswer")
                            updateCmd.CommandText = MembershipSql.UpdateAnswerFailureCount;

                        updateCmd.Parameters["$Count"].Value = failureCount;


                        if (updateCmd.ExecuteNonQuery() < 0)
                            throw new ProviderException("Unable to update failure count.");
                    }
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "UpdateFailureCount", WriteExceptionsToEventLog);

                    
            }
            finally
            {
                if (reader != null) { reader.Close(); }
                conn.Close();
            }
        }
        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.FindUsersByName, conn);

            MembershipUserCollection users = new MembershipUserCollection();
            SQLiteDataReader r = null;
            cmd.Parameters.Add("$UsernameSearch", DbType.String).Value = usernameToMatch;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;
            cmd.Parameters.Add("$Count", DbType.Int32).Value = pageSize;
            cmd.Parameters.Add("$Skip", DbType.Int32).Value = pageIndex * pageSize;

            int recordCount = 0;

            try
            {
                conn.Open();
                r = cmd.ExecuteReader();
                while (r.Read())
                {
                    users.Add(this.GetUserFromReader(r));
                    recordCount++;
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "FindUsersByName", WriteExceptionsToEventLog);
                
            }
            finally
            {
                totalRecords = recordCount;
                if (r != null) { r.Close(); }

                conn.Close();
            }
            return users;
        }
        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {

            
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(MembershipSql.FindUsersByEmail, conn);

            MembershipUserCollection users = new MembershipUserCollection();
            SQLiteDataReader r = null;
            cmd.Parameters.Add("$EmailSearch", DbType.String).Value = emailToMatch;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;
            cmd.Parameters.Add("$Count", DbType.Int32).Value = pageSize;
            cmd.Parameters.Add("$Skip", DbType.Int32).Value = pageIndex * pageSize;

            int recordCount = 0;

            try
            {
                conn.Open();
                r = cmd.ExecuteReader();
                while (r.Read())
                {
                    users.Add(this.GetUserFromReader(r));
                    recordCount++;
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "FindUsersByEmail", WriteExceptionsToEventLog);
                
            }
            finally
            {
                totalRecords = recordCount;
                if (r != null) { r.Close(); }

                conn.Close();
            }
            return users;


        }



    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Membership/MembershipProvider/MembershipUtility.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
using System.Web.Security;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System;
using System.Data;
using System.Data.SQLite;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Web.Configuration;




namespace SQLiteProvider
{

    public sealed partial class SQLiteMembership : MembershipProvider
    {
        //
        // CheckPassword
        //   Compares password values based on the MembershipPasswordFormat.
        //

        private bool CheckPassword(string password, string dbpassword)
        {
            string pass1 = password;
            string pass2 = dbpassword;

            switch (PasswordFormat)
            {
                case MembershipPasswordFormat.Encrypted:
                    pass2 = UnEncodePassword(dbpassword);
                    break;
                case MembershipPasswordFormat.Hashed:
                    pass1 = EncodePassword(password);
                    break;
                default:
                    break;
            }

            if (pass1 == pass2)
            {
                return true;
            }

            return false;
        }


        //
        // EncodePassword
        //   Encrypts, Hashes, or leaves the password clear based on the PasswordFormat.
        //

        private string EncodePassword(string password)
        {
            string pw = (password == null ? "" : password);
            string encodedPassword = pw;

            switch (PasswordFormat)
            {
                case MembershipPasswordFormat.Clear:
                    break;
                case MembershipPasswordFormat.Encrypted:
                    encodedPassword =
                      Convert.ToBase64String(EncryptPassword(Encoding.Unicode.GetBytes(pw)));
                    break;
                case MembershipPasswordFormat.Hashed:
                    HMACSHA1 hash = new HMACSHA1();
                    hash.Key = HexToByte(machineKey.ValidationKey);
                    encodedPassword =
                      Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(pw)));
                    break;
                default:
                    throw new ProviderException("Unsupported password format.");
            }

            return encodedPassword;
        }


        //
        // UnEncodePassword
        //   Decrypts or leaves the password clear based on the PasswordFormat.
        //

        private string UnEncodePassword(string encodedPassword)
        {
            string password = encodedPassword;

            switch (PasswordFormat)
            {
                case MembershipPasswordFormat.Clear:
                    break;
                case MembershipPasswordFormat.Encrypted:
                    password =
                      Encoding.Unicode.GetString(DecryptPassword(Convert.FromBase64String(password)));
                    break;
                case MembershipPasswordFormat.Hashed:
                    throw new ProviderException("Cannot unencode a hashed password.");
                default:
                    throw new ProviderException("Unsupported password format.");
            }

            return password;
        }

        //
        // HexToByte
        //   Converts a hexadecimal string to a byte array. Used to convert encryption
        // key values from the configuration.
        //

        private byte[] HexToByte(string hexString)
        {
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































Deleted Membership/MembershipProvider/ProviderProperties.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
using System.Web.Security;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System;
using System.Data;
using System.Data.SQLite;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Web.Configuration;




namespace SQLiteProvider
{

    public sealed partial class SQLiteMembership : MembershipProvider
    {
        private Object _appLock = new Object();
        public override string ApplicationName
        {
            get { return _ApplicationName; }
            set
            {
                lock (_appLock)
                {
                    _ApplicationName = value;
                    _AppID = ProviderUtility.GetApplicationID(connectionString, value);
                }
            }
        }
        public override bool EnablePasswordReset
        {
            get { return _EnablePasswordReset; }
        }


        public override bool EnablePasswordRetrieval
        {
            get { return _EnablePasswordRetrieval; }
        }


        public override bool RequiresQuestionAndAnswer
        {
            get { return _RequiresQuestionAndAnswer; }
        }


        public override bool RequiresUniqueEmail
        {
            get { return _RequiresUniqueEmail; }
        }


        public override int MaxInvalidPasswordAttempts
        {
            get { return _MaxInvalidPasswordAttempts; }
        }


        public override int PasswordAttemptWindow
        {
            get { return _PasswordAttemptWindow; }
        }


        public override MembershipPasswordFormat PasswordFormat
        {
            get { return _PasswordFormat; }
        }

        private int _MinRequiredNonAlphanumericCharacters;

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { return _MinRequiredNonAlphanumericCharacters; }
        }

        private int _MinRequiredPasswordLength;

        public override int MinRequiredPasswordLength
        {
            get { return _MinRequiredPasswordLength; }
        }

        private string _PasswordStrengthRegularExpression;

        public override string PasswordStrengthRegularExpression
        {
            get { return _PasswordStrengthRegularExpression; }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted Membership/Properties/AssemblyInfo.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
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SQLiteProvider")]
[assembly: AssemblyCompany("Fresnel Computing")]
[assembly: AssemblyProduct("SQLiteProvider")]
[assembly: AssemblyCopyright("Copyright © Fresnel Computing 2006")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("08669110-651d-458d-8c01-0bf683bbe931")]

// Version information for an assembly consists of the following four values:
//
//      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.77.0")]
[assembly: AssemblyFileVersion("1.0.77.0")]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































Deleted Membership/Properties/Settings.Designer.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
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace SQLiteProvider.Properties {
    
    
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
        
        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
        
        public static Settings Default {
            get {
                return defaultInstance;
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































Deleted Membership/Properties/Settings.settings.
1
2
3
4
5
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
  <Profiles />
  <Settings />
</SettingsFile>
<
<
<
<
<










Deleted Membership/RoleProvider/RoleProvider.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
using System.Web.Security;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System.Collections.Generic;
using System;
using System.Data;
using System.Data.SQLite;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Globalization;



namespace SQLiteProvider
{

    public sealed partial class SQLiteRole : RoleProvider
    {


        private string eventSource = "SQLiteRole";

        private string connectionString;
        private bool _WriteExceptionsToEventLog = false;
        private string _ApplicationName;
        private long _AppID;

        private bool _initialized = false;
        private object _InitLock = new Object();
        private object _AppLock = new Object();

        public bool WriteExceptionsToEventLog
        {
            get { return _WriteExceptionsToEventLog; }
        }

        public override void Initialize(string name, NameValueCollection config)
        {
            bool TempInit = _initialized;
            if (_initialized)
                return;

            lock (_InitLock)
            {

                if (config == null)
                    throw new ArgumentNullException("config");

                if (name == null || name.Length == 0)
                    name = "SQLiteRoleProvider";

                if (String.IsNullOrEmpty(config["description"]))
                {
                    config.Remove("description");
                    config.Add("description", "SQLite Role Privider");
                }

                // Initialize the abstract base class.
                base.Initialize(name, config);
                _WriteExceptionsToEventLog = ProviderUtility.GetExceptionDesitination(config["writeExceptionsToEventLog"]);
                connectionString = ProviderUtility.GetConnectionString(config["connectionStringName"]);
                ApplicationName = ProviderUtility.GetApplicationName(config["applicationName"]);

                _initialized = true;
            }
        }
        public override string ApplicationName
        {
            get { return _ApplicationName; }
            set
            {
                lock (_AppLock)
                {
                    _ApplicationName = value;
                    _AppID = ProviderUtility.GetApplicationID(connectionString, value);
                }
            }
        }
        public override void AddUsersToRoles(string[] usernames, string[] rolenames)
        {
            foreach (string rolename in rolenames)
            {
                if (!RoleExists(rolename))
                {
                    throw new ProviderException("Role name not found.");
                }
            }

            foreach (string username in usernames)
            {
                foreach (string rolename in rolenames)
                {
                    if (IsUserInRole(username, rolename))
                    {
                        throw new ProviderException("User is already in role.");
                    }
                }
            }


            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.AddUserToRole, conn);

            SQLiteParameter userParm = cmd.Parameters.Add("$Username", DbType.String);
            SQLiteParameter roleParm = cmd.Parameters.Add("$Rolename", DbType.String);
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            SQLiteTransaction tran = null;

            try
            {
                conn.Open();
                tran = conn.BeginTransaction();
                cmd.Transaction = tran;

                foreach (string username in usernames)
                {
                    foreach (string rolename in rolenames)
                    {
                        userParm.Value = username;
                        roleParm.Value = rolename;
                        cmd.ExecuteNonQuery();
                    }
                }

                tran.Commit();
            }
            catch (SQLiteException e)
            {
                try
                {
                    tran.Rollback();
                }
                catch { }

                ProviderUtility.HandleException(e, eventSource, "AddUsersToRoles", WriteExceptionsToEventLog);

            }
            finally
            {
                conn.Close();
            }
        }
        public override void CreateRole(string rolename)
        {
            if (RoleExists(rolename))
            {
                throw new ProviderException("Role name already exists.");
            }

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.CreateRole, conn);

            cmd.Parameters.Add("$Rolename", DbType.String).Value = rolename;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            try
            {
                conn.Open();

                cmd.ExecuteNonQuery();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "CreateRole", WriteExceptionsToEventLog);

            }
            finally
            {
                conn.Close();
            }
        }
        public override bool DeleteRole(string rolename, bool throwOnPopulatedRole)
        {
            if (!RoleExists(rolename))
            {
                throw new ProviderException("Role does not exist.");
            }

            if (throwOnPopulatedRole && GetUsersInRole(rolename).Length > 0)
            {
                throw new ProviderException("Cannot delete a populated role.");
            }

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.DeleteRole, conn);

            cmd.Parameters.Add("$Rolename", DbType.String).Value = rolename;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;


            SQLiteCommand cmd2 = new SQLiteCommand(RoleSql.DeleteRoleFromMap, conn);

            cmd2.Parameters.Add("$Rolename", DbType.String).Value = rolename;
            cmd2.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            SQLiteTransaction tran = null;

            try
            {
                conn.Open();
                tran = conn.BeginTransaction();
                cmd.Transaction = tran;
                cmd2.Transaction = tran;

                cmd2.ExecuteNonQuery();
                cmd.ExecuteNonQuery();

                tran.Commit();
            }
            catch (SQLiteException e)
            {
                try
                {
                    tran.Rollback();
                }
                catch { }

                ProviderUtility.HandleException(e, eventSource, "DeleteRole", WriteExceptionsToEventLog);
            }
            finally
            {
                conn.Close();
            }

            return true;
        }
        public override string[] GetAllRoles()
        {
            List<String> names = new List<string>();
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.GetAllRoles, conn);

            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            SQLiteDataReader reader = null;

            try
            {
                conn.Open();

                reader = cmd.ExecuteReader();

                while (reader.Read())
                {
                    names.Add(reader.GetString(0));
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetAllRoles", WriteExceptionsToEventLog);
            }
            finally
            {
                if (reader != null) { reader.Close(); }
                conn.Close();
            }


            return names.ToArray();
        }
        public override string[] GetRolesForUser(string username)
        {
            List<string> roles = new List<string>();

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.GetRolesForUser, conn);

            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            SQLiteDataReader reader = null;

            try
            {
                conn.Open();

                reader = cmd.ExecuteReader();

                while (reader.Read())
                {
                    roles.Add(reader.GetString(0));
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetRolesForUser", WriteExceptionsToEventLog);
            }
            finally
            {
                if (reader != null) { reader.Close(); }
                conn.Close();
            }


            return roles.ToArray();
        }
        public override string[] GetUsersInRole(string rolename)
        {
            List<String> users = new List<string>();

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.GetUsersInRole, conn);

            cmd.Parameters.Add("$Rolename", DbType.String).Value = rolename;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            SQLiteDataReader reader = null;

            try
            {
                conn.Open();

                reader = cmd.ExecuteReader();

                while (reader.Read())
                {
                    users.Add(reader.GetString(0));
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "GetUsersInRole", WriteExceptionsToEventLog);
            }
            finally
            {
                if (reader != null) { reader.Close(); }
                conn.Close();
            }
            return users.ToArray();
        }
        public override bool IsUserInRole(string username, string rolename)
        {
            long count = 0;

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.IsUserInRole, conn);

            cmd.Parameters.Add("$Username", DbType.String).Value = username;
            cmd.Parameters.Add("$Rolename", DbType.String).Value = rolename;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            try
            {
                conn.Open();
                count = (long)cmd.ExecuteScalar();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "IsUserInRole", WriteExceptionsToEventLog);
            }
            finally
            {
                conn.Close();
            }

            return (count != 0);
        }
        public override void RemoveUsersFromRoles(string[] usernames, string[] rolenames)
        {
            foreach (string rolename in rolenames)
            {
                if (!RoleExists(rolename))
                {
                    throw new ProviderException("Role name not found.");
                }
            }

            foreach (string username in usernames)
            {
                foreach (string rolename in rolenames)
                {
                    if (!IsUserInRole(username, rolename))
                    {
                        throw new ProviderException("User is not in role.");
                    }
                }
            }


            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.DeleteUserFromRole, conn);

            SQLiteParameter userParm = cmd.Parameters.Add("$Username", DbType.String);
            SQLiteParameter roleParm = cmd.Parameters.Add("$Rolename", DbType.String);
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            SQLiteTransaction tran = null;

            try
            {
                conn.Open();
                tran = conn.BeginTransaction();
                cmd.Transaction = tran;

                foreach (string username in usernames)
                {
                    foreach (string rolename in rolenames)
                    {
                        userParm.Value = username;
                        roleParm.Value = rolename;
                        cmd.ExecuteNonQuery();
                    }
                }

                tran.Commit();
            }
            catch (SQLiteException e)
            {
                try
                {
                    tran.Rollback();
                }
                catch { }
                ProviderUtility.HandleException(e, eventSource, "RemoveUsersFromRoles", WriteExceptionsToEventLog);

            }
            finally
            {
                conn.Close();
            }
        }
        public override bool RoleExists(string rolename)
        {
            long count = 0;

            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.RoleExists, conn);

            cmd.Parameters.Add("$Rolename", DbType.String).Value = rolename;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            try
            {
                conn.Open();
                count = (long)cmd.ExecuteScalar();
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "RoleExists", WriteExceptionsToEventLog);


            }
            finally
            {
                conn.Close();
            }

            return (count != 0);
        }
        public override string[] FindUsersInRole(string rolename, string usernameToMatch)
        {
            SQLiteConnection conn = new SQLiteConnection(connectionString);
            SQLiteCommand cmd = new SQLiteCommand(RoleSql.FindUsersInRole, conn);
            cmd.Parameters.Add("$Username", DbType.String).Value = usernameToMatch;
            cmd.Parameters.Add("$Rolename", DbType.String).Value = rolename;
            cmd.Parameters.Add("$AppID", DbType.Int64).Value = _AppID;

            List<String> users = new List<string>();
            SQLiteDataReader reader = null;

            try
            {
                conn.Open();

                reader = cmd.ExecuteReader();

                while (reader.Read())
                {
                    users.Add(reader.GetString(0));
                }
            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, eventSource, "FindUsersInRole", WriteExceptionsToEventLog);                

            }
            finally
            {
                if (reader != null) { reader.Close(); }

                conn.Close();
            }

            return users.ToArray();
        }

    }
}


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Membership/SQLiteProvider.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLiteProvider.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{1B7C6ACE-35AA-481C-9CF6-56B702E3E043}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>SQLiteProvider</RootNamespace>
    <AssemblyName>SQLiteProvider</AssemblyName>
    <OldToolsVersion>2.0</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Data" />
    <Reference Include="System.Data.SQLite" />
    <Reference Include="System.Web" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Profile\SQLiteProfile.cs" />
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
      <DependentUpon>Settings.settings</DependentUpon>
    </Compile>
    <Compile Include="SiteMap\DynamicSiteMap.cs" />
    <Compile Include="SiteMap\StaticSiteMap.cs" />
    <Compile Include="Sql\ApplicationSql.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>ApplicationSql.resx</DependentUpon>
    </Compile>
    <Compile Include="Sql\MembershipSql.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>MembershipSql.resx</DependentUpon>
    </Compile>
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Sql\RoleSql.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>RoleSql.resx</DependentUpon>
    </Compile>
    <Compile Include="MembershipProvider\Membership.cs" />
    <Compile Include="MembershipProvider\Initialize.cs" />
    <Compile Include="MembershipProvider\ProviderProperties.cs" />
    <Compile Include="MembershipProvider\MembershipUtility.cs" />
    <Compile Include="Sql\SiteMapSql.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>SiteMapSql.resx</DependentUpon>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </Compile>
    <Compile Include="Utiliy\ProviderUtility.cs" />
    <Compile Include="RoleProvider\RoleProvider.cs" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Sql\ApplicationSql.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>ApplicationSql.Designer.cs</LastGenOutput>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </EmbeddedResource>
    <EmbeddedResource Include="Sql\MembershipSql.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>MembershipSql.Designer.cs</LastGenOutput>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </EmbeddedResource>
    <EmbeddedResource Include="Sql\RoleSql.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>RoleSql.Designer.cs</LastGenOutput>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </EmbeddedResource>
    <EmbeddedResource Include="Sql\SiteMapSql.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>SiteMapSql.Designer.cs</LastGenOutput>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <None Include="Sql\Schema.sql" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="TODO.txt" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































Deleted Membership/SQLiteProvider.2010.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLiteProvider.2010.csproj -
 *
 * 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>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.30319</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{1B7C6ACE-35AA-481C-9CF6-56B702E3E043}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>SQLiteProvider</RootNamespace>
    <AssemblyName>SQLiteProvider</AssemblyName>
    <OldToolsVersion>3.5</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <ConfigurationYear>2010</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Data" />
    <Reference Include="System.Data.SQLite" />
    <Reference Include="System.Web" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Profile\SQLiteProfile.cs" />
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
      <DependentUpon>Settings.settings</DependentUpon>
    </Compile>
    <Compile Include="SiteMap\DynamicSiteMap.cs" />
    <Compile Include="SiteMap\StaticSiteMap.cs" />
    <Compile Include="Sql\ApplicationSql.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>ApplicationSql.resx</DependentUpon>
    </Compile>
    <Compile Include="Sql\MembershipSql.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>MembershipSql.resx</DependentUpon>
    </Compile>
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Sql\RoleSql.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>RoleSql.resx</DependentUpon>
    </Compile>
    <Compile Include="MembershipProvider\Membership.cs" />
    <Compile Include="MembershipProvider\Initialize.cs" />
    <Compile Include="MembershipProvider\ProviderProperties.cs" />
    <Compile Include="MembershipProvider\MembershipUtility.cs" />
    <Compile Include="Sql\SiteMapSql.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>SiteMapSql.resx</DependentUpon>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </Compile>
    <Compile Include="Utiliy\ProviderUtility.cs" />
    <Compile Include="RoleProvider\RoleProvider.cs" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Sql\ApplicationSql.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>ApplicationSql.Designer.cs</LastGenOutput>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </EmbeddedResource>
    <EmbeddedResource Include="Sql\MembershipSql.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>MembershipSql.Designer.cs</LastGenOutput>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </EmbeddedResource>
    <EmbeddedResource Include="Sql\RoleSql.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>RoleSql.Designer.cs</LastGenOutput>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </EmbeddedResource>
    <EmbeddedResource Include="Sql\SiteMapSql.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>SiteMapSql.Designer.cs</LastGenOutput>
      <CustomToolNamespace>SQLiteProvider</CustomToolNamespace>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <None Include="Sql\Schema.sql" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="TODO.txt" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































Deleted Membership/Sql/ApplicationSql.Designer.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
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace SQLiteProvider {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class ApplicationSql {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal ApplicationSql() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SQLiteProvider.Sql.ApplicationSql", typeof(ApplicationSql).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select Count(*) from Application where ApplicationName = $ApplicationName.
        /// </summary>
        internal static string AppExists {
            get {
                return ResourceManager.GetString("AppExists", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select AppID from Application where ApplicationName = $ApplicationName;.
        /// </summary>
        internal static string GetAppID {
            get {
                return ResourceManager.GetString("GetAppID", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Insert into Application (ApplicationName) values ($ApplicationName).
        /// </summary>
        internal static string InsertApp {
            get {
                return ResourceManager.GetString("InsertApp", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































Deleted Membership/Sql/ApplicationSql.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="AppExists" xml:space="preserve">
    <value>Select Count(*) from Application where ApplicationName = $ApplicationName</value>
  </data>
  <data name="GetAppID" xml:space="preserve">
    <value>Select AppID from Application where ApplicationName = $ApplicationName;</value>
  </data>
  <data name="InsertApp" xml:space="preserve">
    <value>Insert into Application (ApplicationName) values ($ApplicationName)</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































Deleted Membership/Sql/MembershipSql.Designer.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
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace SQLiteProvider {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class MembershipSql {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal MembershipSql() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SQLiteProvider.Sql.MembershipSql", typeof(MembershipSql).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User SET Password = $Password, LastPasswordChangedDate = datetime(&apos;now&apos;,&apos;utc&apos;) WHERE Username = $Username AND AppID = $AppID;.
        /// </summary>
        internal static string ChangePassword {
            get {
                return ResourceManager.GetString("ChangePassword", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User SET PasswordQuestion = $Question, PasswordAnswer = $Answer WHERE Username = $Username AND AppID = $AppID;.
        /// </summary>
        internal static string ChangePasswordQA {
            get {
                return ResourceManager.GetString("ChangePasswordQA", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to INSERT INTO User
        ///(
        ///	Username,
        ///	Password,
        ///	Email,
        ///	PasswordQuestion,
        ///	PasswordAnswer,
        ///	IsApproved,
        ///	Comment,
        ///	CreationDate,
        ///	LastPasswordChangedDate,
        ///	LastActivityDate,
        ///	AppID,
        ///	IsLockedOut,
        ///	LastLockedOutDate,
        ///	FailedPasswordAttemptCount,
        ///	FailedPasswordAttemptWindowStart,
        ///	FailedPasswordAnswerAttemptCount,
        ///	FailedPasswordAnswerAttemptWindowStart
        ///)
        ///Values(
        ///	$Username,
        ///	$Password,
        ///	$Email,
        ///	$PasswordQuestion,
        ///	$PasswordAnswer,
        ///	$IsApproved,
        ///	&apos;&apos;,
        ///	datetime(&apos;now&apos;,&apos;utc&apos;),
        ///	datetime( [rest of string was truncated]&quot;;.
        /// </summary>
        internal static string CreateUser {
            get {
                return ResourceManager.GetString("CreateUser", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to DELETE FROM User WHERE Username = $Username AND AppID = $AppID;.
        /// </summary>
        internal static string DeleteUser {
            get {
                return ResourceManager.GetString("DeleteUser", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT UserID, Username, Email, PasswordQuestion,
        ///Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate,
        ///LastActivityDate, LastPasswordChangedDate, LastLockedOutDate 
        ///FROM User 
        ///WHERE Email LIKE $EmailSearch AND AppID = $AppID 
        ///ORDER BY Username Asc
        ///LIMIT $Count, $Skip .
        /// </summary>
        internal static string FindUsersByEmail {
            get {
                return ResourceManager.GetString("FindUsersByEmail", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT UserID, Username, Email, PasswordQuestion,
        ///Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate,
        ///LastActivityDate, LastPasswordChangedDate, LastLockedOutDate 
        ///FROM User 
        ///WHERE Username LIKE $UsernameSearch AND AppID = $AppID
        ///ORDER BY Username Asc
        ///LIMIT $Count, $Skip .
        /// </summary>
        internal static string FindUsersByName {
            get {
                return ResourceManager.GetString("FindUsersByName", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT 
        ///	UserID, Username, Email, PasswordQuestion, Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate, LastActivityDate, LastPasswordChangedDate, LastLockedOutDate 
        ///FROM 
        ///	User 
        ///WHERE 
        ///	AppID = $AppID 
        ///ORDER BY 
        ///	Username Asc
        ///LIMIT
        ///	$Skip, $Count.
        /// </summary>
        internal static string GetAppUsers {
            get {
                return ResourceManager.GetString("GetAppUsers", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT Password, PasswordAnswer, IsLockedOut FROM User WHERE Username = $Username AND AppID = $AppID;.
        /// </summary>
        internal static string GetPassword {
            get {
                return ResourceManager.GetString("GetPassword", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT UserID, Username, Email, PasswordQuestion,
        ///Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate,
        ///LastActivityDate, LastPasswordChangedDate, LastLockedOutDate
        ///FROM User WHERE UserID = $UserID;.
        /// </summary>
        internal static string GetUserByID {
            get {
                return ResourceManager.GetString("GetUserByID", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT 
        ///	UserID, Username, Email, PasswordQuestion, Comment, 
        ///	IsApproved, IsLockedOut, CreationDate, LastLoginDate, 
        ///	LastActivityDate, LastPasswordChangedDate, LastLockedOutDate 
        ///FROM 
        ///	User 
        ///WHERE 
        ///	Username = $Username AND AppID = $AppID;.
        /// </summary>
        internal static string GetUserByName {
            get {
                return ResourceManager.GetString("GetUserByName", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT Username  FROM User WHERE Email = $Email AND AppID = $AppID;.
        /// </summary>
        internal static string GetUserNameByEmail {
            get {
                return ResourceManager.GetString("GetUserNameByEmail", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT Count(*) FROM User WHERE LastActivityDate &gt; $CompareDate AND AppID = $AppID;.
        /// </summary>
        internal static string GetUsersOnline {
            get {
                return ResourceManager.GetString("GetUsersOnline", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User
        ///SET IsLockedOut = $IsLockedOut, LastLockedOutDate = datetime(&apos;now&apos;,&apos;utc&apos;)
        ///WHERE Username = $Username AND AppID = $AppID.
        /// </summary>
        internal static string LockOutUser {
            get {
                return ResourceManager.GetString("LockOutUser", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT FailedPasswordAttemptCount, 
        ///FailedPasswordAttemptWindowStart, 
        ///FailedPasswordAnswerAttemptCount, 
        ///FailedPasswordAnswerAttemptWindowStart 
        ///FROM User 
        ///WHERE Username = $Username AND AppID = $AppID.
        /// </summary>
        internal static string QueryFailureCount {
            get {
                return ResourceManager.GetString("QueryFailureCount", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT PasswordAnswer, IsLockedOut FROM User WHERE Username = $Username AND AppID = $AppID;.
        /// </summary>
        internal static string QueryPasswordReset {
            get {
                return ResourceManager.GetString("QueryPasswordReset", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User SET Password = $Password, LastPasswordChangedDate = datetime(&apos;now&apos;,&apos;utc&apos;) WHERE Username = $Username AND AppID = $AppID AND IsLockedOut = 0.
        /// </summary>
        internal static string ResetPassword {
            get {
                return ResourceManager.GetString("ResetPassword", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User 
        ///SET IsLockedOut = 0, LastLockedOutDate = datetime(&apos;now&apos;,&apos;utc&apos;) 
        ///WHERE Username = $Username AND AppID = $AppID;.
        /// </summary>
        internal static string UnlockUser {
            get {
                return ResourceManager.GetString("UnlockUser", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User 
        ///SET LastActivityDate = datetime(&apos;now&apos;,&apos;utc&apos;) 
        ///WHERE UserID = $UserID;.
        /// </summary>
        internal static string UpdateAccessTimeByID {
            get {
                return ResourceManager.GetString("UpdateAccessTimeByID", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User 
        ///SET FailedPasswordAnswerAttemptCount = $Count
        ///WHERE Username = $Username AND AppID = $AppID.
        /// </summary>
        internal static string UpdateAnswerFailureCount {
            get {
                return ResourceManager.GetString("UpdateAnswerFailureCount", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User 
        ///SET FailedPasswordAnswerAttemptCount = $Count, 
        ///FailedPasswordAnswerAttemptWindowStart = datetime(&apos;now&apos;,&apos;utc&apos;) 
        ///WHERE Username = $Username AND AppID = $AppID.
        /// </summary>
        internal static string UpdateAnswerFailureCountStart {
            get {
                return ResourceManager.GetString("UpdateAnswerFailureCountStart", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User SET LastLoginDate = datetime(&apos;now&apos;,&apos;utc&apos;) WHERE Username = $Username AND AppID = $AppID.
        /// </summary>
        internal static string UpdateLastLoginDate {
            get {
                return ResourceManager.GetString("UpdateLastLoginDate", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User 
        ///SET FailedPasswordAttemptCount = $Count
        ///WHERE Username = $Username AND AppID = $AppID.
        /// </summary>
        internal static string UpdatePasswordFailureCount {
            get {
                return ResourceManager.GetString("UpdatePasswordFailureCount", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User 
        ///SET FailedPasswordAttemptCount = $Count, 
        ///FailedPasswordAttemptWindowStart = datetime(&apos;now&apos;,&apos;utc&apos;) 
        ///WHERE Username = $Username AND AppID = $AppID.
        /// </summary>
        internal static string UpdatePasswordFailureCountStart {
            get {
                return ResourceManager.GetString("UpdatePasswordFailureCountStart", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User
        ///SET Email = $Email, Comment = $Comment,
        ///IsApproved = $IsApproved
        ///WHERE Username = $Username AND AppID = $AppID.
        /// </summary>
        internal static string UpdateUser {
            get {
                return ResourceManager.GetString("UpdateUser", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to UPDATE User SET LastActivityDate = datetime(&apos;now&apos;,&apos;utc&apos;) WHERE Username = $Username AND AppID = $AppID;.
        /// </summary>
        internal static string UpdateUserAccessTimeByName {
            get {
                return ResourceManager.GetString("UpdateUserAccessTimeByName", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT Password, IsApproved FROM User WHERE Username = $Username AND AppID = $AppID AND IsLockedOut = 0.
        /// </summary>
        internal static string ValidateUser {
            get {
                return ResourceManager.GetString("ValidateUser", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































Deleted Membership/Sql/MembershipSql.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="ChangePassword" xml:space="preserve">
    <value>UPDATE User SET Password = $Password, LastPasswordChangedDate = datetime('now','utc') WHERE Username = $Username AND AppID = $AppID;</value>
  </data>
  <data name="ChangePasswordQA" xml:space="preserve">
    <value>UPDATE User SET PasswordQuestion = $Question, PasswordAnswer = $Answer WHERE Username = $Username AND AppID = $AppID;</value>
  </data>
  <data name="CreateUser" xml:space="preserve">
    <value>INSERT INTO User
(
	Username,
	Password,
	Email,
	PasswordQuestion,
	PasswordAnswer,
	IsApproved,
	Comment,
	CreationDate,
	LastPasswordChangedDate,
	LastActivityDate,
	AppID,
	IsLockedOut,
	LastLockedOutDate,
	FailedPasswordAttemptCount,
	FailedPasswordAttemptWindowStart,
	FailedPasswordAnswerAttemptCount,
	FailedPasswordAnswerAttemptWindowStart
)
Values(
	$Username,
	$Password,
	$Email,
	$PasswordQuestion,
	$PasswordAnswer,
	$IsApproved,
	'',
	datetime('now','utc'),
	datetime('now','utc'),
	datetime('now','utc'),
	$AppID,
	$IsLockedOut,
	datetime('now','utc'),
	0,
	datetime('now','utc'),
	0,
	datetime('now','utc')
);</value>
  </data>
  <data name="DeleteUser" xml:space="preserve">
    <value>DELETE FROM User WHERE Username = $Username AND AppID = $AppID;</value>
  </data>
  <data name="FindUsersByEmail" xml:space="preserve">
    <value>SELECT UserID, Username, Email, PasswordQuestion,
Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate,
LastActivityDate, LastPasswordChangedDate, LastLockedOutDate 
FROM User 
WHERE Email LIKE $EmailSearch AND AppID = $AppID 
ORDER BY Username Asc
LIMIT $Count, $Skip </value>
  </data>
  <data name="FindUsersByName" xml:space="preserve">
    <value>SELECT UserID, Username, Email, PasswordQuestion,
Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate,
LastActivityDate, LastPasswordChangedDate, LastLockedOutDate 
FROM User 
WHERE Username LIKE $UsernameSearch AND AppID = $AppID
ORDER BY Username Asc
LIMIT $Count, $Skip </value>
  </data>
  <data name="GetAppUsers" xml:space="preserve">
    <value>SELECT 
	UserID, Username, Email, PasswordQuestion, Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate, LastActivityDate, LastPasswordChangedDate, LastLockedOutDate 
FROM 
	User 
WHERE 
	AppID = $AppID 
ORDER BY 
	Username Asc
LIMIT
	$Skip, $Count</value>
  </data>
  <data name="GetPassword" xml:space="preserve">
    <value>SELECT Password, PasswordAnswer, IsLockedOut FROM User WHERE Username = $Username AND AppID = $AppID;</value>
  </data>
  <data name="GetUserByID" xml:space="preserve">
    <value>SELECT UserID, Username, Email, PasswordQuestion,
Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate,
LastActivityDate, LastPasswordChangedDate, LastLockedOutDate
FROM User WHERE UserID = $UserID;</value>
  </data>
  <data name="GetUserByName" xml:space="preserve">
    <value>SELECT 
	UserID, Username, Email, PasswordQuestion, Comment, 
	IsApproved, IsLockedOut, CreationDate, LastLoginDate, 
	LastActivityDate, LastPasswordChangedDate, LastLockedOutDate 
FROM 
	User 
WHERE 
	Username = $Username AND AppID = $AppID;</value>
  </data>
  <data name="GetUserNameByEmail" xml:space="preserve">
    <value>SELECT Username  FROM User WHERE Email = $Email AND AppID = $AppID;</value>
  </data>
  <data name="GetUsersOnline" xml:space="preserve">
    <value>SELECT Count(*) FROM User WHERE LastActivityDate &gt; $CompareDate AND AppID = $AppID;</value>
  </data>
  <data name="LockOutUser" xml:space="preserve">
    <value>UPDATE User
SET IsLockedOut = $IsLockedOut, LastLockedOutDate = datetime('now','utc')
WHERE Username = $Username AND AppID = $AppID</value>
  </data>
  <data name="QueryFailureCount" xml:space="preserve">
    <value>SELECT FailedPasswordAttemptCount, 
FailedPasswordAttemptWindowStart, 
FailedPasswordAnswerAttemptCount, 
FailedPasswordAnswerAttemptWindowStart 
FROM User 
WHERE Username = $Username AND AppID = $AppID</value>
  </data>
  <data name="QueryPasswordReset" xml:space="preserve">
    <value>SELECT PasswordAnswer, IsLockedOut FROM User WHERE Username = $Username AND AppID = $AppID;</value>
  </data>
  <data name="ResetPassword" xml:space="preserve">
    <value>UPDATE User SET Password = $Password, LastPasswordChangedDate = datetime('now','utc') WHERE Username = $Username AND AppID = $AppID AND IsLockedOut = 0</value>
  </data>
  <data name="UnlockUser" xml:space="preserve">
    <value>UPDATE User 
SET IsLockedOut = 0, LastLockedOutDate = datetime('now','utc') 
WHERE Username = $Username AND AppID = $AppID;</value>
  </data>
  <data name="UpdateAccessTimeByID" xml:space="preserve">
    <value>UPDATE User 
SET LastActivityDate = datetime('now','utc') 
WHERE UserID = $UserID;</value>
  </data>
  <data name="UpdateAnswerFailureCount" xml:space="preserve">
    <value>UPDATE User 
SET FailedPasswordAnswerAttemptCount = $Count
WHERE Username = $Username AND AppID = $AppID</value>
  </data>
  <data name="UpdateAnswerFailureCountStart" xml:space="preserve">
    <value>UPDATE User 
SET FailedPasswordAnswerAttemptCount = $Count, 
FailedPasswordAnswerAttemptWindowStart = datetime('now','utc') 
WHERE Username = $Username AND AppID = $AppID</value>
  </data>
  <data name="UpdateLastLoginDate" xml:space="preserve">
    <value>UPDATE User SET LastLoginDate = datetime('now','utc') WHERE Username = $Username AND AppID = $AppID</value>
  </data>
  <data name="UpdatePasswordFailureCount" xml:space="preserve">
    <value>UPDATE User 
SET FailedPasswordAttemptCount = $Count
WHERE Username = $Username AND AppID = $AppID</value>
  </data>
  <data name="UpdatePasswordFailureCountStart" xml:space="preserve">
    <value>UPDATE User 
SET FailedPasswordAttemptCount = $Count, 
FailedPasswordAttemptWindowStart = datetime('now','utc') 
WHERE Username = $Username AND AppID = $AppID</value>
  </data>
  <data name="UpdateUser" xml:space="preserve">
    <value>UPDATE User
SET Email = $Email, Comment = $Comment,
IsApproved = $IsApproved
WHERE Username = $Username AND AppID = $AppID</value>
  </data>
  <data name="UpdateUserAccessTimeByName" xml:space="preserve">
    <value>UPDATE User SET LastActivityDate = datetime('now','utc') WHERE Username = $Username AND AppID = $AppID;</value>
  </data>
  <data name="ValidateUser" xml:space="preserve">
    <value>SELECT Password, IsApproved FROM User WHERE Username = $Username AND AppID = $AppID AND IsLockedOut = 0</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































Deleted Membership/Sql/RoleSql.Designer.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
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace SQLiteProvider {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class RoleSql {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal RoleSql() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SQLiteProvider.Sql.RoleSql", typeof(RoleSql).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Insert into UserRoleMap
        ///	(UserID, RoleID, AppID) values
        ///	(
        ///		(Select UserID from User where Username = $Username and AppID = $AppID),
        ///		(Select RoleID from Role where Rolename = $Rolename and AppID = $AppID),
        ///		$AppID
        ///	);.
        /// </summary>
        internal static string AddUserToRole {
            get {
                return ResourceManager.GetString("AddUserToRole", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Insert into Role (Rolename, AppID) values ($Rolename, $AppID);.
        /// </summary>
        internal static string CreateRole {
            get {
                return ResourceManager.GetString("CreateRole", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to DELETE FROM Role WHERE Rolename = $Rolename AND AppID = $AppID.
        /// </summary>
        internal static string DeleteRole {
            get {
                return ResourceManager.GetString("DeleteRole", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to DELETE FROM UserRoleMap WHERE RoleID = (Select RoleID from Role where Rolename = $Rolename  AND AppID = $AppID) AND AppID = $AppID.
        /// </summary>
        internal static string DeleteRoleFromMap {
            get {
                return ResourceManager.GetString("DeleteRoleFromMap", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Delete From UserRoleMap
        ///Where
        ///UserID = (Select UserID from User where Username = $Username and AppID = $AppID)
        ///AND
        ///RoleID = (Select RoleID from Role Where Rolename = $Rolename AND AppID = $AppID);
        ///.
        /// </summary>
        internal static string DeleteUserFromRole {
            get {
                return ResourceManager.GetString("DeleteUserFromRole", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select User.Username from User
        ///Inner Join UserRoleMap on User.UserID = UserRoleMap.UserID
        ///Inner Join Role on UserRoleMap.RoleID = Role.RoleID
        ///Where Role.Rolename = $RoleName and Role.AppID = $AppID and User.Username Like $Username;.
        /// </summary>
        internal static string FindUsersInRole {
            get {
                return ResourceManager.GetString("FindUsersInRole", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT Rolename FROM Role WHERE AppID = $AppID.
        /// </summary>
        internal static string GetAllRoles {
            get {
                return ResourceManager.GetString("GetAllRoles", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select Rolename from Role
        ///Inner Join UserRoleMap On Role.RoleID = UserRoleMap.RoleID and Role.AppID = UserRoleMap.AppID
        ///Inner Join User On User.UserID = UserRoleMap.UserID and User.AppID = UserRoleMap.AppID
        ///Where User.Username = $Username and User.AppID = $AppID;.
        /// </summary>
        internal static string GetRolesForUser {
            get {
                return ResourceManager.GetString("GetRolesForUser", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select User.Username from User
        ///Inner Join UserRoleMap on User.UserID = UserRoleMap.UserID
        ///Inner Join Role on UserRoleMap.RoleID = Role.RoleID
        ///Where Role.Rolename = $RoleName and Role.AppID = $AppID;
        ///.
        /// </summary>
        internal static string GetUsersInRole {
            get {
                return ResourceManager.GetString("GetUsersInRole", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select Count(*) from User
        ///Inner Join UserRoleMap on User.UserID = UserRoleMap.UserID
        ///Inner Join Role on UserRoleMap.RoleID = Role.RoleID
        ///Where Role.Rolename = $Rolename  and User.Username=$Username and Role.AppID = $AppID;.
        /// </summary>
        internal static string IsUserInRole {
            get {
                return ResourceManager.GetString("IsUserInRole", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SELECT COUNT(*) FROM Role WHERE Rolename = $Rolename AND AppID = $AppID;.
        /// </summary>
        internal static string RoleExists {
            get {
                return ResourceManager.GetString("RoleExists", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































Deleted Membership/Sql/RoleSql.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="AddUserToRole" xml:space="preserve">
    <value>Insert into UserRoleMap
	(UserID, RoleID, AppID) values
	(
		(Select UserID from User where Username = $Username and AppID = $AppID),
		(Select RoleID from Role where Rolename = $Rolename and AppID = $AppID),
		$AppID
	);</value>
  </data>
  <data name="CreateRole" xml:space="preserve">
    <value>Insert into Role (Rolename, AppID) values ($Rolename, $AppID);</value>
  </data>
  <data name="DeleteRole" xml:space="preserve">
    <value>DELETE FROM Role WHERE Rolename = $Rolename AND AppID = $AppID</value>
  </data>
  <data name="DeleteRoleFromMap" xml:space="preserve">
    <value>DELETE FROM UserRoleMap WHERE RoleID = (Select RoleID from Role where Rolename = $Rolename  AND AppID = $AppID) AND AppID = $AppID</value>
  </data>
  <data name="DeleteUserFromRole" xml:space="preserve">
    <value>Delete From UserRoleMap
Where
UserID = (Select UserID from User where Username = $Username and AppID = $AppID)
AND
RoleID = (Select RoleID from Role Where Rolename = $Rolename AND AppID = $AppID);
</value>
  </data>
  <data name="FindUsersInRole" xml:space="preserve">
    <value>Select User.Username from User
Inner Join UserRoleMap on User.UserID = UserRoleMap.UserID
Inner Join Role on UserRoleMap.RoleID = Role.RoleID
Where Role.Rolename = $RoleName and Role.AppID = $AppID and User.Username Like $Username;</value>
  </data>
  <data name="GetAllRoles" xml:space="preserve">
    <value>SELECT Rolename FROM Role WHERE AppID = $AppID</value>
  </data>
  <data name="GetRolesForUser" xml:space="preserve">
    <value>Select Rolename from Role
Inner Join UserRoleMap On Role.RoleID = UserRoleMap.RoleID and Role.AppID = UserRoleMap.AppID
Inner Join User On User.UserID = UserRoleMap.UserID and User.AppID = UserRoleMap.AppID
Where User.Username = $Username and User.AppID = $AppID;</value>
  </data>
  <data name="GetUsersInRole" xml:space="preserve">
    <value>Select User.Username from User
Inner Join UserRoleMap on User.UserID = UserRoleMap.UserID
Inner Join Role on UserRoleMap.RoleID = Role.RoleID
Where Role.Rolename = $RoleName and Role.AppID = $AppID;
</value>
  </data>
  <data name="IsUserInRole" xml:space="preserve">
    <value>Select Count(*) from User
Inner Join UserRoleMap on User.UserID = UserRoleMap.UserID
Inner Join Role on UserRoleMap.RoleID = Role.RoleID
Where Role.Rolename = $Rolename  and User.Username=$Username and Role.AppID = $AppID;</value>
  </data>
  <data name="RoleExists" xml:space="preserve">
    <value>SELECT COUNT(*) FROM Role WHERE Rolename = $Rolename AND AppID = $AppID;</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































Deleted Membership/Sql/Schema.sql.
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
Create Table Application(
  AppID  INTEGER PRIMARY KEY,
  ApplicationName text
);

Create Table Role(
	RoleID INTEGER PRIMARY KEY,
	Rolename text,
	AppID integer NOT NULL
);

Create Table UserRoleMap(
	UserID integer NOT NULL,
	RoleID integer NOT NULL,
	AppID integer NOT NULL
);
	
CREATE TABLE User
(
  UserID INTEGER PRIMARY KEY,
  Username text NOT NULL,
  AppID integer NOT NULL,
  Email text  NOT NULL,
  Comment text,
  Password text NOT NULL,
  PasswordQuestion text,
  PasswordAnswer text,
  IsApproved bool, 
  LastActivityDate DateTime,
  LastLoginDate DateTime,
  LastPasswordChangedDate DateTime,
  CreationDate DateTime, 
  IsOnLine bool,
  IsLockedOut bool,
  LastLockedOutDate DateTime,
  FailedPasswordAttemptCount integer,
  FailedPasswordAttemptWindowStart DateTime,
  FailedPasswordAnswerAttemptCount integer,
  FailedPasswordAnswerAttemptWindowStart DateTime
);

Create Table SiteMapNode(
	NodeID	INTEGER PRIMARY KEY,
	AppID integer NOT NULL,
	Title text,
	Description text,
	Url text,
	Parent integer
);

Create Table SiteMapNodeRoles(
	NodeID integer NOT NULL,
	RoleID integer NOT NULL,
	AppID integer NOT NULL
);


Create Table Profile(
	ProfileID INTEGER PRIMARY KEY,
	UserName text NOT NULL,
	AppID integer NOT NULL,
	LastUpdatedDate Datetime,
	LastActivityDate Datetime
);

Create Table ProfileData(
	ItemID INTEGER PRIMARY KEY,
	ProfileID integer NOT NULL,
	ItemData BLOB,
	ItemName text NOT NULL,
	ItemFormat text NOT NULL
);
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































Deleted Membership/Sql/SiteMapSql.Designer.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
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace SQLiteProvider {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class SiteMapSql {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal SiteMapSql() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SQLiteProvider.Sql.SiteMapSql", typeof(SiteMapSql).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select NodeID, Title, Description, Url from SiteMapNode where AppID = $AppID and Parent = $ParentID;.
        /// </summary>
        internal static string GetNodeByParentID {
            get {
                return ResourceManager.GetString("GetNodeByParentID", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select NodeID Title, Description, Url from SiteMapNode where AppID = $AppID and Url like $Url;.
        /// </summary>
        internal static string GetNodeByUrl {
            get {
                return ResourceManager.GetString("GetNodeByUrl", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select RoleName from Role
        ///Inner Join SiteMapNodeRoles on Role.RoleID = SiteMapNodeRoles.RoleID and Role.AppID = SiteMapNodeRoles.AppID
        ///Where SiteMapNodeRoles.NodeID = $NodeID and Role.AppID = $AppID;.
        /// </summary>
        internal static string GetNodeRoles {
            get {
                return ResourceManager.GetString("GetNodeRoles", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select NodeID, Title, Description, Url, Parent from SiteMapNode where AppID = $AppID order by Parent;.
        /// </summary>
        internal static string GetNodes {
            get {
                return ResourceManager.GetString("GetNodes", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Select Parent.NodeID, Parent.Title, Parent.Description, Parent.Url from SiteMapNode Parent
        ///left join SiteMapNode Child on Parent.NodeID = Child.Parent and Parent.AppID = Child.AppID
        ///where Child.AppID = $AppID and Child.NodeID = $NodeID;.
        /// </summary>
        internal static string GetParentByNodeID {
            get {
                return ResourceManager.GetString("GetParentByNodeID", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































Deleted Membership/Sql/SiteMapSql.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="GetNodeByParentID" xml:space="preserve">
    <value>Select NodeID, Title, Description, Url from SiteMapNode where AppID = $AppID and Parent = $ParentID;</value>
  </data>
  <data name="GetNodeByUrl" xml:space="preserve">
    <value>Select NodeID Title, Description, Url from SiteMapNode where AppID = $AppID and Url like $Url;</value>
  </data>
  <data name="GetNodeRoles" xml:space="preserve">
    <value>Select RoleName from Role
Inner Join SiteMapNodeRoles on Role.RoleID = SiteMapNodeRoles.RoleID and Role.AppID = SiteMapNodeRoles.AppID
Where SiteMapNodeRoles.NodeID = $NodeID and Role.AppID = $AppID;</value>
  </data>
  <data name="GetNodes" xml:space="preserve">
    <value>Select NodeID, Title, Description, Url, Parent from SiteMapNode where AppID = $AppID order by Parent;</value>
  </data>
  <data name="GetParentByNodeID" xml:space="preserve">
    <value>Select Parent.NodeID, Parent.Title, Parent.Description, Parent.Url from SiteMapNode Parent
left join SiteMapNode Child on Parent.NodeID = Child.Parent and Parent.AppID = Child.AppID
where Child.AppID = $AppID and Child.NodeID = $NodeID;</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































Deleted Membership/TODO.txt.
1
2
3
4
5
6
7
8

Optimize SQL.
Write some documentation eg: how to configure the provider via web.config
Dump SQL statements to some sort of human readable format & possibly document them.

? Create a default DB location & make the schema a resource so one can just plunk the provider in and have it just work with little or no config.
? Implement Profile Provider
? Implement a fully dynamic SiteMap Provider so changes to the DB get reflected immediatly
<
<
<
<
<
<
<
<
















Deleted Membership/Utiliy/ProviderUtility.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
using System.Web.Security;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System;
using System.Data;
using System.Data.SQLite;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Globalization;

namespace SQLiteProvider
{
    internal class ProviderUtility
    {

        public static void HandleException(Exception e, string source, string action, bool logging)
        {
            if (logging)
            {
                EventLog log = new EventLog();
                log.Source = source;
                log.Log = "Application";

                string message = "An exception occurred communicating with the data source.\n\n";
                message += "Action: " + action + "\n\n";
                message += "Exception: " + e.ToString();

                log.WriteEntry(message);
                throw new ProviderException("An exception occurred. Please check the Event Log.");
            }
            else
            {
                string msg = String.Format("An exception occured during {0} in {1}. \n Message:{2}", action, source, e.Message );
                throw new ProviderException(msg, e);
            }
        }
        public static long GetApplicationID(String ConnString, string AppName)
        {
            long AppID = 0;
            SQLiteConnection conn = new SQLiteConnection(ConnString);
            SQLiteCommand existsCmd = new SQLiteCommand(ApplicationSql.AppExists, conn);
            SQLiteCommand idCmd = new SQLiteCommand(ApplicationSql.GetAppID, conn);
            SQLiteCommand insertCmd = new SQLiteCommand(ApplicationSql.InsertApp, conn);

            existsCmd.Parameters.Add("$ApplicationName", DbType.String).Value = AppName;
            idCmd.Parameters.Add("$ApplicationName", DbType.String).Value = AppName;
            insertCmd.Parameters.Add("$ApplicationName", DbType.String).Value = AppName;
            try
            {
                conn.Open();
                if (((long)existsCmd.ExecuteScalar()) == 0)
                {
                    insertCmd.ExecuteNonQuery();
                }
                AppID = (long)idCmd.ExecuteScalar();

            }
            catch (SQLiteException e)
            {
                ProviderUtility.HandleException(e, "Utility", "ApplicationName Property", false);
            }
            finally
            {
                conn.Close();
            }
            return AppID;
        }

        public static string GetConnectionString(string csName)
        {
            string cs = "";
            ConnectionStringSettings css = ConfigurationManager.ConnectionStrings[csName];

            if (css == null || css.ConnectionString.Trim() == "")
            {
                // use default location, creating the DB if need be
                throw new ProviderException("Connection string cannot be blank.");
            }
            else
            {
                cs = css.ConnectionString;
            }
            return cs;
        }
        public static string GetApplicationName(string appName)
        {
            return (String.IsNullOrEmpty(appName)? System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath:appName);
        }
        public static bool GetExceptionDesitination(string exToLog)
        {
            bool res = false;
            if (!String.IsNullOrEmpty(exToLog) && exToLog.ToUpper() == "TRUE")
            {
                res = true;
            }
            return res;
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































Deleted Membership/app.config.
1
2
3
4
5
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
</configuration>
<
<
<
<
<










Deleted SQLite.Designer/AssemblyInfo.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
/********************************************************
 * 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.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Resources;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite Designer")]
[assembly: AssemblyDescription("ADO.NET Data Provider for SQLite")]
[assembly: AssemblyCompany("http://system.data.sqlite.org/")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM componenets.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
[assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[assembly: NeutralResourcesLanguage("en")]

// Version information for an assembly consists of the following four values:
//
//      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.77.0")]
[assembly: AssemblyFileVersion("1.0.77.0")]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































Deleted SQLite.Designer/ChangePasswordDialog.Designer.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  partial class ChangePasswordDialog
  {
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      System.Windows.Forms.Button cancelButton;
      System.Windows.Forms.Label label1;
      this.okButton = new System.Windows.Forms.Button();
      this.confirmLabel = new System.Windows.Forms.Label();
      this.password = new System.Windows.Forms.TextBox();
      this.passwordConfirm = new System.Windows.Forms.TextBox();
      this.action = new System.Windows.Forms.Label();
      cancelButton = new System.Windows.Forms.Button();
      label1 = new System.Windows.Forms.Label();
      this.SuspendLayout();
      // 
      // cancelButton
      // 
      cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
      cancelButton.Location = new System.Drawing.Point(212, 134);
      cancelButton.Name = "cancelButton";
      cancelButton.Size = new System.Drawing.Size(75, 23);
      cancelButton.TabIndex = 0;
      cancelButton.Text = "Cancel";
      cancelButton.UseVisualStyleBackColor = true;
      // 
      // label1
      // 
      label1.AutoSize = true;
      label1.Location = new System.Drawing.Point(28, 15);
      label1.Name = "label1";
      label1.Size = new System.Drawing.Size(77, 13);
      label1.TabIndex = 2;
      label1.Text = "New &Password";
      // 
      // okButton
      // 
      this.okButton.Location = new System.Drawing.Point(131, 134);
      this.okButton.Name = "okButton";
      this.okButton.Size = new System.Drawing.Size(75, 23);
      this.okButton.TabIndex = 1;
      this.okButton.Text = "OK";
      this.okButton.UseVisualStyleBackColor = true;
      this.okButton.Click += new System.EventHandler(this.okButton_Click);
      // 
      // confirmLabel
      // 
      this.confirmLabel.AutoSize = true;
      this.confirmLabel.Enabled = false;
      this.confirmLabel.Location = new System.Drawing.Point(12, 42);
      this.confirmLabel.Name = "confirmLabel";
      this.confirmLabel.Size = new System.Drawing.Size(93, 13);
      this.confirmLabel.TabIndex = 4;
      this.confirmLabel.Text = "&Confirm Password";
      // 
      // password
      // 
      this.password.Location = new System.Drawing.Point(111, 12);
      this.password.Name = "password";
      this.password.Size = new System.Drawing.Size(176, 21);
      this.password.TabIndex = 3;
      this.password.UseSystemPasswordChar = true;
      this.password.TextChanged += new System.EventHandler(this.password_TextChanged);
      // 
      // passwordConfirm
      // 
      this.passwordConfirm.Enabled = false;
      this.passwordConfirm.Location = new System.Drawing.Point(111, 39);
      this.passwordConfirm.Name = "passwordConfirm";
      this.passwordConfirm.Size = new System.Drawing.Size(176, 21);
      this.passwordConfirm.TabIndex = 5;
      this.passwordConfirm.UseSystemPasswordChar = true;
      this.passwordConfirm.TextChanged += new System.EventHandler(this.password_TextChanged);
      // 
      // action
      // 
      this.action.Location = new System.Drawing.Point(39, 74);
      this.action.Name = "action";
      this.action.Size = new System.Drawing.Size(220, 46);
      this.action.TabIndex = 6;
      // 
      // ChangePasswordDialog
      // 
      this.AcceptButton = this.okButton;
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.CancelButton = cancelButton;
      this.ClientSize = new System.Drawing.Size(299, 169);
      this.Controls.Add(this.action);
      this.Controls.Add(this.passwordConfirm);
      this.Controls.Add(this.confirmLabel);
      this.Controls.Add(this.password);
      this.Controls.Add(label1);
      this.Controls.Add(this.okButton);
      this.Controls.Add(cancelButton);
      this.Font = new System.Drawing.Font("MS Shell Dlg 2", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
      this.MaximizeBox = false;
      this.MinimizeBox = false;
      this.Name = "ChangePasswordDialog";
      this.ShowIcon = false;
      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
      this.Text = "Change SQLite Database Password";
      this.ResumeLayout(false);
      this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.TextBox passwordConfirm;
    private System.Windows.Forms.Label action;
    private System.Windows.Forms.TextBox password;
    private System.Windows.Forms.Label confirmLabel;
    private System.Windows.Forms.Button okButton;

  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































Deleted SQLite.Designer/ChangePasswordDialog.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Text;
  using System.Windows.Forms;
  using Microsoft.VisualStudio.Data;
  using System.Windows.Forms.Design;
  using Microsoft.VisualStudio.Shell.Interop;
  using Microsoft.VisualStudio;
  using System.Data.Common;

  public partial class ChangePasswordDialog : Form
  {
    internal string Password;

    private SQLiteConnectionProperties _props;

    private string GetCurrentPassword()
    {
      try
      {
        return _props["Password"] as string;
      }
      catch
      {
        return String.Empty;
      }
    }

    internal ChangePasswordDialog(SQLiteConnectionProperties props)
    {
      _props = props;
      InitializeComponent();

      password.Text = GetCurrentPassword();
    }

    private void password_TextChanged(object sender, EventArgs e)
    {
      if (String.IsNullOrEmpty(password.Text) || password.Text == GetCurrentPassword())
      {
        confirmLabel.Enabled = false;
        passwordConfirm.Enabled = false;
        passwordConfirm.Text = "";

        if (String.IsNullOrEmpty(password.Text) && String.IsNullOrEmpty(GetCurrentPassword()) == false)
          action.Text = VSPackage.Decrypt;
        else
          action.Text = "";
      }
      else
      {
        confirmLabel.Enabled = true;
        passwordConfirm.Enabled = true;

        if (String.IsNullOrEmpty(GetCurrentPassword()) == false)
          action.Text = VSPackage.ReEncrypt;
        else
          action.Text = VSPackage.Encrypt;
      }

      okButton.Enabled = (password.Text == passwordConfirm.Text);
    }

    private void okButton_Click(object sender, EventArgs e)
    {
      Password = password.Text;
      DialogResult = DialogResult.OK;
      Close();
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted SQLite.Designer/ChangePasswordDialog.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="cancelButton.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="label1.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































Deleted SQLite.Designer/ChangeScriptDialog.Designer.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
namespace SQLite.Designer
{
  partial class ChangeScriptDialog
  {
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      System.Windows.Forms.PictureBox pictureBox1;
      System.Windows.Forms.Label label1;
      System.Windows.Forms.Button noButton;
      System.Windows.Forms.Button yesButton;
      this._script = new System.Windows.Forms.RichTextBox();
      this._splitter = new System.Windows.Forms.SplitContainer();
      this._show = new System.Windows.Forms.LinkLabel();
      this._original = new System.Windows.Forms.RichTextBox();
      this._saveOrig = new System.Windows.Forms.CheckBox();
      pictureBox1 = new System.Windows.Forms.PictureBox();
      label1 = new System.Windows.Forms.Label();
      noButton = new System.Windows.Forms.Button();
      yesButton = new System.Windows.Forms.Button();
      ((System.ComponentModel.ISupportInitialize)(pictureBox1)).BeginInit();
      this._splitter.Panel1.SuspendLayout();
      this._splitter.Panel2.SuspendLayout();
      this._splitter.SuspendLayout();
      this.SuspendLayout();
      // 
      // pictureBox1
      // 
      pictureBox1.Image = global::SQLite.Designer.VSPackage.info;
      pictureBox1.Location = new System.Drawing.Point(13, 13);
      pictureBox1.Name = "pictureBox1";
      pictureBox1.Size = new System.Drawing.Size(48, 48);
      pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
      pictureBox1.TabIndex = 0;
      pictureBox1.TabStop = false;
      // 
      // label1
      // 
      label1.AutoSize = true;
      label1.Location = new System.Drawing.Point(67, 31);
      label1.Name = "label1";
      label1.Size = new System.Drawing.Size(200, 13);
      label1.TabIndex = 1;
      label1.Text = "Do you want to save this script to a file?";
      // 
      // noButton
      // 
      noButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
      noButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
      noButton.Location = new System.Drawing.Point(445, 362);
      noButton.Name = "noButton";
      noButton.Size = new System.Drawing.Size(75, 25);
      noButton.TabIndex = 3;
      noButton.Text = "&No";
      noButton.UseVisualStyleBackColor = true;
      noButton.Click += new System.EventHandler(this.noButton_Click);
      // 
      // yesButton
      // 
      yesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
      yesButton.Location = new System.Drawing.Point(364, 362);
      yesButton.Name = "yesButton";
      yesButton.Size = new System.Drawing.Size(75, 25);
      yesButton.TabIndex = 4;
      yesButton.Text = "&Yes";
      yesButton.UseVisualStyleBackColor = true;
      yesButton.Click += new System.EventHandler(this.yesButton_Click);
      // 
      // _script
      // 
      this._script.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
      this._script.Dock = System.Windows.Forms.DockStyle.Fill;
      this._script.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
      this._script.Location = new System.Drawing.Point(0, 0);
      this._script.Name = "_script";
      this._script.ReadOnly = true;
      this._script.Size = new System.Drawing.Size(508, 134);
      this._script.TabIndex = 2;
      this._script.Text = "";
      this._script.WordWrap = false;
      // 
      // _splitter
      // 
      this._splitter.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                  | System.Windows.Forms.AnchorStyles.Left)
                  | System.Windows.Forms.AnchorStyles.Right)));
      this._splitter.IsSplitterFixed = true;
      this._splitter.Location = new System.Drawing.Point(12, 80);
      this._splitter.Name = "_splitter";
      this._splitter.Orientation = System.Windows.Forms.Orientation.Horizontal;
      // 
      // _splitter.Panel1
      // 
      this._splitter.Panel1.Controls.Add(this._original);
      this._splitter.Panel1MinSize = 0;
      // 
      // _splitter.Panel2
      // 
      this._splitter.Panel2.Controls.Add(this._script);
      this._splitter.Panel2MinSize = 0;
      this._splitter.Size = new System.Drawing.Size(508, 276);
      this._splitter.SplitterDistance = 138;
      this._splitter.TabIndex = 5;
      // 
      // _show
      // 
      this._show.AutoSize = true;
      this._show.Location = new System.Drawing.Point(12, 64);
      this._show.Name = "_show";
      this._show.Size = new System.Drawing.Size(118, 13);
      this._show.TabIndex = 7;
      this._show.TabStop = true;
      this._show.Tag = "<< &Hide original script";
      this._show.Text = "&Show original script >>";
      this._show.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this._show_LinkClicked);
      // 
      // _original
      // 
      this._original.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
      this._original.Dock = System.Windows.Forms.DockStyle.Fill;
      this._original.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
      this._original.Location = new System.Drawing.Point(0, 0);
      this._original.Name = "_original";
      this._original.ReadOnly = true;
      this._original.Size = new System.Drawing.Size(508, 138);
      this._original.TabIndex = 3;
      this._original.Text = "";
      this._original.WordWrap = false;
      // 
      // _saveOrig
      // 
      this._saveOrig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
      this._saveOrig.AutoSize = true;
      this._saveOrig.Location = new System.Drawing.Point(183, 367);
      this._saveOrig.Name = "_saveOrig";
      this._saveOrig.Size = new System.Drawing.Size(175, 17);
      this._saveOrig.TabIndex = 8;
      this._saveOrig.Text = "Save &original SQL with changes";
      this._saveOrig.UseVisualStyleBackColor = true;
      // 
      // ChangeScriptDialog
      // 
      this.AcceptButton = yesButton;
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.CancelButton = noButton;
      this.ClientSize = new System.Drawing.Size(532, 399);
      this.Controls.Add(this._saveOrig);
      this.Controls.Add(this._show);
      this.Controls.Add(this._splitter);
      this.Controls.Add(yesButton);
      this.Controls.Add(noButton);
      this.Controls.Add(label1);
      this.Controls.Add(pictureBox1);
      this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
      this.Name = "ChangeScriptDialog";
      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
      this.Text = "Save SQL Script";
      ((System.ComponentModel.ISupportInitialize)(pictureBox1)).EndInit();
      this._splitter.Panel1.ResumeLayout(false);
      this._splitter.Panel2.ResumeLayout(false);
      this._splitter.ResumeLayout(false);
      this.ResumeLayout(false);
      this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.RichTextBox _script;
    private System.Windows.Forms.LinkLabel _show;
    private System.Windows.Forms.RichTextBox _original;
    private System.Windows.Forms.SplitContainer _splitter;
    private System.Windows.Forms.CheckBox _saveOrig;

  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































Deleted SQLite.Designer/ChangeScriptDialog.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Text;
  using System.Windows.Forms;
  using System.Globalization;
  using SQLite.Designer.Design;

  public partial class ChangeScriptDialog : Form
  {
    private string _tableName;
    private static bool _defaultSave;

    public ChangeScriptDialog(string tableName, string script, string original)
    {
      _tableName = tableName;
      InitializeComponent();

      _script.Text = script;
      _original.Text = original;

      _saveOrig.Checked = _defaultSave;

      if (String.IsNullOrEmpty(original) || String.IsNullOrEmpty(script))
      {
        int increase = _splitter.Top - _show.Top;
        _show.Visible = false;
        _splitter.Top = _show.Top;
        _splitter.Height += increase;
        _saveOrig.Visible = false;
      }

      if (String.IsNullOrEmpty(script) == false)
        _splitter.Panel1Collapsed = true;
      else
        _splitter.Panel2Collapsed = true;
    }

    private void noButton_Click(object sender, EventArgs e)
    {
      DialogResult = DialogResult.Cancel;
      Close();
    }

    private void yesButton_Click(object sender, EventArgs e)
    {
      using (SaveFileDialog save = new SaveFileDialog())
      {
        save.DefaultExt = "sql";
        save.OverwritePrompt = true;
        save.Filter = "SQL Script Files (*.sql)|*.sql|All Files (*.*)|*.*";
        save.FileName = String.Format(CultureInfo.InvariantCulture, "{0}.sql", _tableName);
        save.Title = "Save SQLite Change Script";

        DialogResult = save.ShowDialog(this);

        if (DialogResult == DialogResult.OK)
        {
          _defaultSave = _saveOrig.Checked;

          using (System.IO.StreamWriter writer = new System.IO.StreamWriter(save.FileName, false, Encoding.UTF8))
          {
            if ((_show.Visible == true && _saveOrig.Checked == true) || (_show.Visible == false && _splitter.Panel2Collapsed == true))
            {
              if (_show.Visible == true) writer.WriteLine("/*");
              writer.WriteLine(_original.Text.Replace("\r", "").TrimEnd('\n').Replace("\n", "\r\n"));
              if (_show.Visible == true) writer.WriteLine("*/");
            }
            if (_show.Visible == true || _splitter.Panel2Collapsed == false) 
              writer.WriteLine(_script.Text.Replace("\r", "").TrimEnd('\n').Replace("\n", "\r\n"));
          }
        }
      }
      Close();
    }

    private void _show_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
    {
      string old = _show.Text;
      _show.Text = _show.Tag.ToString();
      _show.Tag = old;

      if (_splitter.IsSplitterFixed)
      {
        _splitter.IsSplitterFixed = false;
        _splitter.Panel1Collapsed = false;
      }
      else
      {
        _splitter.IsSplitterFixed = true;
        _splitter.Panel1Collapsed = true;
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































Deleted SQLite.Designer/ChangeScriptDialog.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="pictureBox1.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="label1.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="noButton.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="yesButton.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































Deleted SQLite.Designer/CtcComponents/Guids.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//****************************************************************************
//
//    Copyright (c) Microsoft Corporation. All rights reserved.
//    This code is licensed under the Visual Studio SDK license terms.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//****************************************************************************

//
// This file is used to define the Guids used to identify the command groups
// created by the sample.
//

// {DCBE6C8D-0E57-4099-A183-98FF74C64D9C}
#define guidVSPackageBasedProviderPkg { 0xdcbe6c8d, 0x0e57, 0x4099, { 0xa1, 0x83, 0x98, 0xff, 0x74, 0xc6, 0x4d, 0x9c } }

#define Group_Undefined { 0x83285929, 0x227c, 0x11d3, { 0xb8, 0x70, 0x0, 0xc0, 0x4f, 0x79, 0xf8, 0x2 } }

// {814658EE-A28E-4b97-BC33-4B1BC81EBECB}
#define guidVSPackageBasedProviderCmdSet { 0x814658ee, 0xa28e, 0x4b97, { 0xbc, 0x33, 0x4b, 0x1b, 0xc8, 0x1e, 0xbe, 0xcb } }
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































Deleted SQLite.Designer/CtcComponents/PkgCmd.ctc.
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
//****************************************************************************
//
//    Copyright (c) Microsoft Corporation. All rights reserved.
//    This code is licensed under the Visual Studio SDK license terms.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//****************************************************************************

//
// This is the file that defines the actual layout and type of the commands.
// It is divided in different sections (e.g. command definition, command
// placement, ...), with each defining a specific set of properties.
//

#include "stdidcmd.h"
#include "vsshlids.h"
#include "msobtnid.h"
#include "Guids.h"
#include "PkgCmdID.h"

#define DIS_DEF DEFAULTDISABLED | DEFAULTINVISIBLE | DYNAMICVISIBILITY
#define OI_NOID guidOfficeIcon:msotcidNoIcon

CMDS_SECTION guidVSPackageBasedProviderPkg

    BUTTONS_BEGIN

        guidVSPackageBasedProviderCmdSet:cmdidVacuum,      Group_Undefined:0, 0x0000, OI_NOID, BUTTON, DIS_DEF, "&Vacuum";
        guidVSPackageBasedProviderCmdSet:cmdidRekey,       Group_Undefined:0, 0x0000, OI_NOID, BUTTON, DIS_DEF, "Change &Password ...";

    BUTTONS_END

CMDS_END

CMDPLACEMENT_SECTION

    guidVSPackageBasedProviderCmdSet:cmdidVacuum,      guidVSData:IDG_DV_CONNECTION, 0x0100;
    guidVSPackageBasedProviderCmdSet:cmdidRekey,       guidVSData:IDG_DV_CONNECTION, 0x0100;

CMDPLACEMENT_END
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































Deleted SQLite.Designer/CtcComponents/PkgCmdID.h.
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
//****************************************************************************
//
//    Copyright (c) Microsoft Corporation. All rights reserved.
//    This code is licensed under the Visual Studio SDK license terms.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//****************************************************************************

//
// Definition of the numeric part of the IDs for the CTC elements of this
// package.
//

///////////////////////////////////////////////////////////////////////////////
// Commands
#define cmdidCreateTable 256
#define cmdidAlterTable  257
#define cmdidDropTable   258

#define cmdidCreateIndex 259
#define cmdidDropIndex   260
#define cmdidDropView    261
#define cmdidVacuum      262
#define cmdidRekey       263
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































Deleted SQLite.Designer/Design/Check.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Collections.Generic;
  using System.Collections;
  using System.Text;
  using System.ComponentModel;
  using System.Data;
  using System.Data.Common;
  using System.ComponentModel.Design;
  using System.Drawing.Design;
  using System.Windows.Forms;

  internal class CheckEditor : CollectionEditor
  {
    Table _table;
    CollectionEditor.CollectionForm _form;
    object[] _items;
    object[] _orig;
    int _count;

    internal CheckEditor(Table parent)
      : base(typeof(List<string>))
    {
      _table = parent;
    }

    protected override CollectionEditor.CollectionForm CreateCollectionForm()
    {
      _form = base.CreateCollectionForm();
      _form.Text = "CHECK Constraint Editor";
      _form.Width = (int)(_form.Width * 1.25);
      _form.Height = (int)(_form.Height * 1.25);
      return _form;
    }

    protected override object CreateInstance(Type itemType)
    {
      if (itemType == typeof(string)) return String.Empty;
      return base.CreateInstance(itemType);
    }

    protected override object[] GetItems(object editValue)
    {
      if (_items == null)
      {
        List<string> items = editValue as List<string>;
        _items = new object[items.Count];
        _orig = new object[items.Count];

        for (int n = 0; n < _items.Length; n++)
        {
          _items[n] = items[n];
          _orig[n] = items[n];
        }
        _count = _items.Length;
      }
      return _items;
    }

    protected override object SetItems(object editValue, object[] value)
    {
      bool dirty = false;
      if (editValue != null)
      {
        if (!(editValue is IList))
        {
          return editValue;
        }
        IList list = (IList)editValue;
        list.Clear();
        for (int i = 0; i < value.Length; i++)
        {
          string val = value[i] as string;

          if (String.IsNullOrEmpty(val) == false)
          {
            list.Add(val);
            if (i < _orig.Length && val != (string)_orig[i])
              dirty = true;
          }
        }
        if (list.Count != _count)
          dirty = true;

        if (dirty == true && _form.DialogResult == DialogResult.OK)
          _table._owner.MakeDirty();
      }
      return editValue;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































Deleted SQLite.Designer/Design/Column.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.ComponentModel;
  using System.ComponentModel.Design;
  using System.Windows.Forms;
  using System.Drawing.Design;
  using System.Data;
  using System.Data.Common;
  using System.Globalization;

  internal class Column : IHaveConnection
  {
    private bool _allowNulls;
    private string _dataType = "";
    private string _defaultValue = "";
    private string _columnName = "";
    private string _origName = "";
    private string _collate;
    private DataGridViewRow _parent;
    private Unique _unique;
    private Table _table;

    internal Column(Table table, DataGridViewRow row)
    {
      _parent = row;
      _table = table as Table;
      _unique = new Unique(this);
    }

    internal Column(DataRow row, Table source)
    {
      _table = source;
      _unique = new Unique(this, row);

      if (row.IsNull("AUTOINCREMENT") == false && (bool)row["AUTOINCREMENT"] == true)
        _table.PrimaryKey.AutoIncrement = true;

      _dataType = (row.IsNull("DATA_TYPE") == false) ? row["DATA_TYPE"].ToString() : String.Empty;
      _columnName = row["COLUMN_NAME"].ToString();
      _origName = _columnName;
      _allowNulls = (bool)row["IS_NULLABLE"];
      _defaultValue = (row.IsNull("COLUMN_DEFAULT") == false) ? row["COLUMN_DEFAULT"].ToString() : String.Empty;
      _collate = (row.IsNull("COLLATION_NAME") == false) ? row["COLLATION_NAME"].ToString() : String.Empty;

      string edmtype = (row.IsNull("EDM_TYPE") == false) ? row["EDM_TYPE"].ToString() : String.Empty;
      if (edmtype == "nvarchar" || edmtype == "varchar" || edmtype == "blob" || edmtype == "nchar" || edmtype == "char")
      {
        int size = (row.IsNull("CHARACTER_MAXIMUM_LENGTH") == false) ? Convert.ToInt32(row["CHARACTER_MAXIMUM_LENGTH"], CultureInfo.InvariantCulture) : int.MaxValue;
        if (size != int.MaxValue)
          _dataType = string.Format(CultureInfo.InvariantCulture, "{0}({1})", _dataType, size);
      }
      else if (edmtype == "decimal")
      {
        int size = (row.IsNull("NUMERIC_PRECISION") == false) ? Convert.ToInt32(row["NUMERIC_PRECISION"], CultureInfo.InvariantCulture) : 53;
        int scale = (row.IsNull("NUMERIC_SCALE") == false) ? Convert.ToInt32(row["NUMERIC_SCALE"], CultureInfo.InvariantCulture) : int.MaxValue;

        if (size != 53)
        {
          string scalestr = (scale == int.MaxValue) ? "" : String.Format(CultureInfo.InvariantCulture, ",{0}", scale);
          _dataType = string.Format(CultureInfo.InvariantCulture, "{0}({1}{2})", _dataType, size, scalestr);
        }
      }
    }

    #region IHaveConnection Members

    [Browsable(false)]
    public ViewTableBase DesignTable
    {
      get { return _table; }
    }

    public DbConnection GetConnection()
    {
      return ((IHaveConnection)_table).GetConnection();
    }

    #endregion


    [Browsable(false)]
    internal Table Table
    {
      get { return _table; }
    }

    internal void Committed()
    {
      _origName = ColumnName;
    }

    internal DataGridViewRow Parent
    {
      get { return _parent; }
      set 
      {
        _parent = value;
        _parent.Cells[0].Value = ColumnName;
        _parent.Cells[1].Value = DataType;
        _parent.Cells[2].Value = AllowNulls;
      }
    }

    internal void RefreshGrid()
    {
      if (_parent == null) return;
      _parent.DataGridView.Refresh();
    }

    internal void CellValueChanged(int rowIndex, int cellIndex)
    {
      if (_parent == null) return;
      if (rowIndex != _parent.Index) return;

      object value;

      if (_parent.Cells[cellIndex].IsInEditMode == true)
      {
        if (_parent.DataGridView.EditingControl != null)
          value = ((IDataGridViewEditingControl)_parent.DataGridView.EditingControl).EditingControlFormattedValue;
        else
          value = _parent.Cells[cellIndex].EditedFormattedValue;
      }
      else
        value = _parent.Cells[cellIndex].EditedFormattedValue;

      switch (cellIndex)
      {
        case 0:
          ColumnName = value.ToString();
          break;
        case 1:
          DataType = value.ToString();
          break;
        case 2:
          try
          {
            AllowNulls = Convert.ToBoolean(value, CultureInfo.InvariantCulture);
          }
          catch
          {
          }
          break;
      }
    }

    [DefaultValue("BINARY")]
    [Category("Constraints")]
    [Editor(typeof(CollationTypeEditor), typeof(UITypeEditor))]
    [Description("The collation sequence to use for the column.  This will affect comparison and equality tests against the column.")]
    public virtual string Collate
    {
      get { return _collate; }
      set
      {
        if (String.IsNullOrEmpty(value)) value = "BINARY";
        if (_collate != value)
        {
          _collate = value;
          
          if (_table.PrimaryKey.Columns.Count == 1 && String.Compare(ColumnName, _table.PrimaryKey.Columns[0].Column, StringComparison.OrdinalIgnoreCase) == 0)
            _table.PrimaryKey.Columns[0].Collate = value;

          _table._owner.MakeDirty();
        }
      }
    }

    [Category("Constraints")]
    [Description("The unique constraints of the column")]
    public virtual Unique Unique
    {
      get { return _unique; }
    }

    [Browsable(false)]
    public virtual string ColumnName
    {
      get { return _columnName; }
      set
      {
        value = value.Trim();
        if (value != _columnName)
        {
          _columnName = value;
          _table.MakeDirty();
        }
      }
    }

    [Browsable(false)]
    public virtual string OriginalName
    {
      get { return _origName; }
    }

    [DefaultValue(false)]
    [DisplayName("Allow Nulls")]
    [Category("Constraints")]
    [Description("Specifies whether or not the column will allow NULL values.")]
    public virtual bool AllowNulls
    {
      get { return _allowNulls; }
      set
      {
        if (value != _allowNulls)
        {
          _allowNulls = value;
          if (_parent == null) return;
          _parent.Cells[2].Value = _allowNulls;
          _table.MakeDirty();
        }
      }
    }

    [Browsable(false)]
    public virtual string DataType
    {
      get { return _dataType; }
      set
      {
        value = value.Trim();
        if (value != _dataType)
        {
          _dataType = value;
          _table.MakeDirty();
        }
      }
    }

    [DisplayName("Default Value")]
    [Category("Constraints")]
    [Description("The default value to populate in the column when an explicit value is not specified.")]
    public virtual string DefaultValue
    {
      get { return _defaultValue; }
      set
      {
        value = value.Trim();

        if (value != _defaultValue)
        {
          _defaultValue = value;
          _table.MakeDirty();
        }
      }
    }

    internal void WriteSql(StringBuilder builder)
    {
      builder.AppendFormat("[{0}]", ColumnName);
      if (String.IsNullOrEmpty(DataType) == false)
        builder.AppendFormat(" {0}", DataType);

      bool isprimary = false;
      if (_table.PrimaryKey.Columns.Count == 1 && String.Compare(_table.PrimaryKey.Columns[0].Column, ColumnName, StringComparison.OrdinalIgnoreCase) == 0)
      {
        isprimary = true;
        builder.Append(" PRIMARY KEY");

        if (_table.PrimaryKey.Columns[0].SortMode != ColumnSortMode.Ascending)
          builder.Append(" DESC");

        if (_table.PrimaryKey.Conflict != ConflictEnum.Abort)
          builder.AppendFormat(" ON CONFLICT {0}", _table.PrimaryKey.Conflict.ToString().ToUpperInvariant());

        if (_table.PrimaryKey.AutoIncrement == true)
          builder.Append(" AUTOINCREMENT");
      }

      if (AllowNulls == false)
        builder.Append(" NOT NULL");

      if (String.IsNullOrEmpty(Collate) == false && String.Compare(Collate, "BINARY", StringComparison.OrdinalIgnoreCase) != 0)
        builder.AppendFormat(" COLLATE {0}", Collate.ToUpperInvariant());

      if (Unique.Enabled == true && isprimary == false)
      {
        builder.Append(" UNIQUE");
        if (Unique.Conflict != ConflictEnum.Abort)
          builder.AppendFormat(" ON CONFLICT {0}", Unique.Conflict.ToString().ToUpperInvariant());
      }

      if (String.IsNullOrEmpty(DefaultValue) == false)
        builder.AppendFormat(" DEFAULT {0}", DefaultValue);
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/Design/ForeignKey.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Collections.Generic;
  using System.Collections;
  using System.Text;
  using System.ComponentModel;
  using System.Data;
  using System.Data.Common;
  using System.ComponentModel.Design;
  using System.Drawing.Design;
  using System.Windows.Forms;
  using System.Globalization;

  internal class ForeignKeyEditor : CollectionEditor
  {
    Table _table;
    CollectionEditor.CollectionForm _form;
    object[] _items;
    object[] _orig;
    int _count;

    internal ForeignKeyEditor(Table parent)
      : base(typeof(List<ForeignKey>))
    {
      _table = parent;
      _count = _table.ForeignKeys.Count;
    }

    protected override CollectionEditor.CollectionForm CreateCollectionForm()
    {
      _form = base.CreateCollectionForm();
      _form.Text = "Foreign Key Editor";
      foreach (Control c in _form.Controls[0].Controls)
      {
        PropertyGrid grid = c as PropertyGrid;
        if (grid != null)
        {
          grid.HelpVisible = true;
          break;
        }
      }
      _form.Width = (int)(_form.Width * 1.25);
      _form.Height = (int)(_form.Height * 1.25);

      return _form;
    }

    protected override object CreateInstance(Type itemType)
    {
      if (itemType == typeof(ForeignKey))
      {
        return new ForeignKey(null, _table, null);
      }
      throw new NotSupportedException();
    }

    protected override object[] GetItems(object editValue)
    {
      if (_items == null)
      {
        List<ForeignKey> items = editValue as List<ForeignKey>;
        _items = new object[items.Count];
        _orig = new object[items.Count];
        for (int n = 0; n < _items.Length; n++)
        {
          _items[n] = ((ICloneable)items[n]).Clone();
          _orig[n] = items[n];
        }
      }
      return _items;
    }

    protected override object SetItems(object editValue, object[] value)
    {
      bool dirty = false;
      if (_form.DialogResult == DialogResult.Cancel) value = _orig;

      if (editValue != null)
      {
        if (!(editValue is IList))
        {
          return editValue;
        }
        IList list = (IList)editValue;
        list.Clear();
        for (int i = 0; i < value.Length; i++)
        {
          ForeignKey fkey = value[i] as ForeignKey;

          if (fkey != null && String.IsNullOrEmpty(fkey.From.Column) == false && String.IsNullOrEmpty(fkey.To.Catalog) == false &&
            String.IsNullOrEmpty(fkey.To.Table) == false && String.IsNullOrEmpty(fkey.To.Column) == false)
          {
            if (fkey.IsDirty) dirty = true;

            list.Add(value[i]);
          }
        }
        if ((dirty == true || list.Count != _count) && _form.DialogResult == DialogResult.OK)
        _table.MakeDirty();      
      }
      return editValue;
    }
  }

  internal class ForeignKeyItem : IHaveConnectionScope
  {
    private string _catalog;
    private string _table;
    private string _column;
    private ForeignKey _fkey;

    internal ForeignKeyItem(ForeignKey fkey, string catalog, string table, string column)
    {
      _catalog = catalog;
      _table = table;
      _column = column;
      _fkey = fkey;
    }

    public override string ToString()
    {
      return String.Format(CultureInfo.InvariantCulture, "[{0}].[{1}].[{2}]", _catalog, _table, _column);
    }

    #region IHaveConnection Members

    [Browsable(false)]
    public ViewTableBase DesignTable
    {
      get { return _fkey.DesignTable; }
    }

    public DbConnection GetConnection()
    {
      return ((IHaveConnection)_fkey).GetConnection();
    }

    [Browsable(false)]
    public string TableScope
    {
      get { return _table; }
    }

    [Browsable(false)]
    public string CatalogScope
    {
      get { return _catalog; }
    }

    #endregion

    [Browsable(false)]
    [Editor(typeof(CatalogTypeEditor), typeof(UITypeEditor))]
    public virtual string Catalog
    {
      get { return _catalog; }
    }

    [Editor(typeof(TablesTypeEditor), typeof(UITypeEditor))]
    public virtual string Table
    {
      get { return _table; }
    }

    [Editor(typeof(ColumnsTypeEditor), typeof(UITypeEditor))]
    public virtual string Column
    {
      get { return _column; }
    }

    protected void SetCatalog(string value)
    {
      if (_catalog != value)
      {
        _catalog = value;
        _fkey.MakeDirty();
      }
    }

    protected void SetTable(string value)
    {
      if (_table != value)
      {
        _table = value;
        _fkey.MakeDirty();
      }
    }

    protected void SetColumn(string value)
    {
      if (_column != value)
      {
        _column = value;
        _fkey.MakeDirty();
      }
    }
  }

  [TypeConverter(typeof(ExpandableObjectConverter))]
  internal class ForeignKeyFromItem : ForeignKeyItem
  {
    internal ForeignKeyFromItem(ForeignKey fkey, string column)
      : base(fkey, fkey._table.Catalog, fkey._table.Name, column)
    {
    }

    [Editor(typeof(ColumnsTypeEditor), typeof(UITypeEditor))]
    [Description("The column of the current table that refers to the foreign key relationship")]
    public new string Column
    {
      get { return base.Column; }
      set { SetColumn(value); }
    }

    [Browsable(false)]
    public override string Catalog
    {
      get
      {
        return base.Catalog;
      }
    }

    [Browsable(false)]
    public override string Table
    {
      get
      {
        return base.DesignTable.Name;
      }
    }
  }

  [TypeConverter(typeof(ExpandableObjectConverter))]
  internal class ForeignKeyToItem : ForeignKeyItem
  {
    internal ForeignKeyToItem(ForeignKey fkey, string catalog, string table, string column)
      : base(fkey, catalog, table, column)
    {
    }

    [Browsable(false)]
    [Editor(typeof(CatalogTypeEditor), typeof(UITypeEditor))]
    [Description("The database catalog (main, temp, or the name of an attached database) to which the foreign key refers.")]
    public new string Catalog
    {
      get
      {
        return base.Catalog;
      }
      set
      {
        SetCatalog(value);
      }
    }

    [DisplayName("Base Table")]
    [Editor(typeof(TablesTypeEditor), typeof(UITypeEditor))]
    [Description("The table to which the foreign key refers.")]
    public new string Table
    {
      get { return base.Table; }
      set { SetTable(value); }
    }

    [Editor(typeof(ColumnsTypeEditor), typeof(UITypeEditor))]
    [Description("The column to which the foreign key refers.")]
    public new string Column
    {
      get { return base.Column; }
      set { SetColumn(value); }
    }
  }

  [DefaultProperty("From")]
  internal class ForeignKey : IHaveConnection, ICloneable
  {
    internal Table _table;
    internal ForeignKeyFromItem _from;
    internal ForeignKeyToItem _to;
    internal string _name;
    internal string _onUpdate;
    internal string _onDelete;
    internal string _match;
    private bool _dirty;

    private ForeignKey(ForeignKey source)
    {
      _table = source._table;
      _from = new ForeignKeyFromItem(this, source._from.Column);
      _to = new ForeignKeyToItem(this, source._to.Catalog, source._to.Table, source._to.Column);
      _name = source._name;
      _onUpdate = source._onUpdate;
      _onDelete = source._onDelete;
      _match = source._match;
      _dirty = source._dirty;
    }

    internal void MakeDirty()
    {
      _dirty = true;
    }

    [Browsable(false)]
    internal bool IsDirty
    {
      get { return _dirty; }
    }

    internal void ClearDirty()
    {
      _dirty = false;
    }

    internal ForeignKey(DbConnection cnn, Table table, DataRow row)
    {
      _table = table;
      if (row != null)
      {
        _from = new ForeignKeyFromItem(this, row["FKEY_FROM_COLUMN"].ToString());
        _to = new ForeignKeyToItem(this, row["FKEY_TO_CATALOG"].ToString(), row["FKEY_TO_TABLE"].ToString(), row["FKEY_TO_COLUMN"].ToString());
        _name = row["CONSTRAINT_NAME"].ToString();
        _onUpdate = row["FKEY_ON_UPDATE"].ToString();
        _onDelete = row["FKEY_ON_DELETE"].ToString();
        _match = row["FKEY_MATCH"].ToString();
      }
      else
      {
        _from = new ForeignKeyFromItem(this, "");
        _to = new ForeignKeyToItem(this, _table.Catalog, "", "");
      }
    }

    //internal void WriteSql(StringBuilder builder)
    //{
    //  if (String.IsNullOrEmpty(_from.Column) == false && String.IsNullOrEmpty(_to.Catalog) == false &&
    //    String.IsNullOrEmpty(_to.Table) == false && String.IsNullOrEmpty(_to.Column) == false)
    //  {
    //    builder.AppendFormat("CONSTRAINT [{0}] FOREIGN KEY ([{1}]) REFERENCES [{3}] ([{4}])", Name, _from.Column, _to.Catalog, _to.Table, _to.Column);
    //  }
    //}

    [ParenthesizePropertyName(true)]
    [Category("Identity")]
    [Description("The name of the foreign key.")]
    public string Name
    {
      get
      {
        if (String.IsNullOrEmpty(_name) == false) return _name;

        return String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}_{3}", _from.Table, _from.Column, _to.Table, _to.Column);
      }
      set
      {
        if (_name != value)
        {
          _name = value;
          MakeDirty();
        }
      }
    }

    #region IHaveConnection Members

    [Browsable(false)]
    public ViewTableBase DesignTable
    {
      get { return _table; }
    }

    public DbConnection GetConnection()
    {
      return ((IHaveConnection)_table).GetConnection();
    }

    #endregion

    [DisplayName("From Key")]
    [Category("From")]
    [Description("The source column in the current table that refers to the foreign key.")]
    public ForeignKeyFromItem From
    {
      get { return _from; }
    }

    [DisplayName("To Key")]
    [Category("To")]
    [Description("The table and column to which the specified from column is related.")]
    public ForeignKeyToItem To
    {
      get { return _to; }
    }

    [DisplayName("On Update")]
    [Category("Action")]
    [Description("The action to take when modifying the parent key values of an existing row.")]
    public string OnUpdate
    {
        get { return _onUpdate; }
    }

    [DisplayName("On Delete")]
    [Category("Action")]
    [Description("The action to take when deleting a row from the parent table.")]
    public string OnDelete
    {
        get { return _onDelete; }
    }

    [DisplayName("Match")]
    [Category("Match")]
    [Description("Used with composite foreign key definitions to modify the way NULL values that occur in child keys are handled.  Not currently supported.")]
    public string Match
    {
        get { return _match; }
    }

    #region ICloneable Members

    public object Clone()
    {
      return new ForeignKey(this);
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/Design/Index.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Collections.Generic;
  using System.Collections;
  using System.Text;
  using System.ComponentModel;
  using System.Data;
  using System.Data.Common;
  using System.ComponentModel.Design;
  using System.Drawing.Design;
  using System.Windows.Forms;
  using System.Security.Permissions;
  using System.Globalization;

  internal class IndexEditor : CollectionEditor
  {
    Table _table;
    CollectionEditor.CollectionForm _form;
    object[] _items;
    object[] _orig;
    int _count;

    internal IndexEditor(Table parent)
      : base(typeof(List<Index>))
    {
      _table = parent;
    }

    protected override object[] GetItems(object editValue)
    {
      if (_items == null)
      {
        List<Index> value = editValue as List<Index>;

        int extra = (_table.PrimaryKey.Columns.Count > 0) ? 1 : 0;

        _items = new object[value.Count + extra];
        _orig = new object[_items.Length];
        for (int n = extra; n < _items.Length; n++)
        {
          _items[n] = ((ICloneable)value[n - extra]).Clone();
          _orig[n] = value[n - extra];
        }

        if (extra > 0)
        {
          _items[0] = ((ICloneable)_table.PrimaryKey).Clone();
          _orig[0] = _table.PrimaryKey;
        }

        _count = _items.Length;
      }
      return _items;
    }

    protected override CollectionEditor.CollectionForm CreateCollectionForm()
    {
      _form = base.CreateCollectionForm();
      _form.Text = "Index Editor";

      /* Doing this because I can't figure out how to get the Columns collection editor to notify this editor when a column of an index is updated.
         This forces the collection editor form to be "dirty" which calls SetItems() when you hit OK or cancel.  Otherwise, if you
         change a column around and hit OK, then hit OK on this editor, it won't be dirty and won't update. */
      try
      {
        _form.GetType().InvokeMember("dirty", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.SetField, null, _form, new object[] { true });
      }
      catch
      {
      }

      foreach (Control c in _form.Controls[0].Controls)
      {
        PropertyGrid grid = c as PropertyGrid;
        if (grid != null)
        {
          grid.HelpVisible = true;
          break;
        }
      }
      _form.Width = (int)(_form.Width * 1.25);
      _form.Height = (int)(_form.Height * 1.25);

      return _form;
    }

    protected override object CreateInstance(Type itemType)
    {
      if (itemType == typeof(Index))
      {
        return new Index(null, _table, null);
      }
      throw new NotSupportedException();
    }

    protected override bool CanRemoveInstance(object value)
    {
      return !(value is PrimaryKey);
    }

    protected override object SetItems(object editValue, object[] value)
    {
      bool dirty = false;
      int count = 0;

      if (_form.DialogResult == DialogResult.Cancel)
        value = _orig;

      if (editValue != null)
      {
        if (!(editValue is IList))
        {
          return editValue;
        }
        IList list = (IList)editValue;
        list.Clear();
        for (int i = 0; i < value.Length; i++)
        {
          Index idx = value[i] as Index;

          if (idx is PrimaryKey)
          {
            _table.PrimaryKey = (PrimaryKey)idx;
            if (idx.IsDirty) dirty = true;
            count++;
          }
          else
          {
            if (idx != null && idx.Columns.Count > 0)
            {
              idx.Name = idx.Name;
              list.Add(idx);
              if (idx.IsDirty) dirty = true;
              count++;
            }
          }
        }
      }

      if ((dirty == true || count != _count) && _form.DialogResult == DialogResult.OK)
        _table._owner.MakeDirty();

      return editValue;
    }
  }

  internal class IndexColumnEditor : CollectionEditor
  {
    Index _index;
    object[] _items;
    object[] _orig;
    int _count;
    CollectionEditor.CollectionForm _form;

    public IndexColumnEditor() : base(typeof(List<IndexColumn>))
    {
    }

    protected override CollectionEditor.CollectionForm CreateCollectionForm()
    {
      _form = base.CreateCollectionForm();
      _form.Text = "Index Columns Editor";
      foreach (Control c in _form.Controls[0].Controls)
      {
        PropertyGrid grid = c as PropertyGrid;
        if (grid != null)
        {
          grid.HelpVisible = true;
          break;
        }
      }
      _form.Width = (int)(_form.Width * 1.25);
      _form.Height = (int)(_form.Height * 1.25);
      return _form;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
      _index = context.Instance as Index;
      _items = null;
      _count = 0;
      return base.EditValue(context, provider, value);
    }

    protected override object CreateInstance(Type itemType)
    {
      if (itemType == typeof(IndexColumn))
      {
        return new IndexColumn(_index, null);
      }
      throw new NotSupportedException();
    }

    protected override object[] GetItems(object editValue)
    {
      if (_items == null)
      {
        List<IndexColumn> value = editValue as List<IndexColumn>;
        _items = new object[value.Count];
        _orig = new object[value.Count];
        for (int n = 0; n < _items.Length; n++)
        {
          _items[n] = ((ICloneable)value[n]).Clone();
          _orig[n] = value[n];
        }

        _count = _items.Length;
      }
      return _items;
    }

    protected override object SetItems(object editValue, object[] value)
    {
      if (_form.DialogResult == DialogResult.Cancel)
        value = _orig;

      if (editValue != null)
      {
        if (!(editValue is IList))
        {
          return editValue;
        }
        IList list = (IList)editValue;
        list.Clear();
        for (int i = 0; i < value.Length; i++)
        {
          IndexColumn idx = value[i] as IndexColumn;

          if (idx != null && String.IsNullOrEmpty(idx.Column) == false)
          {
            list.Add(value[i]);
          }
        }
      }

      if ((_index.IsDirty || _index.Columns.Count != _count) && _form.DialogResult == DialogResult.OK)
      {
        if (_index.Columns.Count > 0 && String.IsNullOrEmpty(_index._name) == true)
          _index.Name = _index.Name;
      }
      return editValue;
    }
  }

  internal class IndexTypeConverter : TypeConverter
  {
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
      if (sourceType == typeof(string)) return true;
      return base.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
      if (destinationType == typeof(string)) return true;
      return base.CanConvertTo(context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
      if (destinationType == typeof(string))
      {
        StringBuilder builder = new StringBuilder();
        string separator = "";
        foreach (IndexColumn c in (List<IndexColumn>)value)
        {
          builder.AppendFormat("{0}[{1}]", separator, c.Column);
          if (c.SortMode != ColumnSortMode.Ascending)
            builder.Append(" DESC");
          if (c.Collate != "BINARY")
            builder.AppendFormat(" COLLATE {0}", c.Collate.ToUpperInvariant());

          separator = ", ";
        }
        return builder.ToString();
      }
      else
        return base.ConvertTo(context, culture, value, destinationType);
    }
  }

  internal enum ColumnSortMode
  {
    Ascending = 0,
    Descending = 1
  }

  [DefaultProperty("Column")]
  internal class IndexColumn : IHaveConnectionScope, ICloneable
  {
    internal Index _parent;
    private string _column;
    private ColumnSortMode _mode = ColumnSortMode.Ascending;
    private string _collate = "BINARY";

    [Editor(typeof(ColumnsTypeEditor), typeof(UITypeEditor))]
    [DisplayName("Base Column")]
    [Category("Source")]
    [Description("The column name to be included in the index.")]
    [NotifyParentProperty(true)]
    [RefreshProperties(RefreshProperties.All)]
    public string Column
    {
      get { return _column; }
      set
      {
        if (_column != value)
        {
          _column = value;
          _parent.MakeDirty();
        }
      }
    }

    [DefaultValue(ColumnSortMode.Ascending)]
    [Category("Constraints")]
    [Description("Specifies what order to sort the column in.  Descending indexes are not supported when using the SQLite legacy file format.")]
    [NotifyParentProperty(true)]
    [RefreshProperties(RefreshProperties.All)]
    public ColumnSortMode SortMode
    {
      get { return _mode; }
      set
      {
        if (value != _mode)
        {
          _mode = value;
          _parent.MakeDirty();
        }
      }
    }

    [DefaultValue("BINARY")]
    [Category("Constraints")]
    [Editor(typeof(CollationTypeEditor), typeof(UITypeEditor))]
    [Description("The collation sequence to use to generate the index for the specified column.")]
    [NotifyParentProperty(true)]
    [RefreshProperties(RefreshProperties.All)]
    public string Collate
    {
      get { return _collate; }
      set
      {
        if (String.IsNullOrEmpty(value)) value = "BINARY";

        if (value != _collate)
        {
          _collate = value;
          if (_parent is PrimaryKey)
          {
            PrimaryKey pk = _parent as PrimaryKey;
            if (pk.Columns.Count == 1)
            {
              foreach (Column c in pk.Table.Columns)
              {
                if (string.Compare(c.ColumnName, Column, StringComparison.OrdinalIgnoreCase) == 0)
                {
                  c.Collate = value;
                  break;
                }
              }
            }
          }
          _parent.MakeDirty();
        }
      }
    }

    public override string ToString()
    {
      if (String.IsNullOrEmpty(_column) == true) return "(none)";
      return _column;
    }

    private IndexColumn(IndexColumn source)
    {
      _parent = source._parent;
      _column = source._column;
      _mode = source._mode;
      _collate = source._collate;
    }

    internal IndexColumn(Index parent, DataRow row)
    {
      _parent = parent;
      if (row != null)
      {
        _column = row["COLUMN_NAME"].ToString();
        if (row.IsNull("SORT_MODE") == false && (string)row["SORT_MODE"] != "ASC")
          _mode = ColumnSortMode.Descending;

        if (row.IsNull("COLLATION_NAME") == false)
          _collate = row["COLLATION_NAME"].ToString().ToUpperInvariant();
      }
    }

    public object Clone()
    {
      return new IndexColumn(this);
    }

    #region IHaveConnectionScope Members

    [Browsable(false)]
    public string CatalogScope
    {
      get { return _parent.Table.Catalog; }
    }

    [Browsable(false)]
    public string TableScope
    {
      get { return _parent.Table.Name; }
    }

    #endregion

    #region IHaveConnection Members

    [Browsable(false)]
    public ViewTableBase DesignTable
    {
      get { return _parent.DesignTable; }
    }

    public DbConnection GetConnection()
    {
      return ((IHaveConnection)_parent).GetConnection();
    }

    #endregion
  }

  public enum IndexTypeEnum
  {
    Index = 0,
    PrimaryKey = 1,
  }

  [DefaultProperty("Columns")]
  internal class Index : IHaveConnection, ICloneable
  {
    private Table _table;
    internal string _name;
    private bool _unique;
    private List<IndexColumn> _columns = new List<IndexColumn>();
    private string _definition;
    private bool _calcname;
    internal ConflictEnum _conflict = ConflictEnum.Abort;
    bool _dirty;

    protected Index(Index source)
    {
      _table = source._table;
      _name = source._name;
      _unique = source._unique;
      _definition = source._definition;
      _conflict = source._conflict;
      _dirty = source._dirty;

      foreach (IndexColumn c in source._columns)
      {
        IndexColumn copy = ((ICloneable)c).Clone() as IndexColumn;
        copy._parent = this;
        _columns.Add(copy);
      }
    }

    internal Index(DbConnection cnn, Table table, DataRow index)
    {
      _table = table;
      if (index != null)
      {
        _name = index["INDEX_NAME"].ToString();
        _unique = (bool)index["UNIQUE"];
        _definition = index["INDEX_DEFINITION"].ToString();

        using (DataTable tbl = cnn.GetSchema("IndexColumns", new string[] { table.Catalog, null, table.Name, Name }))
        {
          foreach (DataRow row in tbl.Rows)
          {
            _columns.Add(new IndexColumn(this, row));
          }
        }
      }
    }

    [DisplayName("Index Type")]
    [Category("Storage")]
    [Description("Specifies whether this is an index or a primary key.")]
    public virtual IndexTypeEnum IndexType
    {
      get { return IndexTypeEnum.Index; }
    }

    #region IHaveConnection Members

    [Browsable(false)]
    public ViewTableBase DesignTable
    {
      get { return _table; }
    }

    public DbConnection GetConnection()
    {
      return ((IHaveConnection)_table).GetConnection();
    }

    #endregion

    internal virtual void WriteSql(StringBuilder builder)
    {
      string separator = "";
      builder.AppendFormat(CultureInfo.InvariantCulture, "CREATE {0}INDEX [{1}].[{2}] ON [{3}] (", (_unique == true) ? "UNIQUE " : "", _table.Catalog, Name, _table.Name);
      foreach (IndexColumn c in Columns)
      {
        builder.AppendFormat(CultureInfo.InvariantCulture, "{0}[{1}]", separator, c.Column);
        
        if (c.SortMode != ColumnSortMode.Ascending)
          builder.Append(" DESC");

        if (String.IsNullOrEmpty(c.Collate) && String.Compare(c.Collate,"BINARY", StringComparison.OrdinalIgnoreCase) != 0)
          builder.AppendFormat(CultureInfo.InvariantCulture, " COLLATE {0}", c.Collate.ToUpperInvariant());

        separator = ", ";
      }
      builder.AppendFormat(");");
    }

    [Browsable(false)]
    internal Table Table
    {
      get { return _table; }
    }

    [Browsable(false)]
    public string OriginalSql
    {
      get { return _definition; }
    }

    internal void MakeDirty()
    {
      _dirty = true;
    }

    [Browsable(false)]
    internal bool IsDirty
    {
      get { return _dirty; }
    }

    internal void ClearDirty()
    {
      _dirty = false;
    }

    [DefaultValue(false)]
    [Description("When set to true, the combination of column(s) of the index must be a unique value.")]
    public virtual bool Unique
    {
      get { return _unique; }
      set
      {
        if (value != _unique)
        {
          _unique = value;
          MakeDirty();
        }
      }
    }

    [Browsable(false)]
    protected virtual string NamePrefix
    {
      get { return "IX"; }
    }

    [Browsable(false)]
    protected virtual string NewName
    {
      get { return "NewIndex"; }
    }

    [ParenthesizePropertyName(true)]
    [RefreshProperties(RefreshProperties.All)]
    [Category("Identity")]
    [Description("The name of the index.")]
    public virtual string Name
    {
      get
      {
        if (String.IsNullOrEmpty(_name))
        {
          if (_calcname == true) return GetHashCode().ToString();

          string name = String.Format(CultureInfo.InvariantCulture, "{0}_{1}", NamePrefix, NewName);
          if (Columns.Count > 0 && NewName != Table.Name)
          {
            name = String.Format(CultureInfo.InvariantCulture, "{0}_", NamePrefix);
            for (int n = 0; n < Columns.Count; n++)
            {
              if (n > 0) name += "_";
              name += Columns[n].Column;
            }
          }
          int count = 0;
          string proposed = name;

          _calcname = true;
          for (int n = 0; n < _table.Indexes.Count; n++)
          {
            Index idx = _table.Indexes[n];
            proposed = String.Format(CultureInfo.InvariantCulture, "{0}{1}", name, (count > 0) ? count.ToString() : "");
            if (idx.Name == proposed)
            {
              count++;
              n = -1;
            }
          }
          _calcname = false;
          return proposed;
        }
        return _name;
      }
      set
      {
        if (value != _name)
        {
          _name = value;
          MakeDirty();
        }
      }
    }

    [TypeConverter(typeof(IndexTypeConverter))]
    [Editor(typeof(IndexColumnEditor), typeof(UITypeEditor))]
    [RefreshProperties(RefreshProperties.All)]
    [Category("Source")]
    [Description("The column(s) to be indexed.")]
    [NotifyParentProperty(true)]
    public List<IndexColumn> Columns
    {
      get { return _columns; }
    }

    #region ICloneable Members

    object ICloneable.Clone()
    {
      return new Index(this);
    }

    #endregion
  }

  public class ColumnsMultiSelectEditor : UITypeEditor
  {
    private System.Windows.Forms.Design.IWindowsFormsEditorService _edSvc;
    private CheckedListBox _list;
    private bool _cancel;

    public ColumnsMultiSelectEditor()
    {
      // build selector list
      _list = new CheckedListBox();
      _list.BorderStyle = BorderStyle.FixedSingle;
      _list.CheckOnClick = true;
      _list.ThreeDCheckBoxes = false;
      _list.KeyPress += new KeyPressEventHandler(_list_KeyPress);
    }

    [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    override public UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext ctx)
    {
      return UITypeEditorEditStyle.DropDown;
    }

    [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    override public object EditValue(ITypeDescriptorContext ctx, IServiceProvider provider, object value)
    {
      Index idx = ctx.Instance as Index;
      Trigger trig = ctx.Instance as Trigger;
      ViewTableBase parent = null;

      if (idx != null) parent = idx.Table;
      else if (trig != null) parent = trig.ViewTableBase;

      // initialize editor service
      _edSvc = (System.Windows.Forms.Design.IWindowsFormsEditorService)provider.GetService(typeof(System.Windows.Forms.Design.IWindowsFormsEditorService));
      if (_edSvc == null)
        return value;

      if (value == null) value = String.Empty;
      if (String.IsNullOrEmpty(value.ToString()) == true) value = String.Empty;

      string[] values = value.ToString().Split(',');
      
      // populate the list
      _list.Items.Clear();

      if (parent is Table)
      {
        foreach (Column c in ((Table)parent).Columns)
        {
          CheckState check = CheckState.Unchecked;
          for (int n = 0; n < values.Length; n++)
          {
            if (values[n].Trim() == String.Format(CultureInfo.InvariantCulture, "[{0}]", c.ColumnName))
            {
              check = CheckState.Checked;
              break;
            }
          }
          _list.Items.Add(c.ColumnName, check);
        }
      }
      else
      {
        try
        {
          using (DbCommand cmd = trig.GetConnection().CreateCommand())
          {
            cmd.CommandText = ((View)parent).SqlText;
            using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly))
            using (DataTable tbl = reader.GetSchemaTable())
            {
              foreach (DataRow row in tbl.Rows)
              {
                CheckState check = CheckState.Unchecked;
                for (int n = 0; n < values.Length; n++)
                {
                  if (values[n].Trim() == String.Format(CultureInfo.InvariantCulture, "[{0}]", row[SchemaTableColumn.ColumnName]))
                  {
                    check = CheckState.Checked;
                    break;
                  }
                }
                _list.Items.Add(row[SchemaTableColumn.ColumnName].ToString(), check);
              }
            }
          }
        }
        catch
        {
        }
      }
      _list.Height = Math.Min(300, (_list.Items.Count + 1) * _list.Font.Height);

      // show the list
      _cancel = false;
      _edSvc.DropDownControl(_list);

      // build return value from checked items on the list
      if (!_cancel)
      {
        // build a comma-delimited string with the checked items
        StringBuilder sb = new StringBuilder();
        foreach (object item in _list.CheckedItems)
        {
          if (sb.Length > 0) sb.Append(", ");
          sb.AppendFormat("[{0}]", item.ToString());
        }

        return sb.ToString();
      }

      // done
      return value;
    }

    // ** event handlers

    // close editor if the user presses enter or escape
    private void _list_KeyPress(object sender, KeyPressEventArgs e)
    {
      switch (e.KeyChar)
      {
        case (char)27:
          _cancel = true;
          _edSvc.CloseDropDown();
          break;
        case (char)13:
          _edSvc.CloseDropDown();
          break;
      }
    }
  }

  internal class ColumnsTypeEditor : ObjectSelectorEditor
  {
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
      return UITypeEditorEditStyle.DropDown;
    }

    protected override void FillTreeWithData(Selector selector, ITypeDescriptorContext context, IServiceProvider provider)
    {
      base.FillTreeWithData(selector, context, provider);
      IHaveConnectionScope source = context.Instance as IHaveConnectionScope;
      ViewTableBase design;

      if (source == null) return;

      design = source.DesignTable;

      if (design.Name != source.TableScope)
      {
        using (DataTable table = source.GetConnection().GetSchema("Columns", new string[] { source.CatalogScope, null, source.TableScope }))
        {
          foreach (DataRow row in table.Rows)
          {
            selector.AddNode(row[3].ToString(), row[3], null);
          }
        }
      }
      else
      {
        Table tbl = design as Table;
        if (tbl != null)
        {
          foreach (Column c in tbl.Columns)
          {
            selector.AddNode(c.ColumnName, c.ColumnName, null);
          }
        }
      }
    }

    public override bool IsDropDownResizable
    {
      get
      {
        return true;
      }
    }
  }

  internal class TablesTypeEditor : ObjectSelectorEditor
  {
    public override bool IsDropDownResizable
    {
      get
      {
        return true;
      }
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
      return UITypeEditorEditStyle.DropDown;
    }

    protected override void FillTreeWithData(Selector selector, ITypeDescriptorContext context, IServiceProvider provider)
    {
      base.FillTreeWithData(selector, context, provider);
      IHaveConnectionScope source = context.Instance as IHaveConnectionScope;
      Table design;

      if (source == null) return;

      design = source.DesignTable as Table;

      using (DataTable table = source.GetConnection().GetSchema("Tables", new string[] { source.CatalogScope }))
      {
        foreach (DataRow row in table.Rows)
        {
          bool add = true;
          if (design != null && (row[2].ToString() == design.OldName || row[2].ToString() == design.Name))
            add = false;

          if (add) 
            selector.AddNode(row[2].ToString(), row[2], null);
        }
      }
      if (design != null)
        selector.AddNode(design.Name, design.Name, null);
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/Design/PrimaryKey.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.ComponentModel;
  using System.Data;
  using System.Data.Common;

  internal class PrimaryKey : Index, ICloneable
  {
    private bool _autoincrement;

    internal PrimaryKey(DbConnection cnn, Table table, DataRow row)
      : base(cnn, table, row)
    {
      if (String.IsNullOrEmpty(_name) == false && _name.StartsWith("sqlite_", StringComparison.OrdinalIgnoreCase))
        _name = null;
    }

    protected PrimaryKey(PrimaryKey source)
      : base(source)
    {
      _autoincrement = source._autoincrement;
    }

    public override IndexTypeEnum IndexType
    {
      get
      {
        return IndexTypeEnum.PrimaryKey;
      }
    }

    protected override string NamePrefix
    {
      get
      {
        return "PK";
      }
    }

    protected override string NewName
    {
      get
      {
        return Table.Name;
      }
    }

    [Browsable(false)]
    public override bool Unique
    {
      get
      {
        return true;
      }
      set
      {
        base.Unique = true;
      }
    }

    [DefaultValue(ConflictEnum.Abort)]
    [DisplayName("On Conflict")]
    [Category("Constraints")]
    [Description("Specifies what action to take when the primary key constraint is violated.")]
    public ConflictEnum Conflict
    {
      get { return _conflict; }
      set
      {
        if (value != _conflict)
        {
          _conflict = value;
          MakeDirty();
        }
      }
    }

    [DefaultValue(false)]
    [Category("Constraints")]
    [Description("Can only be enabled for a single column primary key of type INTEGER.  When set, the primary key is guaranteed to increment in sequence, and no previously deleted or uncommitted values will ever be used.")]
    public bool AutoIncrement
    {
      get
      {
        if (Columns.Count > 1) return false;
        if (Columns.Count == 1 && Columns[0].SortMode != ColumnSortMode.Ascending) return false;
        return _autoincrement;
      }
      set
      {
        if (value != _autoincrement)
        {
          _autoincrement = value;
          MakeDirty();
        }
      }
    }

    #region ICloneable Members

    object ICloneable.Clone()
    {
      return new PrimaryKey(this);
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































Deleted SQLite.Designer/Design/SimpleTokenizer.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Globalization;

  internal static class SimpleTokenizer
  {
    public struct StringParts
    {
      internal string value;
      internal int position;
      internal string quote;
      internal bool sep;
      internal int depth;
      internal string keyword;
      internal char sepchar;

      public override string ToString()
      {
        return String.Format(CultureInfo.InvariantCulture, "{0} {1} at {2} {3} depth {4}", value, quote, position, sep == true ? "(sep)" : "", depth);
      }
    }

    public static StringParts[] BreakString(string source)
    {
      char[] opens = new char[] { '\"', '[', '\'', '(', ')', ',', ' ', ';', '\r', '\n', '\t' };
      char[] opens2 = new char[] { '\"', '[', '\'', '(', ')', ',', ' ', ';', '\r', '\n', '\t', '.' };
      char[] closes = new char[] { '\"', ']', '\'', };
      string sep = ";,";
      string opensstr = "\"['";

      if (String.IsNullOrEmpty(source) == true) return new StringParts[0];

      int n = 0;
      int x;
      int depth = 0;
      List<StringParts> ls = new List<StringParts>();
      int startat = 0;

      while (source.Length > 0)
      {
        if (source.Length > 1 && source[0] == '-' && source[1] == '-')
        {
          StringParts tok = new StringParts();
          tok.position = startat;
          x = source.IndexOf('\n');
          if (x == -1) tok.value = source;
          else tok.value = source.Substring(0, x + 1);

          //ls.Add(tok);
          source = source.Substring(tok.value.Length);
          startat += tok.value.Length;
          continue;
        }
        else if (source.Length > 1 && source[0] == '/' && source[1] == '*')
        {
          StringParts tok = new StringParts();
          tok.position = startat;
          x = source.IndexOf("*/", StringComparison.Ordinal);
          if (x == -1) tok.value = source;
          else tok.value = source.Substring(0, x + 2);

          //ls.Add(tok);
          source = source.Substring(tok.value.Length);
          startat += tok.value.Length;
          continue;
        }
        int comment = source.IndexOf("--", n, StringComparison.Ordinal);
        if (comment == -1) comment = source.IndexOf("/*", n, StringComparison.Ordinal);

        if (n > 0)
          n = source.IndexOfAny(opens2, n);
        else
          n = source.IndexOfAny(opens, n);

        if (comment > -1 && (n == -1 || comment < n))
          n = comment;

        if (n == -1) break;

        x = opensstr.IndexOf(source[n]);
        if (x != -1)
        {
          while (n != -1)
          {
            n = source.IndexOf(closes[x], n + 1);
            if (n == -1)
              break;

            if (n < source.Length - 1 && source[n + 1] == source[n])
            {
              startat++;
              source = source.Remove(n, 1);
            }
            else
            {
              n++;
              break;
            }
          }
          if (n == -1)
            break;
        }
        else
        {
          StringParts tok = new StringParts();

          int y = sep.IndexOf(source[n]);
          tok.sep = (y != -1);
          tok.sepchar = (y != -1) ? sep[y] : '\0';

          if (source[n] == '(') depth++;
          tok.depth = depth;
          if (source[n] == ')') depth--;

          tok.value = source.Substring(0, n);
          tok.position = startat;

          if (tok.value.Length > 1)
          {
            x = opensstr.IndexOf(tok.value[0]);
            if (x != -1 && tok.value[tok.value.Length - 1] == closes[x])
            {
              tok.quote = String.Format(CultureInfo.InvariantCulture, "{0}{1}", tok.value[0], tok.value[tok.value.Length - 1]);
              tok.value = tok.value.Substring(1, tok.value.Length - 2);
            }
            else
              tok.keyword = tok.value.ToUpperInvariant();
          }

          if (source.Length - n > 1 && ((source[n] == '-' && source[n + 1] == '-') || source[n] == '/' && source[n + 1] == '*'))
          {
            startat += n;
            source = source.Substring(n);
          }
          else
          {
            startat += (n + 1);
            source = source.Substring(n + 1);
          }
          if (tok.value.Length > 0)
            ls.Add(tok);
          else if (ls.Count > 0 && tok.sep)
          {
            StringParts prev = ls[ls.Count - 1];
            ls.RemoveAt(ls.Count - 1);
            prev.sep = tok.sep;
            prev.sepchar = tok.sepchar;
            ls.Add(prev);
          }
          n = 0;
        }
      }

      if (source.Length > 0)
      {
        StringParts tok = new StringParts();

        tok.value = source.Trim();
        tok.position = startat;

        if (tok.value.Length > 1)
        {
          x = opensstr.IndexOf(tok.value[0]);
          if (x != -1 && tok.value[tok.value.Length - 1] == closes[x])
          {
            tok.quote = String.Format(CultureInfo.InvariantCulture, "{0}{1}", tok.value[0], tok.value[tok.value.Length - 1]);
            tok.value = tok.value.Substring(1, tok.value.Length - 2);
          }
          else
            tok.keyword = tok.value.ToUpperInvariant();
        }
        if (tok.value.Length > 0) ls.Add(tok);
      }

      StringParts[] ar = new StringParts[ls.Count];
      ls.CopyTo(ar, 0);

      return ar;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































Deleted SQLite.Designer/Design/Table.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Data.Common;
  using System.ComponentModel.Design;
  using System.ComponentModel;
  using System.Drawing.Design;
  using System.Collections.Generic;
  using System.Data;
  using System.Text;
  using System.Globalization;
  using SQLite.Designer.Editors;

  internal abstract class ViewTableBase: IHaveConnection
  {
    public abstract string OldName { get; }
    public abstract string Name { get; set; }
    public abstract string Catalog { get; }
    public abstract object Triggers { get; }
    public abstract void MakeDirty();
    public abstract DbConnection GetConnection();
    public abstract ViewTableBase DesignTable { get; }
  }

  internal class Table : ViewTableBase, ICustomTypeDescriptor
  {
    private string _name;
    private string _oldname;
    private string _catalog;
    private List<Column> _columns = new List<Column>();
    private bool _exists;
    private string _origSql = String.Empty;
    private List<Index> _indexes = new List<Index>();
    private List<Index> _oldindexes = new List<Index>();
    private List<ForeignKey> _fkeys = new List<ForeignKey>();
    private List<ForeignKey> _oldfkeys = new List<ForeignKey>();
    private List<string> _check = new List<string>();
    private List<Trigger> _triggers = new List<Trigger>();
    private List<Trigger> _oldtriggers = new List<Trigger>();
    private PrimaryKey _key;
    internal TableDesignerDoc _owner;
    internal DbConnection _connection;

    internal Table(string tableName, DbConnection connection, TableDesignerDoc owner)
    {
      _owner = owner;
      _oldname = tableName;
      _connection = connection;
      _name = tableName;
      _owner.Name = _name;
      _catalog = _connection.Database; // main

      ReloadDefinition();

      if (_key == null) _key = new PrimaryKey(_connection, this, null);

      if (_exists)
      {
        using (DataTable tbl = connection.GetSchema("ForeignKeys", new string[] { Catalog, null, Name }))
        {
          foreach (DataRow row in tbl.Rows)
          {
            _fkeys.Add(new ForeignKey(connection, this, row));
            _oldfkeys.Add(new ForeignKey(connection, this, row));
          }
        }
      }

      using (DataTable tbl = connection.GetSchema("Columns", new string[] { Catalog, null, Name }))
      {
        foreach (DataRow row in tbl.Rows)
        {
          _columns.Add(new Column(row, this));
        }
      }
    }

    public override void MakeDirty()
    {
      _owner.MakeDirty();
    }

    private void ReloadDefinition()
    {
      using (DataTable tbl = _connection.GetSchema("Tables", new string[] { Catalog, null, Name }))
      {
        if (tbl.Rows.Count > 0)
        {
          _exists = true;
          _origSql = tbl.Rows[0]["TABLE_DEFINITION"].ToString().Trim().TrimEnd(';');
          _oldname = Name;
        }
        else
        {
          _exists = false;
          return;
        }
      }
      
      _indexes.Clear();
      _oldindexes.Clear();

      using (DataTable tbl = _connection.GetSchema("Indexes", new string[] { Catalog, null, Name }))
      {
        foreach (DataRow row in tbl.Rows)
        {
          if ((bool)row["PRIMARY_KEY"] == false)
          {
            if (row["INDEX_NAME"].ToString().StartsWith("sqlite_", StringComparison.OrdinalIgnoreCase) == false)
            {
              _indexes.Add(new Index(_connection, this, row));
              _oldindexes.Add(new Index(_connection, this, row));
            }
          }
          else if (_key == null)
          {
            _key = new PrimaryKey(_connection, this, row);
          }
        }
      }

      _check.Clear();
      StringBuilder builder = new StringBuilder();
      SimpleTokenizer.StringParts[] arr = SimpleTokenizer.BreakString(_origSql);
      for (int n = 0; n < arr.Length - 3; n++)
      {
        if (arr[n].keyword == "CONSTRAINT")
        {
          builder.Length = 0;
          int x;
          for (x = 1; x < 3; x++)
          {
            if (arr[n + x].keyword == "CHECK")
              break;
          }
          if (x == 3)
          {
            n += 2;
            continue;
          }
          x += n + 1;
          int depth = arr[n].depth;
          int basedepth = arr[x].depth;
          for (; x < arr.Length; x++)
          {
            if (arr[x].depth < basedepth)
              break;

            if (builder.Length > 0)
              builder.Append(" ");

            while (depth < arr[x].depth)
            {
              builder.Append("(");
              depth++;
            }
            while (depth > arr[x].depth)
            {
              builder.Append(")");
              depth--;
            }

            if (String.IsNullOrEmpty(arr[x].quote) == false)
              builder.Append(arr[x].quote[0]);
            builder.Append(arr[x].value);
            if (String.IsNullOrEmpty(arr[x].quote) == false)
              builder.Append(arr[x].quote[1]);

            if (arr[x].sep == true) break;
          }
          while (depth > arr[n].depth)
          {
            builder.Append(")");
            depth--;
          }
          n = x;
          _check.Add(builder.ToString());
        }
      }

      builder.Length = 0;
      builder.AppendLine("-- Original table schema");
      builder.Append(_origSql);

      builder.AppendLine(";");
      foreach (Index idx in _oldindexes)
      {
        builder.AppendFormat("{0};\r\n", idx.OriginalSql);
      }

      _triggers.Clear();
      _oldtriggers.Clear();

      using (DataTable tbl = _connection.GetSchema("Triggers", new string[] { Catalog, null, Name }))
      {
        foreach (DataRow row in tbl.Rows)
        {
          Trigger t = new Trigger(this, row);
          _triggers.Add(t);
          _oldtriggers.Add(((ICloneable)t).Clone() as Trigger);

          builder.AppendFormat("{0};\r\n", t.OriginalSql);
        }
      }

      _origSql = builder.ToString();
    }

    internal void Committed()
    {
      _exists = true;
      ReloadDefinition();

      foreach (Column c in Columns)
        c.Committed();

      foreach (ForeignKey key in ForeignKeys)
        key.ClearDirty();

      foreach (Index idx in Indexes)
        idx.ClearDirty();

      if (PrimaryKey != null)
        PrimaryKey.ClearDirty();
    }

    [Browsable(false)]
    public List<Index> Indexes
    {
      get { return _indexes; }
    }

    [Browsable(false)]
    public PrimaryKey PrimaryKey
    {
      get { return _key; }
      set
      {
        _key = value;
        _owner.Invalidate();
      }
    }

    [Browsable(false)]
    public List<ForeignKey> ForeignKeys
    {
      get { return _fkeys; }
    }

    [Browsable(false)]
    public List<string> Check
    {
      get { return _check; }
    }

    [Browsable(false)]
    public override object Triggers
    {
      get { return _triggers; }
    }

    [Browsable(false)]
    public string OriginalSql
    {
      get { return _origSql; }
    }

    [Category("Storage")]
    [RefreshProperties(RefreshProperties.All)]
    [ParenthesizePropertyName(true)]
    [NotifyParentProperty(true)]
    public override string Name
    {
      get { return _name; }
      set
      {
        if (_name != value)
        {
          _name = value;
          _owner.Name = value;
          _owner.MakeDirty();
        }
      }
    }

    [Browsable(false)]
    public override string OldName
    {
      get { return _oldname; }
    }

    public override string ToString()
    {
      return String.Format(CultureInfo.InvariantCulture, "[{0}].[{1}]", Catalog, Name);
    }

    [Category("Storage")]
    [Editor(typeof(CatalogTypeEditor), typeof(UITypeEditor))]
    [DefaultValue("main")]
    [RefreshProperties(RefreshProperties.All)]
    public override string Catalog
    {
      get { return _catalog; }
    }

    [Category("Storage")]
    public string Database
    {
      get { return _connection.DataSource; }
    }

    [Browsable(false)]
    public List<Column> Columns
    {
      get { return _columns; }
    }

    public string GetSql()
    {
      StringBuilder builder = new StringBuilder();
      string altName = null;

      if (_exists)
      {
        Guid g = Guid.NewGuid();
        altName = String.Format(CultureInfo.InvariantCulture, "{0}_{1}", Name, g.ToString("N"));

        if (_oldindexes.Count > 0)
        {
          builder.Append("-- Drop previous indexes on the table\r\n");
          foreach (Index idx in _oldindexes)
          {
            builder.AppendFormat("DROP INDEX [{0}].[{1}];\r\n", _catalog, idx.Name);
          }
          builder.AppendLine();
        }

        if (_oldtriggers.Count > 0)
        {
          builder.Append("-- Drop previous triggers on the table\r\n");
          foreach (Trigger trig in _oldtriggers)
          {
            builder.AppendFormat("DROP TRIGGER [{0}].[{1}];\r\n", _catalog, trig.Name);
          }
          builder.AppendLine();
        }

        builder.Append("-- Rename the old table\r\n");
        builder.AppendFormat("ALTER TABLE [{0}].[{1}] RENAME TO [{2}];\r\n\r\n", _catalog, _oldname, altName);
      }

      builder.Append("-- Create the new table\r\n");
      builder.AppendFormat("CREATE TABLE [{0}].[{1}] (\r\n", _catalog, Name);
      string separator = "    ";

      foreach (Column c in Columns)
      {
        if (String.IsNullOrEmpty(c.ColumnName) == false)
        {
          builder.Append(separator);
          c.WriteSql(builder);
          separator = ",\r\n    ";
        }
      }

      if (_key.Columns.Count > 1)
      {
        string innersep = "";
        builder.AppendFormat(CultureInfo.InvariantCulture, "{0}CONSTRAINT [PK_{1}] PRIMARY KEY (", separator, Name);
        foreach (IndexColumn c in _key.Columns)
        {
          builder.AppendFormat(CultureInfo.InvariantCulture, "{0}[{1}]", innersep, c.Column);
          if (String.IsNullOrEmpty(c.Collate) == false && String.Compare(c.Collate, "BINARY", StringComparison.OrdinalIgnoreCase) != 0)
            builder.AppendFormat(CultureInfo.InvariantCulture, " COLLATE {0}", c.Collate.ToUpperInvariant());

          if (c.SortMode != ColumnSortMode.Ascending)
            builder.Append(" DESC");

          innersep = ", ";
        }
        builder.Append(")");

        if (_key.Conflict != ConflictEnum.Abort)
          builder.AppendFormat(CultureInfo.InvariantCulture, " ON CONFLICT {0}", _key.Conflict.ToString().ToUpperInvariant());
      }

      for (int n = 0; n < Check.Count; n++)
      {
        string check = Check[n];

        if (String.IsNullOrEmpty(check) == true) continue;
        SimpleTokenizer.StringParts[] arr = SimpleTokenizer.BreakString(check);
        for (int x = 0; x < arr.Length; x++)
        {
          if (arr[x].depth == 0)
          {
            check = String.Format(CultureInfo.InvariantCulture, "({0})", check);
            break;
          }
        }
        builder.Append(separator);
        builder.AppendFormat("CONSTRAINT [CK_{0}_{1}] CHECK {2}", Name, n + 1, check);
      }

      List<ForeignKey> keys = new List<ForeignKey>();

      for (int x = 0; x < ForeignKeys.Count; x++)
      {
        ForeignKey key = ForeignKeys[x];

        if (String.IsNullOrEmpty(key.From.Column) == true || String.IsNullOrEmpty(key.From.Catalog) == true ||
          String.IsNullOrEmpty(key.To.Table) == true || String.IsNullOrEmpty(key.To.Column) == true)
          continue;

        if (keys.Count > 0)
        {
          if (keys[0].Name == key.Name && keys[0].To.Catalog == key.To.Catalog && keys[0].To.Table == key.To.Table)
          {
            keys.Add(key);
            continue;
          }
          builder.Append(separator);
          WriteFKeys(keys, builder);
          keys.Clear();
        }
        keys.Add(key);
      }

      if (keys.Count > 0)
      {
        builder.Append(separator);
        WriteFKeys(keys, builder);
      }

      builder.Append("\r\n);\r\n");

      // Rebuilding an existing table
      if (altName != null)
      {
        separator = "";
        builder.Append("\r\n-- Copy the contents of the old table into the new table\r\n");
        builder.AppendFormat("INSERT INTO [{0}].[{1}] (", _catalog, Name);
        foreach (Column c in Columns)
        {
          if (String.IsNullOrEmpty(c.OriginalName) == false)
          {
            builder.AppendFormat("{1}[{0}]", c.ColumnName, separator);
            separator = ", ";
          }
        }
        builder.Append(")\r\n  SELECT ");
        separator = "";
        foreach (Column c in Columns)
        {
          if (String.IsNullOrEmpty(c.OriginalName) == false)
          {
            builder.AppendFormat("{1}[{0}]", c.OriginalName, separator);
            separator = ", ";
          }
        }
        builder.AppendFormat("\r\n  FROM [{0}].[{1}];\r\n\r\n", _catalog, altName);

        builder.Append("-- Drop the old table\r\n");
        builder.AppendFormat("DROP TABLE [{0}].[{1}];\r\n", _catalog, altName);
      }

      separator = "\r\n";
      if (_indexes.Count > 0)
      {
        builder.Append("\r\n-- Create the new indexes");
        foreach (Index idx in _indexes)
        {
          builder.Append(separator);
          idx.WriteSql(builder);
        }
        builder.AppendLine();
      }

      if (_triggers.Count > 0)
      {
        builder.Append("\r\n-- Create the new triggers");
        foreach (Trigger trig in _triggers)
        {
          builder.Append(separator);
          trig.WriteSql(builder);
          separator = "\r\n";
        }
        builder.AppendLine();
      }

      return builder.ToString();
    }

    private void WriteFKeys(List<ForeignKey> keys, StringBuilder builder)
    {
      builder.AppendFormat("CONSTRAINT [{0}] FOREIGN KEY (", keys[0].Name);
      string separator = "";

      foreach (ForeignKey key in keys)
      {
        builder.AppendFormat("{0}[{1}]", separator, key.From.Column);
        separator = ", ";
      }

      builder.AppendFormat(") REFERENCES [{0}] (", keys[0].To.Table);

      separator = "";
      foreach (ForeignKey key in keys)
      {
        builder.AppendFormat("{0}[{1}]", separator, key.To.Column);
        separator = ", ";
      }
      builder.Append(")");

      if (!String.IsNullOrEmpty(keys[0].Match))
          builder.AppendFormat(" MATCH {0}", keys[0].Match);

      if (!String.IsNullOrEmpty(keys[0].OnUpdate))
          builder.AppendFormat(" ON UPDATE {0}", keys[0].OnUpdate);

      if (!String.IsNullOrEmpty(keys[0].OnDelete))
          builder.AppendFormat(" ON DELETE {0}", keys[0].OnDelete);
    }

    [Browsable(false)]
    public override ViewTableBase DesignTable
    {
      get { return this; }
    }

    public override DbConnection GetConnection()
    {
      return _connection;
    }

    #region ICustomTypeDescriptor Members

    AttributeCollection ICustomTypeDescriptor.GetAttributes()
    {
      return TypeDescriptor.GetAttributes(GetType());
    }

    string ICustomTypeDescriptor.GetClassName()
    {
      return "Table Design";
    }

    string ICustomTypeDescriptor.GetComponentName()
    {
      return ToString();
    }

    TypeConverter ICustomTypeDescriptor.GetConverter()
    {
      return TypeDescriptor.GetConverter(GetType());
    }

    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
    {
      return TypeDescriptor.GetDefaultEvent(GetType());
    }

    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
    {
      return TypeDescriptor.GetDefaultProperty(GetType());
    }

    object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
    {
      return TypeDescriptor.GetEditor(GetType(), editorBaseType);
    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
    {
      return TypeDescriptor.GetEvents(GetType(), attributes);
    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
    {
      return TypeDescriptor.GetEvents(GetType());
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
    {
      return TypeDescriptor.GetProperties(GetType(), attributes);
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
    {
      return TypeDescriptor.GetProperties(GetType());
    }

    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
    {
      return this;
    }

    #endregion
  }

  internal interface IHaveConnection
  {
    DbConnection GetConnection();
    [Browsable(false)]
    ViewTableBase DesignTable { get; }
  }

  internal interface IHaveConnectionScope : IHaveConnection
  {
    [Browsable(false)]
    string CatalogScope { get; }
    [Browsable(false)]
    string TableScope { get; }
  }

  internal class CollationTypeEditor : ObjectSelectorEditor
  {
    public override bool IsDropDownResizable
    {
      get
      {
        return true;
      }
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
      return UITypeEditorEditStyle.DropDown;
    }

    protected override void FillTreeWithData(Selector selector, ITypeDescriptorContext context, IServiceProvider provider)
    {
      base.FillTreeWithData(selector, context, provider);
      selector.AddNode("BINARY", "BINARY", null);
      selector.AddNode("NOCASE", "NOCASE", null);
    }
  }

  internal class CatalogTypeEditor : ObjectSelectorEditor
  {
    public override bool IsDropDownResizable
    {
      get
      {
        return true;
      }
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
      return UITypeEditorEditStyle.DropDown;
    }

    protected override void FillTreeWithData(Selector selector, ITypeDescriptorContext context, IServiceProvider provider)
    {
      base.FillTreeWithData(selector, context, provider);
      IHaveConnection source = context.Instance as IHaveConnection;

      if (source == null) return;

      using (DataTable table = source.GetConnection().GetSchema("Catalogs"))
      {
        foreach (DataRow row in table.Rows)
        {
          selector.AddNode(row[0].ToString(), row[0], null);
        }
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/Design/Trigger.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Collections.Generic;
  using System.Collections;
  using System.Text;
  using System.ComponentModel;
  using System.ComponentModel.Design;
  using System.Windows.Forms;
  using System.Drawing.Design;
  using System.Data;
  using System.Data.Common;
  using System.Globalization;

  public enum TriggerOccurs
  {
    Before = 0,
    After = 1,
  }
  
  public enum ViewTriggerOccurs
  {
    InsteadOf = 2
  }

  public enum TriggerType
  {
    Delete = 0,
    Insert = 1,
    Update = 2,
  }

  internal class ViewTrigger : Trigger, ICloneable
  {
    internal ViewTrigger(ViewTrigger source)
      : base(source)
    {
      _triggerOccurs = (int)ViewTriggerOccurs.InsteadOf;
    }

    internal ViewTrigger(ViewTableBase parent, DataRow row)
      : base(parent, row)
    {
      _triggerOccurs = (int)ViewTriggerOccurs.InsteadOf;
    }

    [Browsable(true)]
    [DefaultValue(ViewTriggerOccurs.InsteadOf)]
    [Category("Event")]
    [Description("Determines when the trigger fires.  For tables, Before or After are supported.  For views, Instead Of is the only option.")]
    public new ViewTriggerOccurs Occurs
    {
      get
      {
        return ViewTriggerOccurs.InsteadOf;
      }
    }

    #region ICloneable Members

    object ICloneable.Clone()
    {
      return new ViewTrigger(this);
    }

    #endregion
  }

  [DefaultProperty("SQL")]
  internal class Trigger : IHaveConnection, ICloneable
  {
    protected int _triggerOccurs;
    private TriggerType _type = TriggerType.Update;
    //private bool _eachRow;
    private string _when;
    private ViewTableBase _table;
    private string _name;
    private string _columns;
    private string _action;
    private bool _calcname;
    private string _origsql;
    private bool _dirty;

    protected Trigger(Trigger source)
    {
      _triggerOccurs = source._triggerOccurs;
      _type = source._type;
      //_eachRow = source._eachRow;
      _when = source._when;
      _table = source._table;
      _name = source._name;
      _columns = source._columns;
      _action = source._action;
      _dirty = source._dirty;
    }

    internal void MakeDirty()
    {
      _dirty = true;
    }

    [Browsable(false)]
    internal bool IsDirty
    {
      get { return _dirty; }
    }

    internal void ClearDirty()
    {
      _dirty = false;
    }

    internal virtual void WriteSql(StringBuilder builder)
    {
      WriteSql(builder, false);
    }

    private void WriteSql(StringBuilder builder, bool temp)
    {
      string name = Name;

      if (temp == true)
        name = String.Format(CultureInfo.InvariantCulture, "{0}_{1}", name, Guid.NewGuid().ToString("N"));

      builder.AppendFormat(CultureInfo.InvariantCulture, "CREATE TRIGGER [{0}].[{1}]", _table.Catalog, name);
      switch (_triggerOccurs)
      {
        case 0:
          builder.Append(" BEFORE");
          break;
        case 1:
          builder.Append(" AFTER");
          break;
        case 2:
          builder.Append(" INSTEAD OF");
          break;
      }

      builder.AppendFormat(CultureInfo.InvariantCulture, " {0}", _type.ToString().ToUpperInvariant());
      if (_type == TriggerType.Update && String.IsNullOrEmpty(Columns) == false)
        builder.AppendFormat(CultureInfo.InvariantCulture, " OF {0}", Columns);

      builder.AppendFormat(CultureInfo.InvariantCulture, " ON [{0}].[{1}]", _table.Catalog, _table.Name);

      if (EachRow)
        builder.Append(" FOR EACH ROW");
      if (String.IsNullOrEmpty(When) == false)
        builder.AppendFormat(CultureInfo.InvariantCulture, " WHEN {0}", When);

      builder.AppendFormat(CultureInfo.InvariantCulture, "\r\nBEGIN\r\n{0}", SQL);
      SimpleTokenizer.StringParts[] arr = SimpleTokenizer.BreakString(SQL);
      if (arr[arr.Length - 1].sepchar != ';')
        builder.Append(";");

      builder.Append("\r\nEND;");
    }

    [DefaultValue(TriggerOccurs.Before)]
    [Category("Event")]
    [Description("Determines when the trigger fires.  For tables, Before or After are supported.  For views, Instead Of is the only option.")]
    public virtual TriggerOccurs Occurs
    {
      get { return (TriggerOccurs)_triggerOccurs; }
      set
      {
        if (_triggerOccurs != (int)value)
        {
          _triggerOccurs = (int)value;
          MakeDirty();
        }
      }
    }

    [DefaultValue(TriggerType.Update)]
    [Category("Event")]
    [Description("Determines what type of operation the trigger applies to.  Can be either Insert, Update or Delete.")]
    public TriggerType Type
    {
      get { return _type; }
      set
      {
        if (_type != value)
        {
          _type = value;
          MakeDirty();
        }
      }
    }

    [DefaultValue(true)]
    [Category("Event")]
    [Description("When set to true, the trigger will fire for each row in an update, insert or delete operation.")]
    public bool EachRow
    {
      get { return true; }
      //get { return _eachRow; }
      //set { _eachRow = value; }
    }

    [Category("Constraint")]
    [Description("Limits the exection of the trigger so it only occurs when the expression evaluates to True.")]
    public string When
    {
      get { return _when; }
      set
      {
        if (_when != value)
        {
          _when = value;
          MakeDirty();
        }
      }
    }

    [Browsable(false)]
    protected virtual string NamePrefix
    {
      get { return "TRG"; }
    }

    [Browsable(false)]
    protected virtual string NewName
    {
      get { return "NewTrigger"; }
    }

    [Browsable(false)]
    internal ViewTableBase ViewTableBase
    {
      get { return _table; }
    }

    [ParenthesizePropertyName(true)]
    [Category("Identity")]
    [Description("The name of the trigger")]
    public string Name
    {
      get
      {
        if (String.IsNullOrEmpty(_name))
        {
          if (_calcname == true) return GetHashCode().ToString();

          string name = String.Format(CultureInfo.InvariantCulture, "{0}_{1}", NamePrefix, NewName);
          int count = 0;
          string proposed = name;

          _calcname = true;
          for (int n = 0; n < ((IList)_table.Triggers).Count; n++)
          {
            Trigger idx = ((IList)_table.Triggers)[n] as Trigger;
            proposed = string.Format(CultureInfo.InvariantCulture, "{0}{1}", name, (count > 0) ? count.ToString() : "");
            if (idx.Name == proposed)
            {
              count++;
              n = -1;
            }
          }
          _calcname = false;
          return proposed;
        }
        return _name;
      }
      set
      {
        if (_name != value)
        {
          _name = value;
          MakeDirty();
        }
      }
    }

    [Editor(typeof(ColumnsMultiSelectEditor), typeof(UITypeEditor))]
    [Category("Event")]
    [DisplayName("Update Columns")]
    [Description("Limit the trigger to only occur when updating these columns")]
    public string Columns
    {
      get { return _columns; }
      set
      {
        if (_columns != value)
        {
          _columns = value;
          MakeDirty();
        }
      }
    }

    [Category("Action")]
    [Description("The SQL to execute for this trigger")]
    public string SQL
    {
      get { return _action; }
      set
      {
        //using (DbTransaction trans = GetConnection().BeginTransaction())
        //using (DbCommand cmd = GetConnection().CreateCommand())
        //{
        //  StringBuilder builder = new StringBuilder();
        //  WriteSql(builder, true);
        //  cmd.CommandText = builder.ToString();

        //  cmd.ExecuteNonQuery();
        //  trans.Rollback();
        //}
        if (_action != value)
        {
          _action = value;
          MakeDirty();
        }
      }
    }

    [Browsable(false)]
    public string OriginalSql
    {
      get { return _origsql; }
    }

    internal Trigger(ViewTableBase parent, DataRow row)
    {
      _table = parent;
      if (row != null)
      {
        _name = row["TRIGGER_NAME"].ToString();

        string sql = row["TRIGGER_DEFINITION"].ToString();
        _origsql = sql;
        SimpleTokenizer.StringParts[] arr = SimpleTokenizer.BreakString(sql);

        int x = 3;
        switch (arr[x].keyword)
        {
          case "BEFORE":
            _triggerOccurs = 0;
            break;
          case "AFTER":
            _triggerOccurs = 1;
            break;
          case "INSTEAD":
            _triggerOccurs = 2;
            x++;
            break;
          default:
            x--;
            break;
        }
        x++;

        switch (arr[x].keyword)
        {
          case "UPDATE":
            _type = TriggerType.Update;
            if (arr[x + 1].keyword == "OF")
            {
              x++;
              StringBuilder builder = new StringBuilder();
              string separator = "";
              while (arr[x + 1].keyword != "ON")
              {
                builder.AppendFormat("{0}[{1}]", separator, arr[x + 1].value);
                separator = ", ";
                x++;
              }
              _columns = builder.ToString();
            }
            break;
          case "INSERT":
            _type = TriggerType.Insert;
            break;
          case "DELETE":
            _type = TriggerType.Delete;
            break;
        }
        x++;

        while (arr[x].keyword != "BEGIN")
        {
          if (arr[x].keyword == "FOR" && arr[x + 1].keyword == "EACH" && arr[x + 1].keyword == "ROW")
          {
            //_eachRow = true;
            x += 3;
            continue;
          }

          if (arr[x].keyword == "WHEN")
          {
            x++;
            int depth = 0;
            StringBuilder builder = new StringBuilder();
            while (arr[x].keyword != "BEGIN")
            {
              if (builder.Length > 0) builder.Append(" ");
              while (depth < arr[x].depth)
              {
                depth++;
                builder.Append("(");
              }
              while (depth > arr[x].depth)
              {
                depth--;
                builder.Append(")");
              }

              if (String.IsNullOrEmpty(arr[x].quote) == false)
                builder.Append(arr[x].quote[0]);
              builder.Append(arr[x].value);
              if (String.IsNullOrEmpty(arr[x].quote) == false)
                builder.Append(arr[x].quote[1]);
              x++;
            }
            while (depth > 0)
            {
              depth--;
              builder.Append(")");
            }
            _when = builder.ToString();
            break;
          }
          x++;
        }

        int startpos = arr[x].position + arr[x].value.Length;

        x = arr.Length - 1;
        while (arr[x].keyword != "END")
        {
          x--;
        }
        int endpos = arr[x].position;

        _action = sql.Substring(startpos, endpos - startpos);
        _action = _action.TrimStart('\r').TrimStart('\n').TrimEnd('\n').TrimEnd('\r').Trim();
      }
    }

    #region IHaveConnection Members

    [Browsable(false)]
    public ViewTableBase DesignTable
    {
      get { return _table; }
    }

    public DbConnection GetConnection()
    {
      return ((IHaveConnection)_table).GetConnection();
    }

    #endregion

    #region ICloneable Members

    object ICloneable.Clone()
    {
      return new Trigger(this);
    }

    #endregion
  }

  internal class TriggerEditor : CollectionEditor
  {
    ViewTableBase _table;
    object[] _items;
    object[] _orig;
    CollectionEditor.CollectionForm _form;
    int _count;

    internal TriggerEditor(ViewTableBase parent)
      : base((parent is View) ? typeof(List<ViewTrigger>) :  typeof(List<Trigger>))
    {
      _table = parent;
    }

    protected override CollectionEditor.CollectionForm CreateCollectionForm()
    {
      _form = base.CreateCollectionForm();
      _form.Text = "Trigger Editor";
      foreach (Control c in _form.Controls[0].Controls)
      {
        PropertyGrid grid = c as PropertyGrid;
        if (grid != null)
        {
          grid.HelpVisible = true;
          break;
        }
      }
      _form.Width = (int)(_form.Width * 1.25);
      _form.Height = (int)(_form.Height * 1.25);
      return _form;
    }

    protected override object CreateInstance(Type itemType)
    {
      if (itemType == typeof(Trigger))
      {
        return new Trigger(_table, null);
      }
      else if (itemType == typeof(ViewTrigger))
      {
        return new ViewTrigger(_table, null);
      }
      throw new NotSupportedException();
    }

    protected override object[] GetItems(object editValue)
    {
      if (_items == null)
      {
        IList value = editValue as IList;
        _items = new object[value.Count];
        _orig = new object[value.Count];
        for (int n = 0; n < _items.Length; n++)
        {
          _items[n] = ((ICloneable)value[n]).Clone();
          _orig[n] = value[n];
        }
        _count = _items.Length;
      }
      return _items;
    }

    protected override object SetItems(object editValue, object[] value)
    {
      bool dirty = false;
      if (_form.DialogResult == DialogResult.Cancel)
        value = _orig;

      if (editValue != null)
      {
        if (!(editValue is IList))
        {
          return editValue;
        }
        IList list = (IList)editValue;
        list.Clear();
        for (int i = 0; i < value.Length; i++)
        {
          Trigger trig = value[i] as Trigger;

          if (trig != null && String.IsNullOrEmpty(trig.SQL) == false)
          {
            if (trig.IsDirty) dirty = true;
            trig.Name = trig.Name;
            list.Add(trig);
          }
        }

        if ((dirty == true || list.Count != _count) && _form.DialogResult == DialogResult.OK)
          _table.MakeDirty();
      }

      return editValue;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/Design/Unique.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.ComponentModel;
  using System.Data;
  using System.Data.Common;
  using System.Globalization;

  [TypeConverter(typeof(ExpandableObjectConverter))]
  [DefaultProperty("Enabled")]
  internal class Unique : IHaveConnection
  {
    private bool _isUnique;
    private ConflictEnum _conflict = ConflictEnum.Abort;
    private Column _column;

    internal Unique(Column col)
      : this(col, null)
    {
    }

    internal Unique(Column col, DataRow row)
    {
      _column = col;
      if (row != null)
      {
        _isUnique = (row.IsNull("UNIQUE") == false) ? (bool)row["UNIQUE"] : false;
      }
    }

    #region IHaveConnection Members

    [Browsable(false)]
    public ViewTableBase DesignTable
    {
      get { return _column.DesignTable; }
    }

    public DbConnection GetConnection()
    {
      return ((IHaveConnection)_column).GetConnection();
    }

    #endregion


    [DefaultValue(false)]
    [DisplayName("Enabled")]
    [RefreshProperties(RefreshProperties.All)]
    [Description("When enabled, all values entered into this column must be unique.")]
    public bool Enabled
    {
      get { return _isUnique; }
      set
      {
        if (value != _isUnique)
        {
          _isUnique = value;
          _column.Table._owner.MakeDirty();
        }
      }
    }

    [DefaultValue(ConflictEnum.Abort)]
    [DisplayName("On Conflict")]
    [RefreshProperties(RefreshProperties.All)]
    [Description("Specifies what action to take when the unique constraint on the column is violated.")]
    public ConflictEnum Conflict
    {
      get { return _conflict; }
      set
      {
        if (_conflict != value)
        {
          _conflict = value;
          
          if (_conflict != ConflictEnum.Abort && _isUnique == false)
            _isUnique = true;

          _column.Table._owner.MakeDirty();
        }
      }
    }

    public override string ToString()
    {
      if (_isUnique == false)
        return Convert.ToString(false, CultureInfo.InvariantCulture);
      else
        return String.Format(CultureInfo.InvariantCulture, "{0} ({1})", Convert.ToString(true, CultureInfo.InvariantCulture), Convert.ToString(Conflict, CultureInfo.InvariantCulture));
        //return Convert.ToString(true);
    }
  }

  public enum ConflictEnum
  {
    Abort = 2,
    Rollback = 0,
    Fail = 3,
    Ignore = 4,
    Replace = 5,
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































Deleted SQLite.Designer/Design/View.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Design
{
  using System;
  using System.Data.Common;
  using System.ComponentModel.Design;
  using System.ComponentModel;
  using System.Drawing.Design;
  using System.Collections.Generic;
  using System.Data;
  using System.Text;
  using System.Globalization;
  using SQLite.Designer.Editors;

  internal class View : ViewTableBase, ICustomTypeDescriptor
  {
    private string _name;
    private string _oldname;
    private string _sql;
    private string _oldsql;
    private ViewDesignerDoc _owner;
    private string _catalog;
    private DbConnection _connection;
    List<ViewTrigger> _triggers = new List<ViewTrigger>();
    List<ViewTrigger> _oldtriggers = new List<ViewTrigger>();

    internal View(string viewName, DbConnection connection, ViewDesignerDoc parent)
    {
      _owner = parent;
      _name = viewName;
      _oldname = viewName;
      _catalog = connection.Database;
      _connection = connection;
      _owner.Name = _name;

      if (String.IsNullOrEmpty(viewName) == false)
      {
        using (DataTable tbl = connection.GetSchema("Views", new string[] { Catalog, null, Name }))
        {
          if (tbl.Rows.Count > 0)
          {
            _sql = tbl.Rows[0]["VIEW_DEFINITION"].ToString();

            StringBuilder builder = new StringBuilder();
            builder.Append(_sql);
            builder.AppendLine(";");

            _triggers.Clear();
            _oldtriggers.Clear();

            using (DataTable ttbl = _connection.GetSchema("Triggers", new string[] { Catalog, null, Name }))
            {
              foreach (DataRow row in ttbl.Rows)
              {
                ViewTrigger t = new ViewTrigger(this, row);
                _triggers.Add(t);
                _oldtriggers.Add(((ICloneable)t).Clone() as ViewTrigger);

                builder.AppendFormat("{0};\r\n", t.OriginalSql);
              }
            }
            _oldsql = builder.ToString();
          }
          else
          {
            _oldname = null;
          }
        }
      }
    }

    public override void MakeDirty()
    {
      _owner.MakeDirty();
    }

    [Browsable(false)]
    public override object Triggers
    {
      get { return _triggers; }
    }

    public void Committed()
    {
      _oldsql = _sql;
      _oldname = _name;

      _oldtriggers = _triggers;
      _triggers.Clear();
      foreach (ViewTrigger trig in _oldtriggers)
      {
        _triggers.Add(((ICloneable)trig).Clone() as ViewTrigger);
      }
    }

    public override string ToString()
    {
      return String.Format(CultureInfo.InvariantCulture, "[{0}].[{1}]", Catalog, Name);
    }

    [Category("Storage")]
    [RefreshProperties(RefreshProperties.All)]
    [ParenthesizePropertyName(true)]
    public override string Name
    {
      get { return _name; }
      set
      {
        if (_name != value)
        {
          _name = value;
          _owner.Name = value;
          _owner.MakeDirty();
        }
      }
    }

    [Browsable(false)]
    public override string OldName
    {
      get { return _oldname; }
    }

    [Category("Storage")]
    [Editor(typeof(CatalogTypeEditor), typeof(UITypeEditor))]
    [DefaultValue("main")]
    [RefreshProperties(RefreshProperties.All)]
    public override string Catalog
    {
      get { return _catalog; }
    }

    [Category("Storage")]
    public string Database
    {
      get { return _connection.DataSource; }
    }

    [Browsable(false)]
    public string SqlText
    {
      get { return _sql; }
      set
      {
        if (String.Compare(_sql, value, StringComparison.OrdinalIgnoreCase) != 0)
        {
          _sql = value;
          _owner.MakeDirty();
        }
      }
    }

    [Browsable(false)]
    public string OriginalSql
    {
      get { return _oldsql; }
    }

    public string GetSqlText()
    {
      if (String.Compare(_sql, _oldsql, StringComparison.OrdinalIgnoreCase) == 0 && String.Compare(_name, _oldname, StringComparison.OrdinalIgnoreCase) == 0) return null;

      StringBuilder builder = new StringBuilder();

      if (String.IsNullOrEmpty(_oldname) == false)
      {
        foreach (ViewTrigger trig in _oldtriggers)
        {
          builder.AppendFormat("DROP TRIGGER [{0}].[{1}];\r\n", Catalog, trig.Name);
        }
        builder.AppendFormat("DROP VIEW [{0}].[{1}];\r\n", Catalog, _oldname);
      }

      builder.AppendFormat("CREATE VIEW [{0}].[{1}] AS {2};\r\n", Catalog, Name, SqlText);

      string sep = "";
      foreach (ViewTrigger trig in _triggers)
      {
        builder.Append(sep);
        trig.WriteSql(builder);
        sep = "\r\n";
      }

      return builder.ToString();
    }

    #region ICustomTypeDescriptor Members

    AttributeCollection ICustomTypeDescriptor.GetAttributes()
    {
      return TypeDescriptor.GetAttributes(GetType());
    }

    string ICustomTypeDescriptor.GetClassName()
    {
      return "View Design";
    }

    string ICustomTypeDescriptor.GetComponentName()
    {
      return ToString();
    }

    TypeConverter ICustomTypeDescriptor.GetConverter()
    {
      return TypeDescriptor.GetConverter(GetType());
    }

    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
    {
      return TypeDescriptor.GetDefaultEvent(GetType());
    }

    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
    {
      return TypeDescriptor.GetDefaultProperty(GetType());
    }

    object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
    {
      return TypeDescriptor.GetEditor(GetType(), editorBaseType);
    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
    {
      return TypeDescriptor.GetEvents(GetType(), attributes);
    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
    {
      return TypeDescriptor.GetEvents(GetType());
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
    {
      return TypeDescriptor.GetProperties(GetType(), attributes);
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
    {
      return TypeDescriptor.GetProperties(GetType());
    }

    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
    {
      return this;
    }

    #endregion

    [Browsable(false)]
    public override ViewTableBase DesignTable
    {
      get { return this; }
    }

    public override DbConnection GetConnection()
    {
      return _connection;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































Deleted SQLite.Designer/Editors/AutoCompleteColumn.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Editors
{
  using System;
  using System.Windows.Forms;
  using System.Runtime.InteropServices;
  using System.Drawing;

  public class AutoCompleteColumn : DataGridViewColumn
  {
    public AutoCompleteColumn()
      : base(new AutoCompleteCell())
    {
    }
  }

  public class AutoCompleteCell : DataGridViewTextBoxCell
  {
    public override Type EditType
    {
      get
      {
        return typeof(AutoCompleteEditingControl);
      }
    }
  }

  public class AutoCompleteEditingControl : DataGridViewComboBoxEditingControl
  {
    private bool inPrepare;
    private bool isDeleting;

    public override object EditingControlFormattedValue
    {
      get
      {
        return base.Text;
      }
      set
      {
        base.Text = value as string;
      }
    }

    public override void PrepareEditingControlForEdit(bool selectAll)
    {
      inPrepare = true;
      base.PrepareEditingControlForEdit(selectAll);
      if (base.Items.Count == 0)
      {
        base.Items.Add("integer");
        base.Items.Add("int");
        base.Items.Add("smallint");
        base.Items.Add("tinyint");
        base.Items.Add("bigint");
        base.Items.Add("bit");
        base.Items.Add("varchar(50)");
        base.Items.Add("nvarchar(50)");
        base.Items.Add("text");
        base.Items.Add("ntext");
        base.Items.Add("image");
        base.Items.Add("money");
        base.Items.Add("float");
        base.Items.Add("real");
        base.Items.Add("decimal");
        base.Items.Add("numeric(18,0)");
        base.Items.Add("char(10)");
        base.Items.Add("nchar(10)");
        base.Items.Add("datetime");
        base.Items.Add("guid");
      }
      base.DropDownStyle = ComboBoxStyle.DropDown;
      base.Text = EditingControlDataGridView.CurrentCell.Value as string;
      
      if (selectAll)
        base.SelectAll();

      inPrepare = false;
    }

    public override bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
    {
      isDeleting = false;

      switch (keyData & Keys.KeyCode)
      {
        case Keys.Delete:
        case Keys.Back:
          isDeleting = true;
          break;
      }

      if (((keyData & Keys.KeyCode) == Keys.Left && (base.SelectionStart > 0 ||  base.SelectionLength > 0))
        || ((keyData & Keys.KeyCode) == Keys.Right && (base.SelectionStart < base.Text.Length ||  base.SelectionLength > 0))
        || (((keyData & Keys.KeyCode) == Keys.Home || (keyData & Keys.KeyCode) == Keys.End) && base.SelectionLength != base.Text.Length)
        )
      {
        return true;
      }

      return base.EditingControlWantsInputKey(keyData, dataGridViewWantsInputKey);
    }

    protected override void OnTextChanged(EventArgs e)
    {
      if (inPrepare) return;
      base.OnTextChanged(e);

      bool changed = !(EditingControlDataGridView.CurrentCell.Value as string == base.Text ||
                     (String.IsNullOrEmpty(base.Text) && String.IsNullOrEmpty(EditingControlDataGridView.CurrentCell.Value as string)));

      if ((base.SelectionLength == 0 || base.SelectionStart == base.Text.Length) && isDeleting == false)
      {
        if (base.Items.Contains(base.Text) == false)
        {
          for (int n = 0; n < base.Items.Count; n++)
          {
            if (((string)base.Items[n]).StartsWith(base.Text, StringComparison.OrdinalIgnoreCase) == true)
            {
              int start = base.SelectionStart;
              inPrepare = true;
              
              base.Text = base.Items[n] as string;
              base.SelectionStart = start;
              base.SelectionLength = base.Text.Length - start;

              inPrepare = false;
              break;
            }
          }
        }
      }
      EditingControlValueChanged = changed;
      EditingControlDataGridView.NotifyCurrentCellDirty(changed);
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































Deleted SQLite.Designer/Editors/TableDesignerDoc.Designer.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Editors
{
  partial class TableDesignerDoc
  {
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }

      _editingTables.Remove(GetHashCode());

      base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.components = new System.ComponentModel.Container();
      System.Windows.Forms.SplitContainer _splitter;
      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TableDesignerDoc));
      this._dataGrid = new System.Windows.Forms.DataGridView();
      this.name = new System.Windows.Forms.DataGridViewTextBoxColumn();
      this.type = new SQLite.Designer.Editors.AutoCompleteColumn();
      this.isnull = new System.Windows.Forms.DataGridViewCheckBoxColumn();
      this._pg = new System.Windows.Forms.PropertyGrid();
      this._sqlText = new System.Windows.Forms.RichTextBox();
      this._propertyGrid = new System.Windows.Forms.PropertyGrid();
      this.autoCompleteColumn1 = new SQLite.Designer.Editors.AutoCompleteColumn();
      this._imageList = new System.Windows.Forms.ImageList(this.components);
      _splitter = new System.Windows.Forms.SplitContainer();
      _splitter.Panel1.SuspendLayout();
      _splitter.Panel2.SuspendLayout();
      _splitter.SuspendLayout();
      ((System.ComponentModel.ISupportInitialize)(this._dataGrid)).BeginInit();
      this.SuspendLayout();
      // 
      // _splitter
      // 
      _splitter.BackColor = System.Drawing.SystemColors.Control;
      _splitter.Dock = System.Windows.Forms.DockStyle.Fill;
      _splitter.Location = new System.Drawing.Point(0, 0);
      _splitter.Name = "_splitter";
      _splitter.Orientation = System.Windows.Forms.Orientation.Horizontal;
      // 
      // _splitter.Panel1
      // 
      _splitter.Panel1.Controls.Add(this._dataGrid);
      _splitter.Panel1.Controls.Add(this._pg);
      _splitter.Panel1.Controls.Add(this._sqlText);
      // 
      // _splitter.Panel2
      // 
      _splitter.Panel2.Controls.Add(this._propertyGrid);
      _splitter.Size = new System.Drawing.Size(436, 631);
      _splitter.SplitterDistance = 383;
      _splitter.TabIndex = 0;
      // 
      // _dataGrid
      // 
      this._dataGrid.AllowDrop = true;
      this._dataGrid.AllowUserToResizeRows = false;
      this._dataGrid.BackgroundColor = System.Drawing.SystemColors.Window;
      this._dataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
      this._dataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.name,
            this.type,
            this.isnull});
      this._dataGrid.Dock = System.Windows.Forms.DockStyle.Fill;
      this._dataGrid.Location = new System.Drawing.Point(0, 0);
      this._dataGrid.Name = "_dataGrid";
      this._dataGrid.RowHeadersWidth = 42;
      this._dataGrid.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
      this._dataGrid.RowTemplate.Height = 23;
      this._dataGrid.Size = new System.Drawing.Size(436, 383);
      this._dataGrid.TabIndex = 2;
      this._dataGrid.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this._dataGrid_CellValueChanged);
      this._dataGrid.MouseDown += new System.Windows.Forms.MouseEventHandler(this._dataGrid_MouseDown);
      this._dataGrid.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this._dataGrid_UserDeletingRow);
      this._dataGrid.MouseMove += new System.Windows.Forms.MouseEventHandler(this._dataGrid_MouseMove);
      this._dataGrid.CellValidated += new System.Windows.Forms.DataGridViewCellEventHandler(this._dataGrid_CellValidated);
      this._dataGrid.UserDeletedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this._dataGrid_UserDeletedRow);
      this._dataGrid.DragOver += new System.Windows.Forms.DragEventHandler(this._dataGrid_DragOver);
      this._dataGrid.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this._dataGrid_CellValidated);
      this._dataGrid.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(this._dataGrid_CellPainting);
      this._dataGrid.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this._dataGrid_CellClick);
      this._dataGrid.CellEnter += new System.Windows.Forms.DataGridViewCellEventHandler(this._dataGrid_CellEnter);
      this._dataGrid.RowHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this._dataGrid_RowHeaderMouseClick);
      this._dataGrid.SelectionChanged += new System.EventHandler(this._dataGrid_SelectionChanged);
      this._dataGrid.DragDrop += new System.Windows.Forms.DragEventHandler(this._dataGrid_DragDrop);
      // 
      // name
      // 
      this.name.Frozen = true;
      this.name.HeaderText = "Column Name";
      this.name.Name = "name";
      this.name.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
      // 
      // type
      // 
      this.type.HeaderText = "Data Type";
      this.type.Name = "type";
      // 
      // isnull
      // 
      this.isnull.FalseValue = false;
      this.isnull.HeaderText = "Allow Nulls";
      this.isnull.IndeterminateValue = false;
      this.isnull.Name = "isnull";
      this.isnull.TrueValue = true;
      // 
      // _pg
      // 
      this._pg.Location = new System.Drawing.Point(3, 171);
      this._pg.Name = "_pg";
      this._pg.PropertySort = System.Windows.Forms.PropertySort.NoSort;
      this._pg.Size = new System.Drawing.Size(130, 130);
      this._pg.TabIndex = 1;
      this._pg.ToolbarVisible = false;
      this._pg.Visible = false;
      // 
      // _sqlText
      // 
      this._sqlText.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
      this._sqlText.Location = new System.Drawing.Point(3, 3);
      this._sqlText.Name = "_sqlText";
      this._sqlText.ReadOnly = true;
      this._sqlText.Size = new System.Drawing.Size(165, 162);
      this._sqlText.TabIndex = 0;
      this._sqlText.Text = "";
      this._sqlText.Visible = false;
      // 
      // _propertyGrid
      // 
      this._propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
      this._propertyGrid.Location = new System.Drawing.Point(0, 0);
      this._propertyGrid.Name = "_propertyGrid";
      this._propertyGrid.Size = new System.Drawing.Size(436, 244);
      this._propertyGrid.TabIndex = 0;
      // 
      // autoCompleteColumn1
      // 
      this.autoCompleteColumn1.HeaderText = "Data Type";
      this.autoCompleteColumn1.Name = "autoCompleteColumn1";
      this.autoCompleteColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True;
      this.autoCompleteColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
      // 
      // _imageList
      // 
      this._imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("_imageList.ImageStream")));
      this._imageList.TransparentColor = System.Drawing.Color.Magenta;
      this._imageList.Images.SetKeyName(0, "PrimaryKey.bmp");
      // 
      // TableDesignerDoc
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.BackColor = System.Drawing.SystemColors.Window;
      this.Controls.Add(_splitter);
      this.Font = new System.Drawing.Font("MS Shell Dlg 2", 8.25F);
      this.Name = "TableDesignerDoc";
      this.Size = new System.Drawing.Size(436, 631);
      _splitter.Panel1.ResumeLayout(false);
      _splitter.Panel2.ResumeLayout(false);
      _splitter.ResumeLayout(false);
      ((System.ComponentModel.ISupportInitialize)(this._dataGrid)).EndInit();
      this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.PropertyGrid _propertyGrid;
    private AutoCompleteColumn autoCompleteColumn1;
    private System.Windows.Forms.ImageList _imageList;
    private System.Windows.Forms.DataGridView _dataGrid;
    private System.Windows.Forms.RichTextBox _sqlText;
    private System.Windows.Forms.PropertyGrid _pg;
    private System.Windows.Forms.DataGridViewTextBoxColumn name;
    private AutoCompleteColumn type;
    private System.Windows.Forms.DataGridViewCheckBoxColumn isnull;

  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































Deleted SQLite.Designer/Editors/TableDesignerDoc.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Editors
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Data.Common;
  using System.Drawing;
  using System.Text;
  using System.Windows.Forms;
  using Microsoft.VisualStudio.Shell.Interop;
  using Microsoft.VisualStudio.OLE.Interop;
  using Microsoft.VisualStudio;
  using Microsoft.VisualStudio.Data;
  using System.ComponentModel.Design;
  using System.Globalization;
  using SQLite.Designer.Design;

  public partial class TableDesignerDoc : DesignerDocBase,
    IVsPersistDocData,
    IVsWindowPane,
    IOleCommandTarget,
    ISelectionContainer,
    IVsWindowPaneCommit,
    IVsWindowFrameNotify
  {
    private static Dictionary<int, string> _editingTables = new Dictionary<int, string>();
    
    internal DataConnection _connection;
    internal Microsoft.VisualStudio.Data.ServiceProvider _serviceProvider;
    internal Table _table;
    internal bool _dirty;
    internal bool _init;
    internal DataViewHierarchyAccessor _accessor;
    internal int _itemId;
    static private bool _warned;

    public TableDesignerDoc(int itemId, DataViewHierarchyAccessor accessor, string tableName)
    {
      _accessor = accessor;
      _connection = accessor.Connection;
      _itemId = itemId;
      _init = true;

      InitializeComponent();

      StringBuilder tables = new StringBuilder();

      using (DataReader reader = _connection.Command.Execute("SELECT * FROM sqlite_master", 1, null, 30))
      {
        while (reader.Read())
        {
          tables.Append(reader.GetItem(2).ToString());
          tables.Append(",");
        }
      }

      int n = 1;

      if (String.IsNullOrEmpty(tableName))
      {
        string alltables = tables.ToString();

        do
        {
          tableName = String.Format(CultureInfo.InvariantCulture, "Table{0}", n);
          n++;
        } while (alltables.IndexOf(tableName + ",", StringComparison.OrdinalIgnoreCase) > -1 || _editingTables.ContainsValue(tableName));

        _editingTables.Add(GetHashCode(), tableName);
      }
      _table = new Table(tableName, _connection.ConnectionSupport.ProviderObject as DbConnection, this);
      foreach(Column c in _table.Columns)
      {
        n = _dataGrid.Rows.Add();
        _dataGrid.Rows[n].Tag = c;
        c.Parent = _dataGrid.Rows[n];
      }
      _init = false;

      if (_dataGrid.Rows.Count > 0)
      {
        _dataGrid.EndEdit();
        _sqlText.Text = _table.OriginalSql;
      }
    }

    public override string CanonicalName
    {
      get
      {
        return _table.Name;
      }
    }

    void SetPropertyWindow()
    {
      IVsTrackSelectionEx track = _serviceProvider.GetService(typeof(SVsTrackSelectionEx)) as IVsTrackSelectionEx;
      if (track != null)
      {
        track.OnSelectChange(this);
      }
    }

    public string Caption
    {
      get
      {
        string catalog = "main";
        if (_table != null) catalog = _table.Catalog;

        return String.Format(CultureInfo.InvariantCulture, "{0}.{1} Table (SQLite [{2}])", catalog, base.Name, ((DbConnection)_connection.ConnectionSupport.ProviderObject).DataSource);
      }
    }

    public new string Name
    {
      get
      {
        if (_table != null)
          return _table.Name;
        else return base.Name;
      }
      set
      {
        base.Name = value;

        if (_serviceProvider != null)
        {
          IVsWindowFrame frame = _serviceProvider.GetService(typeof(IVsWindowFrame)) as IVsWindowFrame;
          if (frame != null)
          {
            frame.SetProperty((int)__VSFPROPID.VSFPROPID_EditorCaption, Caption);
          }
        }
      }
    }

    public void NotifyChanges()
    {
      if (_serviceProvider == null) return;

      _sqlText.Text = _table.GetSql();

      // Get a reference to the Running Document Table
      IVsRunningDocumentTable runningDocTable = (IVsRunningDocumentTable)_serviceProvider.GetService(typeof(SVsRunningDocumentTable));

      // Lock the document
      uint docCookie;
      IVsHierarchy hierarchy;
      uint itemID;
      IntPtr docData;
      int hr = runningDocTable.FindAndLockDocument(
          (uint)_VSRDTFLAGS.RDT_ReadLock,
          base.Name,
          out hierarchy,
          out itemID,
          out docData,
          out docCookie
      );
      ErrorHandler.ThrowOnFailure(hr);

      IVsUIShell shell = _serviceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;
      if (shell != null)
      {
        shell.UpdateDocDataIsDirtyFeedback(docCookie, (_dirty == true) ? 1 : 0);
      }

      // Unlock the document.
      // Note that we have to unlock the document even if the previous call failed.
      runningDocTable.UnlockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, docCookie);

      // Check ff the call to NotifyDocChanged failed.
      //ErrorHandler.ThrowOnFailure(hr);
    }

    #region IVsPersistDocData Members

    int IVsPersistDocData.Close()
    {
      return VSConstants.S_OK;
    }

    public int GetGuidEditorType(out Guid pClassID)
    {
      return ((IPersistFileFormat)this).GetClassID(out pClassID);
    }

    public int IsDocDataDirty(out int pfDirty)
    {
      pfDirty = _dirty == true ? 1 : 0;
      return VSConstants.S_OK;
    }

    public int IsDocDataReloadable(out int pfReloadable)
    {
      pfReloadable = 0;
      return VSConstants.S_OK;
    }

    public int LoadDocData(string pszMkDocument)
    {
      return ((IPersistFileFormat)this).Load(pszMkDocument, 0, 0);
    }

    public int OnRegisterDocData(uint docCookie, IVsHierarchy pHierNew, uint itemidNew)
    {
      return VSConstants.S_OK;
    }

    public int ReloadDocData(uint grfFlags)
    {
      return VSConstants.E_NOTIMPL;
    }

    public int RenameDocData(uint grfAttribs, IVsHierarchy pHierNew, uint itemidNew, string pszMkDocumentNew)
    {
      return VSConstants.E_NOTIMPL;
    }

    private string GetChangeScript()
    {
      _dataGrid.EndEdit();
      _init = true;
      for (int n = 0; n < _table.Columns.Count; n++)
      {
        Column c = _table.Columns[n];
        if (String.IsNullOrEmpty(c.ColumnName) == true)
        {
          try
          {
            _dataGrid.Rows.Remove(c.Parent);
          }
          catch
          {
            c.Parent.Tag = null;
          }
          _table.Columns.Remove(c);
          n--;
          continue;
        }
      }

      for (int n = 0; n < _dataGrid.Rows.Count; n++)
      {
        if ((_dataGrid.Rows[n].Tag is Column) == false)
        {
          try
          {
            _dataGrid.Rows.RemoveAt(n);
          }
          catch
          {
            if (n == _dataGrid.Rows.Count - 1) break;
          }
          n--;
        }
      }
      _init = false;

      return _table.GetSql();
    }

    public int SaveDocData(VSSAVEFLAGS dwSave, out string pbstrMkDocumentNew, out int pfSaveCanceled)
    {
      pbstrMkDocumentNew = _table.Name;
      pfSaveCanceled = 0;

      if (String.IsNullOrEmpty(_table.OriginalSql) == true)
      {
        using (TableNameDialog dlg = new TableNameDialog("Table", _table.Name))
        {
          if (dlg.ShowDialog(this) == DialogResult.Cancel)
          {
            pfSaveCanceled = 1;
            return VSConstants.S_OK;
          }
          _table.Name = dlg.TableName;
        }
      }

      string sql = GetChangeScript();

      using (DbTransaction trans = _table.GetConnection().BeginTransaction())
      {
        try
        {
          using (DbCommand cmd = _table.GetConnection().CreateCommand())
          {
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
          }
          trans.Commit();
        }
        catch (Exception)
        {
          trans.Rollback();
          throw;
        }
      }

      _dirty = false;
      _table.Committed();
      NotifyChanges();
      _sqlText.Text = _table.OriginalSql;

      SQLiteCommandHandler.Refresh(_accessor, _itemId);

      _dataGrid_SelectionChanged(this, EventArgs.Empty);

      RefreshToolbars();

      return VSConstants.S_OK;
    }

    public int SetUntitledDocPath(string pszDocDataPath)
    {
      return ((IPersistFileFormat)this).InitNew(0);
    }

    #endregion

    #region IVsWindowPane Members

    public int ClosePane()
    {
      this.Dispose(true);
      return VSConstants.S_OK;
    }

    public int CreatePaneWindow(IntPtr hwndParent, int x, int y, int cx, int cy, out IntPtr hwnd)
    {
      Win32Methods.SetParent(Handle, hwndParent);
      hwnd = Handle;

      Size = new System.Drawing.Size(cx - x, cy - y);
      return VSConstants.S_OK;
    }

    public int GetDefaultSize(Microsoft.VisualStudio.OLE.Interop.SIZE[] size)
    {
      if (size.Length >= 1)
      {
        size[0].cx = Size.Width;
        size[0].cy = Size.Height;
      }

      return VSConstants.S_OK;
    }

    public int LoadViewState(Microsoft.VisualStudio.OLE.Interop.IStream pStream)
    {
      return VSConstants.S_OK;
    }

    public int SaveViewState(Microsoft.VisualStudio.OLE.Interop.IStream pStream)
    {
      return VSConstants.S_OK;
    }

    public void RefreshToolbars()
    {
      if (_serviceProvider == null) return;

      IVsUIShell shell = _serviceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;

      if (shell != null)
      {
        shell.UpdateCommandUI(1);
      }
    }

    public int SetSite(Microsoft.VisualStudio.OLE.Interop.IServiceProvider psp)
    {
      _serviceProvider = new ServiceProvider(psp);
      return VSConstants.S_OK;
    }

    public int TranslateAccelerator(Microsoft.VisualStudio.OLE.Interop.MSG[] lpmsg)
    {
      return VSConstants.S_FALSE;
    }

    #endregion

    public void MakeDirty()
    {
      _dirty = true;
      NotifyChanges();
    }

    private bool IsPkSelected()
    {
      bool newVal = false;
      foreach (Column c in _propertyGrid.SelectedObjects)
      {
        foreach (IndexColumn ic in _table.PrimaryKey.Columns)
        {
          if (String.Compare(c.ColumnName, ic.Column, StringComparison.OrdinalIgnoreCase) == 0)
          {
            newVal = true;
            break;
          }
        }
      }
      return newVal;
    }

    #region IOleCommandTarget Members

    public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
    {
      if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
      {
        switch ((VSConstants.VSStd97CmdID)nCmdID)
        {
          case VSConstants.VSStd97CmdID.GenerateChangeScript:
            {
              using (ChangeScriptDialog dlg = new ChangeScriptDialog(_table.Name, (_dirty == true) ? GetChangeScript() : String.Empty, _table.OriginalSql))
              {
                dlg.ShowDialog(this);
              }
            }
            return VSConstants.S_OK;
          case VSConstants.VSStd97CmdID.PrimaryKey:
            bool newVal = IsPkSelected();

            if (newVal == false)
            {
              _table.PrimaryKey.Columns.Clear();
              foreach (Column c in _propertyGrid.SelectedObjects)
              {
                IndexColumn newcol = new IndexColumn(_table.PrimaryKey, null);
                newcol.Column = c.ColumnName;
                _table.PrimaryKey.Columns.Add(newcol);
              }
            }
            else
            {
              foreach (Column c in _propertyGrid.SelectedObjects)
              {
                foreach (IndexColumn ic in _table.PrimaryKey.Columns)
                {
                  if (String.Compare(c.ColumnName, ic.Column, StringComparison.OrdinalIgnoreCase) == 0)
                  {
                    _table.PrimaryKey.Columns.Remove(ic);
                    break;
                  }
                }
              }
            }

            _dataGrid_SelectionChanged(this, EventArgs.Empty);
            _dataGrid.Invalidate();
            MakeDirty();
            return VSConstants.S_OK;

          case VSConstants.VSStd97CmdID.Cut:
            _clipRows = SelectedRows;
            foreach (DataGridViewRow row in _clipRows)
            {
              _dataGrid.Rows.Remove(row);
              _table.Columns.Remove(row.Tag as Column);
              MakeDirty();
            }
            Clipboard.SetData("SQLiteTableDesigner", Caption);
            RefreshToolbars();
            return VSConstants.S_OK;

          case VSConstants.VSStd97CmdID.Copy:
            _clipRows = SelectedRows;
            Clipboard.SetData("SQLiteTableDesigner", Caption);
            RefreshToolbars();
            return VSConstants.S_OK;

          case VSConstants.VSStd97CmdID.Paste:
            DataGridViewRow[] arr = GetClipboardRows();
            int rowIndex = _dataGrid.CurrentRow.Index;
            _dataGrid.EndEdit();

            for (int n = arr.Length - 1; n > -1; n--)
            {
              DataGridViewRow row = arr[n];
              Column c = row.Tag as Column;
              bool hasCol = false;
              foreach (Column oc in _table.Columns)
              {
                if (String.Compare(c.ColumnName, oc.ColumnName, StringComparison.OrdinalIgnoreCase) == 0)
                {
                  hasCol = true;
                  break;
                }
              }
              _dataGrid.Rows.Insert(rowIndex, 1);
              DataGridViewRow newrow = _dataGrid.Rows[rowIndex];

              if (hasCol == true)
              {
                Column oc = c;
                c = new Column(_table, newrow);
                int num = 1;
                while (String.IsNullOrEmpty(c.ColumnName) == true)
                {
                  bool found = false;
                  string proposed = String.Format(CultureInfo.InvariantCulture, "{0}{1}", oc.ColumnName, num);
                  foreach (Column cc in _table.Columns)
                  {
                    if (String.Compare(cc.ColumnName, proposed, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                      found = true;
                      break;
                    }
                  }
                  if (found == true)
                  {
                    num++;
                  }
                  else
                    c.ColumnName = proposed;
                }
                c.AllowNulls = oc.AllowNulls;
                c.Collate = oc.Collate;
                c.DataType = oc.DataType;
                c.DefaultValue = oc.DefaultValue;
                c.Unique.Enabled = oc.Unique.Enabled;
                c.Unique.Conflict = oc.Unique.Conflict;
              }

              c.Parent = newrow;
              newrow.Tag = c;
              newrow.SetValues(c.ColumnName, c.DataType, c.AllowNulls);
              _table.Columns.Insert(rowIndex, c);
            }
            
            MakeDirty();
            _dataGrid.Invalidate();

            return VSConstants.S_OK;
        }
      }
      else if (pguidCmdGroup == SQLiteCommandHandler.guidDavinci)
      {
        switch ((VSConstants.VSStd97CmdID)nCmdID)
        {
          case VSConstants.VSStd97CmdID.ManageIndexes:
            EditorHolder holder = new EditorHolder(_table);
            _pg.SelectedObject = holder;
            _pg.SelectedGridItem = _pg.SelectedGridItem.Parent.GridItems[0];
            IndexEditor ed = new IndexEditor(_table);
            ed.EditValue((ITypeDescriptorContext)_pg.SelectedGridItem, (System.IServiceProvider)_pg.SelectedGridItem, _pg.SelectedGridItem.Value);

            _dataGrid_SelectionChanged(this, EventArgs.Empty);
            _dataGrid.Invalidate();

            return VSConstants.S_OK;
          case VSConstants.VSStd97CmdID.ManageRelationships:
            holder = new EditorHolder(_table);
            _pg.SelectedObject = holder;
            _pg.SelectedGridItem = _pg.SelectedGridItem.Parent.GridItems[1];
            ForeignKeyEditor fed = new ForeignKeyEditor(_table);
            fed.EditValue((ITypeDescriptorContext)_pg.SelectedGridItem, (System.IServiceProvider)_pg.SelectedGridItem, _pg.SelectedGridItem.Value);
            return VSConstants.S_OK;
          
          case VSConstants.VSStd97CmdID.ManageConstraints:
            holder = new EditorHolder(_table);
            _pg.SelectedObject = holder;
            _pg.SelectedGridItem = _pg.SelectedGridItem.Parent.GridItems[2];
            CheckEditor ced = new CheckEditor(_table);
            ced.EditValue((ITypeDescriptorContext)_pg.SelectedGridItem, (System.IServiceProvider)_pg.SelectedGridItem, _pg.SelectedGridItem.Value);
            return VSConstants.S_OK;

          case VSConstants.VSStd97CmdID.AlignRight: // Insert Column
            _dataGrid.EndEdit();
            _dataGrid.Rows.Insert(_dataGrid.SelectedRows[0].Index, 1);
            return VSConstants.S_OK;
          case VSConstants.VSStd97CmdID.AlignToGrid: // Delete Column
            _dataGrid.EndEdit();
            int deleted = 0;
            while (_dataGrid.SelectedRows.Count > 0)
            {
              try
              {
                DataGridViewRow row = _dataGrid.SelectedRows[0];
                Column c = row.Tag as Column;
                row.Selected = false;
                if (c != null)
                {
                  _table.Columns.Remove(c);
                  deleted++;
                }
                _dataGrid.Rows.Remove(row);
              }
              catch
              {
              }
            }
            if (deleted > 0) MakeDirty();
            return VSConstants.S_OK;
        }
      }
      else if (pguidCmdGroup == SQLiteCommandHandler.guidSQLiteCmdSet)
      {
        switch ((cmdid)nCmdID)
        {
          case cmdid.Triggers:
            EditorHolder holder = new EditorHolder(_table);
            _pg.SelectedObject = holder;
            _pg.SelectedGridItem = _pg.SelectedGridItem.Parent.GridItems[3];
            TriggerEditor ted = new TriggerEditor(_table);
            ted.EditValue((ITypeDescriptorContext)_pg.SelectedGridItem, (System.IServiceProvider)_pg.SelectedGridItem, _pg.SelectedGridItem.Value);
            return VSConstants.S_OK;
        }
      }

      return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
    }

    private DataGridViewRow[] _clipRows;

    private DataGridViewRow[] GetClipboardRows()
    {
      if (Clipboard.ContainsData("SQLiteTableDesigner") && Clipboard.GetData("SQLiteTableDesigner").ToString() == Caption)
      {
        DataGridViewRow[] arr = _clipRows;
        if (arr != null)
        {
          for (int n = 0; n < arr.Length; n++)
          {
            Column c = arr[n].Tag as Column;
            if (c != null && c.Table == _table) return arr;
          }
        }
      }
      return null;
    }

    public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
      if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
      {
        switch ((VSConstants.VSStd97CmdID)prgCmds[0].cmdID)
        {
          case VSConstants.VSStd97CmdID.PrimaryKey:
            prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
            if (IsPkSelected() == true)
              prgCmds[0].cmdf |= (uint)(OLECMDF.OLECMDF_LATCHED);

            break;
          case VSConstants.VSStd97CmdID.GenerateChangeScript:
            if (_dirty == true || String.IsNullOrEmpty(_table.OriginalSql) == false)
            {
              prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
              break;
            }
            return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
          case VSConstants.VSStd97CmdID.Cut:
            if (SelectedRows.Length > 0)
            {
              prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
              break;
            }
            return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
          case VSConstants.VSStd97CmdID.Copy:
            if (SelectedRows.Length > 0)
            {
              prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
              break;
            }
            return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
          case VSConstants.VSStd97CmdID.Paste:
            DataGridViewRow[] rows = GetClipboardRows();
            if (rows != null)
            {
              prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
              break;
            }
            return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
          default:
            return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
        }
        return VSConstants.S_OK;
      }

      if (pguidCmdGroup == SQLiteCommandHandler.guidSQLiteCmdSet)
      {
        switch (prgCmds[0].cmdID)
        {
          case (uint)cmdid.Triggers:
            prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
            return VSConstants.S_OK;
        }
      }

      if (pguidCmdGroup == SQLiteCommandHandler.guidDavinci)
      {
        switch (prgCmds[0].cmdID)
        {
          case (uint)VSConstants.VSStd97CmdID.ManageRelationships:
          case (uint)VSConstants.VSStd97CmdID.ManageIndexes:
          case (uint)VSConstants.VSStd97CmdID.ManageConstraints:
          //case 10: // Table View -> Custom
          //case 14: // Table View -> Modify Custom
          //case 33: // Database Diagram -> Add Table
          //case 1: // Database Diagram -> Add Related Tables
          //case 12: // Database Diagram -> Delete From Database
          //case 51: // Database Diagram -> Remove From Diagram
          //case 13: // Database Diagram -> Autosize Selected Tables
          //case 3: // Database Diagram -> Arrange Selection
          //case 2: // Database Diagram -> Arrange Tables
          //case 16: // Database Diagram -> Zoom -> 200%
          //case 17: // Database Diagram -> Zoom -> 150%
          //case 18: // Database Diagram -> Zoom -> 100%
          //case 19: // Database Diagram -> Zoom -> 75%
          //case 20: // Database Diagram -> Zoom -> 50%
          //case 21: // Database Diagram -> Zoom -> 25%
          //case 22: // Database Diagram -> Zoom -> 10%
          //case 24: // Database Diagram -> Zoom -> To Fit
          //case 6: // Database Diagram -> New Text Annotation
          //case 15: // Database Diagram -> Set Text Annotation Font
          //case 7: // Database Diagram -> Show Relationship Labels
          //case 8: // Database Diagram -> View Page Breaks
          //case 9: // Database Diagram -> Recalculate Page Breaks
          //case 43: // Database Diagram -> Copy Diagram to Clipboard
          //case 41: // Query Designer -> Table Display -> Column Names
          //case 42: // Query Designer -> Table Display -> Name Only
          //case 39: // Query Designer -> Add Table
          case 4: // Insert Column
          case 5: // Delete Column
            prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
            break;
          default:
            return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
        }
        return VSConstants.S_OK;
      }

      return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
    }

    #endregion

    #region ISelectionContainer Members

    int ISelectionContainer.CountObjects(uint dwFlags, out uint pc)
    {
      pc = 1;
      return VSConstants.S_OK;
    }

    int ISelectionContainer.GetObjects(uint dwFlags, uint cObjects, object[] apUnkObjects)
    {
      apUnkObjects[0] = _table;
      return VSConstants.S_OK;
    }

    int ISelectionContainer.SelectObjects(uint cSelect, object[] apUnkSelect, uint dwFlags)
    {
      return VSConstants.S_OK;
    }

    #endregion

    #region IVsWindowPaneCommit Members

    int IVsWindowPaneCommit.CommitPendingEdit(out int pfCommitFailed)
    {
      pfCommitFailed = 0;
      return VSConstants.S_OK;
    }

    #endregion

    #region IVsWindowFrameNotify Members

    int IVsWindowFrameNotify.OnDockableChange(int fDockable)
    {
      return VSConstants.S_OK;
    }

    int IVsWindowFrameNotify.OnMove()
    {
      return VSConstants.S_OK;
    }

    int IVsWindowFrameNotify.OnShow(int fShow)
    {
      switch ((__FRAMESHOW)fShow)
      {
        case __FRAMESHOW.FRAMESHOW_WinShown:
        case __FRAMESHOW.FRAMESHOW_WinRestored:
          SetPropertyWindow();
          if (_warned == false)
          {
            _warned = true;
            MessageBox.Show(this, "The table designer is still in development.  Please report bugs to robert@blackcastlesoft.com", "Feature Under Review", MessageBoxButtons.OK);
          }
          break;
      }
      return VSConstants.S_OK;
    }

    int IVsWindowFrameNotify.OnSize()
    {
      return VSConstants.S_OK;
    }

    #endregion

    private void _dataGrid_CellEnter(object sender, DataGridViewCellEventArgs e)
    {
      try
      {
        if (e.ColumnIndex > -1)
        {
          _dataGrid.BeginEdit(true);
          _dataGrid_SelectionChanged(sender, e);
        }
      }
      catch
      {
      }
    }

    private void _dataGrid_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
      _dataGrid.EndEdit();
      if (e.Button == MouseButtons.Right)
      {
        if (_dataGrid.Rows[e.RowIndex].Selected == false)
        {
          switch (Control.ModifierKeys)
          {
            case Keys.Control:
              _dataGrid.Rows[e.RowIndex].Selected = true;
              break;
            case Keys.Shift:
              int min = Math.Min(_dataGrid.CurrentRow.Index, e.RowIndex);
              int max = Math.Max(_dataGrid.CurrentRow.Index, e.RowIndex);
              for (int n = 0; n < _dataGrid.Rows.Count; n++)
              {
                _dataGrid.Rows[n].Selected = (_dataGrid.Rows[n].Index <= min || _dataGrid.Rows[n].Index <= max);
              }
              break;
            default:
              for (int n = 0; n < _dataGrid.Rows.Count; n++)
              {
                _dataGrid.Rows[n].Selected = (e.RowIndex == n);
              }
              break;
          }
        }

        IVsUIShell shell = _serviceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;
        if (shell != null)
        {
          Guid guid;
          POINTS[] p = new POINTS[1];
          int ret;

          p[0].x = (short)Control.MousePosition.X;
          p[0].y = (short)Control.MousePosition.Y;

          guid = new Guid("732abe74-cd80-11d0-a2db-00aa00a3efff");

          ret = shell.ShowContextMenu(0, ref guid, 259, p, this);
        }
      }
    }

    private void _dataGrid_CellClick(object sender, DataGridViewCellEventArgs e)
    {
      if (_init == true) return;
      if (e.ColumnIndex == -1 && e.RowIndex == -1)
      {
        _dataGrid.EndEdit();
      }
      _dataGrid_SelectionChanged(sender, e);
    }

    private void _dataGrid_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
      if (_init == true) return;
      if (e.ColumnIndex > -1 || e.RowIndex < 0) return;

      Column col = _dataGrid.Rows[e.RowIndex].Tag as Column;

      if (col == null) return;

      bool ispk = false;
      foreach (IndexColumn ic in _table.PrimaryKey.Columns)
      {
        if (String.Compare(ic.Column, col.ColumnName, StringComparison.OrdinalIgnoreCase) == 0)
        {
          ispk = true;
          break;
        }
      }
      if (ispk == true)
      {
        e.Paint(e.ClipBounds, DataGridViewPaintParts.All);
        _imageList.Draw(e.Graphics, e.CellBounds.Left, e.CellBounds.Top + ((e.CellBounds.Bottom - e.CellBounds.Top) - _imageList.ImageSize.Height) / 2, 0);
        e.Handled = true;
      }
    }

    private DataGridViewRow[] SelectedRows
    {
      get
      {
        List<DataGridViewRow> items = new List<DataGridViewRow>();

        for (int n = 0; n < _dataGrid.Rows.Count; n++)
        {
          if (_dataGrid.Rows[n].Selected || (_dataGrid.CurrentCell.RowIndex == n && _dataGrid.CurrentCell.Selected == true))
          {
            if (_dataGrid.Rows[n].Tag is Column)
              items.Add(_dataGrid.Rows[n]);
          }
        }

        DataGridViewRow[] objs = new DataGridViewRow[items.Count];
        items.CopyTo(objs);

        return objs;
      }
    }

    private void _dataGrid_SelectionChanged(object sender, EventArgs e)
    {
      if (_init == true) return;
      DataGridViewRow[] arr = SelectedRows;

      object[] objs = new object[arr.Length];

      for (int n = 0; n < objs.Length; n++)
        objs[n] = arr[n].Tag;

      _propertyGrid.SelectedObjects = objs;

      RefreshToolbars();
    }

    private void _dataGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
      if (_init == true) return;
      if (e.RowIndex > -1)
      {
        _propertyGrid.SelectedObjects = _propertyGrid.SelectedObjects;
      }
    }

    private void _dataGrid_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
    {
      if (_init == true) return;
      
      if (e.Row.Tag is Column)
        MakeDirty();

      _dataGrid_SelectionChanged(sender, e);
    }

    private void _dataGrid_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
    {
      if (_init == true) return;
      if (e.Row.Tag is Column)
      {
        _table.Columns.Remove(e.Row.Tag as Column);
      }
    }

    private void _dataGrid_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
    {

    }

    private void _dataGrid_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
    {

    }

    private Rectangle _dragBoxFromMouseDown;
    private int _rowIndexFromMouseDown;
    private int _rowIndexOfItemUnderMouseToDrop;

    private void _dataGrid_DragDrop(object sender, DragEventArgs e)
    {
      // The mouse locations are relative to the screen, so they must be 
      // converted to client coordinates.
      Point clientPoint = _dataGrid.PointToClient(new Point(e.X, e.Y));

      if (_rowIndexOfItemUnderMouseToDrop != -1)
        _dataGrid.Rows[_rowIndexOfItemUnderMouseToDrop].DividerHeight = 0;

      _rowIndexOfItemUnderMouseToDrop = _dataGrid.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

      if (_rowIndexOfItemUnderMouseToDrop != -1)
        _dataGrid.Rows[_rowIndexOfItemUnderMouseToDrop].DividerHeight = 0;

      // If the drag operation was a move then remove and insert the row.
      if (e.Effect == DragDropEffects.Move)
      {
        DataGridViewRow[] rowsToMove = e.Data.GetData(typeof(DataGridViewRow[])) as DataGridViewRow[];
        for (int n = 0; n < rowsToMove.Length; n++)
        {
          _dataGrid.Rows.Remove(rowsToMove[n]);
          _table.Columns.Remove(rowsToMove[n].Tag as Column);
          _dataGrid.Rows.Insert(_rowIndexOfItemUnderMouseToDrop, rowsToMove[n]);
          _table.Columns.Insert(_rowIndexOfItemUnderMouseToDrop, rowsToMove[n].Tag as Column);
        }
        MakeDirty();
        RefreshToolbars();
      }
    }

    private void _dataGrid_DragOver(object sender, DragEventArgs e)
    {
      // The mouse locations are relative to the screen, so they must be 
      // converted to client coordinates.
      Point clientPoint = _dataGrid.PointToClient(new Point(e.X, e.Y));

      // Get the row index of the item the mouse is below. 
      if (_rowIndexOfItemUnderMouseToDrop != -1)
        _dataGrid.Rows[_rowIndexOfItemUnderMouseToDrop].DividerHeight = 0;

      _rowIndexOfItemUnderMouseToDrop = _dataGrid.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

      if (_dataGrid.Rows[_rowIndexOfItemUnderMouseToDrop].IsNewRow == false && _rowIndexOfItemUnderMouseToDrop != _rowIndexFromMouseDown)
      {
        e.Effect = DragDropEffects.Move;

        if (_rowIndexOfItemUnderMouseToDrop != -1)
          _dataGrid.Rows[_rowIndexOfItemUnderMouseToDrop].DividerHeight = 3;
      }
      else
        e.Effect = DragDropEffects.None;
    }

    private void _dataGrid_MouseDown(object sender, MouseEventArgs e)
    {
      // Get the index of the item the mouse is below.
      _rowIndexFromMouseDown = _dataGrid.HitTest(e.X, e.Y).RowIndex;

      if (_rowIndexFromMouseDown != -1)
      {
        // Remember the point where the mouse down occurred. 
        // The DragSize indicates the size that the mouse can move 
        // before a drag event should be started. 
        Size dragSize = SystemInformation.DragSize;

        // Create a rectangle using the DragSize, with the mouse position being
        // at the center of the rectangle.
        _dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
      }
      else
        // Reset the rectangle if the mouse is not over an item in the ListBox.
        _dragBoxFromMouseDown = Rectangle.Empty;
    }

    private void _dataGrid_MouseMove(object sender, MouseEventArgs e)
    {
      if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
      {
        // If the mouse moves outside the rectangle, start the drag.
        if (_dragBoxFromMouseDown != Rectangle.Empty && !_dragBoxFromMouseDown.Contains(e.X, e.Y))
        {
          _rowIndexOfItemUnderMouseToDrop = -1;
          _dataGrid.EndEdit();
          // Proceed with the drag and drop, passing in the list item. 
          DragDropEffects dropEffect = _dataGrid.DoDragDrop(SelectedRows, DragDropEffects.Move);
        }
      }
    }

    private void _dataGrid_CellValidated(object sender, DataGridViewCellEventArgs e)
    {
      DataGridViewRow row = _dataGrid.Rows[e.RowIndex];
      Column col = row.Tag as Column;

      if (col == null && row.IsNewRow == false)
      {
        col = new Column(_table, row);
        row.Tag = col;
        _table.Columns.Insert(row.Index, col);
        _dataGrid_SelectionChanged(this, new EventArgs());
      }
      if (col != null)
        col.CellValueChanged(e.RowIndex, e.ColumnIndex);

      RefreshToolbars();
    }
  }

  internal class EditorHolder
  {
    private List<Index> _indexes;
    private List<ForeignKey> _fkeys;
    private List<string> _check;
    private List<Trigger> _triggers;

    internal EditorHolder(Table tbl)
    {
      _indexes = tbl.Indexes;
      _fkeys = tbl.ForeignKeys;
      _check = tbl.Check;
      _triggers = tbl.Triggers as List<Trigger>;
    }

    public List<Index> Indexes
    {
      get { return _indexes; }
    }

    public List<ForeignKey> ForeignKeys
    {
      get { return _fkeys; }
    }

    public List<string> Check
    {
      get { return _check; }
    }

    public List<Trigger> Triggers
    {
      get { return _triggers; }
    }
  }

  public class DesignerDocBase : UserControl
  {
    public virtual string CanonicalName
    {
      get
      {
        return null;
      }
    }
  }

  internal class FakeHierarchy : IVsUIHierarchy, IVsPersistHierarchyItem2
  {
    DesignerDocBase _control;
    IVsUIHierarchy _owner;
    Dictionary<uint, IVsHierarchyEvents> _events = new Dictionary<uint, IVsHierarchyEvents>();

    internal FakeHierarchy(DesignerDocBase control, IVsUIHierarchy owner)
    {
      _control = control;
      _owner = owner;
    }

    #region IVsUIHierarchy Members

    int IVsUIHierarchy.AdviseHierarchyEvents(IVsHierarchyEvents pEventSink, out uint pdwCookie)
    {
      pdwCookie = 100;
      while (_events.ContainsKey(pdwCookie))
        pdwCookie++;

      _events[pdwCookie] = pEventSink;

      return VSConstants.S_OK;
    }

    int IVsUIHierarchy.Close()
    {
      return VSConstants.S_OK;
    }

    int IVsUIHierarchy.ExecCommand(uint itemid, ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.GetCanonicalName(uint itemid, out string pbstrName)
    {
      pbstrName = _control.CanonicalName;
      return VSConstants.S_OK;
    }

    int IVsUIHierarchy.GetGuidProperty(uint itemid, int propid, out Guid pguid)
    {
      return _owner.GetGuidProperty(itemid, propid, out pguid);
    }

    int IVsUIHierarchy.GetNestedHierarchy(uint itemid, ref Guid iidHierarchyNested, out IntPtr ppHierarchyNested, out uint pitemidNested)
    {
      ppHierarchyNested = IntPtr.Zero;
      pitemidNested = 0;

      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.GetProperty(uint itemid, int propid, out object pvar)
    {
      pvar = null;

      switch ((__VSHPROPID)propid)
      {
        case __VSHPROPID.VSHPROPID_AllowEditInRunMode:
          pvar = true;
          break;
        case __VSHPROPID.VSHPROPID_CanBuildFromMemory:
          pvar = true;
          break;
        case __VSHPROPID.VSHPROPID_Caption:
        case __VSHPROPID.VSHPROPID_SaveName:
          pvar = _control.CanonicalName;
          break;
        case __VSHPROPID.VSHPROPID_IsHiddenItem:
          pvar = true;
          break;
        case __VSHPROPID.VSHPROPID_IsNewUnsavedItem:
          pvar = true;
          break;
        case __VSHPROPID.VSHPROPID_ShowOnlyItemCaption:
          pvar = true;
          break;
        case __VSHPROPID.VSHPROPID_IconImgList:
          pvar = 0;
          break;
        case __VSHPROPID.VSHPROPID_IconHandle:
          pvar = null;
          return VSConstants.S_OK;
      }

      if (pvar == null)
        return _owner.GetProperty(itemid, propid, out pvar);
      else
        return VSConstants.S_OK;
    }

    int IVsUIHierarchy.GetSite(out Microsoft.VisualStudio.OLE.Interop.IServiceProvider ppSP)
    {
      ppSP = null;
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.ParseCanonicalName(string pszName, out uint pitemid)
    {
      pitemid = 0;
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.QueryClose(out int pfCanClose)
    {
      pfCanClose = 1;
      return VSConstants.S_OK;
    }

    int IVsUIHierarchy.QueryStatusCommand(uint itemid, ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.SetGuidProperty(uint itemid, int propid, ref Guid rguid)
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.SetProperty(uint itemid, int propid, object var)
    {
      foreach(IVsHierarchyEvents listener in _events.Values)
      {
        listener.OnPropertyChanged(itemid, propid, 0);
      }
      return VSConstants.S_OK;
    }

    int IVsUIHierarchy.SetSite(Microsoft.VisualStudio.OLE.Interop.IServiceProvider psp)
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.UnadviseHierarchyEvents(uint dwCookie)
    {
      _events.Remove(dwCookie);
      return VSConstants.S_OK;
    }

    int IVsUIHierarchy.Unused0()
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.Unused1()
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.Unused2()
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.Unused3()
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsUIHierarchy.Unused4()
    {
      return VSConstants.E_NOTIMPL;
    }

    #endregion

    #region IVsHierarchy Members

    int IVsHierarchy.AdviseHierarchyEvents(IVsHierarchyEvents pEventSink, out uint pdwCookie)
    {
      return ((IVsUIHierarchy)this).AdviseHierarchyEvents(pEventSink, out pdwCookie);
    }

    int IVsHierarchy.Close()
    {
      return ((IVsUIHierarchy)this).Close();
    }

    int IVsHierarchy.GetCanonicalName(uint itemid, out string pbstrName)
    {
      return ((IVsUIHierarchy)this).GetCanonicalName(itemid, out pbstrName);
    }

    int IVsHierarchy.GetGuidProperty(uint itemid, int propid, out Guid pguid)
    {
      return ((IVsUIHierarchy)this).GetGuidProperty(itemid, propid, out pguid);
    }

    int IVsHierarchy.GetNestedHierarchy(uint itemid, ref Guid iidHierarchyNested, out IntPtr ppHierarchyNested, out uint pitemidNested)
    {
      return ((IVsUIHierarchy)this).GetNestedHierarchy(itemid, ref iidHierarchyNested, out ppHierarchyNested, out pitemidNested);
    }

    int IVsHierarchy.GetProperty(uint itemid, int propid, out object pvar)
    {
      return ((IVsUIHierarchy)this).GetProperty(itemid, propid, out pvar);
    }

    int IVsHierarchy.GetSite(out Microsoft.VisualStudio.OLE.Interop.IServiceProvider ppSP)
    {
      ppSP = null;
      return VSConstants.E_NOTIMPL;
    }

    int IVsHierarchy.ParseCanonicalName(string pszName, out uint pitemid)
    {
      pitemid = 0;
      return VSConstants.E_NOTIMPL;
    }

    int IVsHierarchy.QueryClose(out int pfCanClose)
    {
      return ((IVsUIHierarchy)this).QueryClose(out pfCanClose);
    }

    int IVsHierarchy.SetGuidProperty(uint itemid, int propid, ref Guid rguid)
    {
      return ((IVsUIHierarchy)this).SetGuidProperty(itemid, propid, ref rguid);
    }

    int IVsHierarchy.SetProperty(uint itemid, int propid, object var)
    {
      return ((IVsUIHierarchy)this).SetProperty(itemid, propid, var);
    }

    int IVsHierarchy.SetSite(Microsoft.VisualStudio.OLE.Interop.IServiceProvider psp)
    {
      return ((IVsUIHierarchy)this).SetSite(psp);
    }

    int IVsHierarchy.UnadviseHierarchyEvents(uint dwCookie)
    {
      return ((IVsUIHierarchy)this).UnadviseHierarchyEvents(dwCookie);
    }

    int IVsHierarchy.Unused0()
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsHierarchy.Unused1()
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsHierarchy.Unused2()
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsHierarchy.Unused3()
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsHierarchy.Unused4()
    {
      return VSConstants.E_NOTIMPL;
    }

    #endregion

    #region IVsPersistHierarchyItem Members

    int IVsPersistHierarchyItem.IsItemDirty(uint itemid, IntPtr punkDocData, out int pfDirty)
    {
      return ((IVsPersistDocData)_control).IsDocDataDirty(out pfDirty);
    }

    int IVsPersistHierarchyItem.SaveItem(VSSAVEFLAGS dwSave, string pszSilentSaveAsName, uint itemid, IntPtr punkDocData, out int pfCanceled)
    {
      return ((IVsPersistDocData)_control).SaveDocData(dwSave, out pszSilentSaveAsName, out pfCanceled);
    }

    #endregion

    #region IVsPersistHierarchyItem2 Members

    int IVsPersistHierarchyItem2.IgnoreItemFileChanges(uint itemid, int fIgnore)
    {
      return VSConstants.E_NOTIMPL;
    }

    int IVsPersistHierarchyItem2.IsItemDirty(uint itemid, IntPtr punkDocData, out int pfDirty)
    {
      return ((IVsPersistDocData)_control).IsDocDataDirty(out pfDirty);
    }

    int IVsPersistHierarchyItem2.IsItemReloadable(uint itemid, out int pfReloadable)
    {
      return ((IVsPersistDocData)_control).IsDocDataReloadable(out pfReloadable);
    }

    int IVsPersistHierarchyItem2.ReloadItem(uint itemid, uint dwReserved)
    {
      return ((IVsPersistDocData)_control).ReloadDocData(dwReserved);
    }

    int IVsPersistHierarchyItem2.SaveItem(VSSAVEFLAGS dwSave, string pszSilentSaveAsName, uint itemid, IntPtr punkDocData, out int pfCanceled)
    {
      return ((IVsPersistDocData)_control).SaveDocData(dwSave, out pszSilentSaveAsName, out pfCanceled);
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/Editors/TableDesignerDoc.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="_splitter.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="name.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="type.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="isnull.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="_imageList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
    <value>17, 17</value>
  </metadata>
  <data name="_imageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
    <value>
        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
        LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACA
        AgAAAk1TRnQBSQFMAwEBAAEEAQABBAEAASgBAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABoAMA
        ARADAAEBAQABGAYAAR7/AP8A/wD/ADMAAcMBzgHVARkBQAFaAbkBwQHG/wDYAAELAUIBYgExAcIB7AEl
        AT8BTgGxAbkBvf8A1QABEgFRAXEBXgHjAf8BMwGjAcIBIgExAT7/ANUAARcBXgF8AVcB4AH/AQsBNQFM
        AccBzwHT/wDVAAEeAWsBiwFuAecB/wFDAbwB2wE2AU0BXf8A0gABvQHJAdEBHgFqAYsBdwHpAf4BHgFA
        AU0BvQHGAcr/AM8AAd0B4wHnARwBWwF7AXwB6wH/AYoB7wH/AWAB0gHlAQ0BMwFDAaIBrwG2/wDMAAEj
        AWgBiQGHAewB+QGbAfMB/wGDAe8B/wGiAfYB/wFtAc0B3gEGASoBQP8AzAABMAF1AZIBrgH3Af8BhwHj
        Ae8BLgFhAXsBjQHlAfEBrgH4Af8BBQFCAV//AMwAAUcBkAGpAZ8B9QH/Aa4B+gH/AZIB5wHwAbEB+gH/
        AYoB6QH1AQQBSgFo/wDMAAHTAdsB3wFpAbYBygFSAZwBswE5AYABmgElAW8BkAEZAWoBjgHWAd0B4f8A
        /wD/AP8A/wD/AP8AGwABQgFNAT4HAAE+AwABKAMAAaADAAEQAwABAQEAAQEFAAFAAQEWAAP/AQAF/w8A
        Bf8PAAP/Af4BPw8AA/8B/gEfDwAD/wH+AR8PAAP/Af4BHw8AA/8B/gEfDwAD/wH8AR8PAAP/AfgBDw8A
        A/8B+AEPDwAD/wH4AQ8PAAP/AfgBDw8AA/8B+AEPDwAF/w8ABf8PAAX/DwAL
</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































Deleted SQLite.Designer/Editors/ViewDesignerDoc.Designer.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Editors
{
  partial class ViewDesignerDoc
  {
    /// <summary> 
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      _editingTables.Remove(GetHashCode());
      base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.components = new System.ComponentModel.Container();
      this._timer = new System.Windows.Forms.Timer(this.components);
      this._check = new System.Windows.Forms.Timer(this.components);
      this._pg = new System.Windows.Forms.PropertyGrid();
      this.SuspendLayout();
      // 
      // _timer
      // 
      this._timer.Tick += new System.EventHandler(this._timer_Tick);
      // 
      // _check
      // 
      this._check.Interval = 200;
      this._check.Tick += new System.EventHandler(this._check_Tick);
      // 
      // _pg
      // 
      this._pg.Location = new System.Drawing.Point(0, 3);
      this._pg.Name = "_pg";
      this._pg.PropertySort = System.Windows.Forms.PropertySort.NoSort;
      this._pg.Size = new System.Drawing.Size(130, 130);
      this._pg.TabIndex = 2;
      this._pg.ToolbarVisible = false;
      this._pg.Visible = false;
      // 
      // ViewDesignerDoc
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.Controls.Add(this._pg);
      this.Font = new System.Drawing.Font("MS Shell Dlg 2", 8.25F);
      this.Name = "ViewDesignerDoc";
      this.Size = new System.Drawing.Size(553, 407);
      this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.Timer _timer;
    private System.Windows.Forms.Timer _check;
    private System.Windows.Forms.PropertyGrid _pg;
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































Deleted SQLite.Designer/Editors/ViewDesignerDoc.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer.Editors
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Data.Common;
  using System.Drawing;
  using System.Text;
  using System.Windows.Forms;
  using Microsoft.VisualStudio.Shell.Interop;
  using Microsoft.VisualStudio.OLE.Interop;
  using Microsoft.VisualStudio;
  using Microsoft.VisualStudio.Data;
  using SQLite.Designer.Design;
  using System.ComponentModel.Design;
  using System.Runtime.InteropServices;
  using System.Globalization;

  public partial class ViewDesignerDoc : DesignerDocBase,
    IVsPersistDocData,
    IVsWindowPane,
    IOleCommandTarget,
    ISelectionContainer,
    IVsWindowPaneCommit,
    IVsWindowFrameNotify
  {
    private static Dictionary<int, string> _editingTables = new Dictionary<int, string>();

    private bool _qdinit;
    private bool _init;
    internal DataConnection _connection;
    internal Microsoft.VisualStudio.Data.ServiceProvider _serviceProvider;
    internal bool _dirty;
    internal UserControl _queryDesigner;
    internal Type _typeQB;
    internal SQLite.Designer.Design.View _view;
    internal IOleCommandTarget _qbole;
    internal IOleInPlaceActiveObject _qbbase;
    private IntPtr _qbsql;
    internal DataViewHierarchyAccessor _accessor;
    internal int _itemId;
    static private bool _warned;

    public delegate bool EnumWindowsCallback(IntPtr hwnd, IntPtr lParam);
    [DllImport("user32.Dll")]
    static extern bool EnumChildWindows(IntPtr parentHandle, EnumWindowsCallback callback, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetWindowTextLength(IntPtr hWnd);

    public ViewDesignerDoc(int itemId, DataViewHierarchyAccessor accessor, string viewName)
    {
      _accessor = accessor;
      _connection = accessor.Connection;
      _itemId = itemId;
      InitializeComponent();

      _init = true;
      try
      {
        _typeQB = SQLiteDataAdapterToolboxItem._vsdesigner.GetType("Microsoft.VSDesigner.Data.Design.QueryBuilderControl");

        if (_typeQB != null)
        {
          _queryDesigner = Activator.CreateInstance(_typeQB) as UserControl;
          _typeQB.InvokeMember("Provider", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.NonPublic, null, _queryDesigner, new object[] { "System.Data.SQLite" });
          _typeQB.InvokeMember("ConnectionString", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.NonPublic, null, _queryDesigner, new object[] { _connection.ConnectionSupport.ConnectionString });
          _typeQB.InvokeMember("EnableMorphing", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.NonPublic, null, _queryDesigner, new object[] { false });
          Controls.Add(_queryDesigner);
          _queryDesigner.Dock = DockStyle.Fill;
          _queryDesigner.Visible = true;
        }

        StringBuilder tables = new StringBuilder();

        using (DataReader reader = _connection.Command.Execute("SELECT * FROM sqlite_master", 1, null, 30))
        {
          while (reader.Read())
          {
            tables.Append(reader.GetItem(2).ToString());
            tables.Append(",");
          }
        }

        int n = 1;

        if (String.IsNullOrEmpty(viewName))
        {
          string alltables = tables.ToString();

          do
          {
            viewName = String.Format(CultureInfo.InvariantCulture, "View{0}", n);
            n++;
          } while (alltables.IndexOf(viewName + ",", StringComparison.OrdinalIgnoreCase) > -1 || _editingTables.ContainsValue(viewName));

          _editingTables.Add(GetHashCode(), viewName);
        }
        _view = new SQLite.Designer.Design.View(viewName, _connection.ConnectionSupport.ProviderObject as DbConnection, this);
      }
      finally
      {
        _init = false;
      }
    }

    private string GetRichText()
    {
      if (_qbsql != IntPtr.Zero)
      {
        int len = GetWindowTextLength(_qbsql);
        StringBuilder builder = new StringBuilder(len + 1);
        GetWindowText(_qbsql, builder, builder.Capacity);
        return builder.ToString();
      }
      return String.Empty;
    }

    void SetPropertyWindow()
    {
      IVsTrackSelectionEx track = _serviceProvider.GetService(typeof(SVsTrackSelectionEx)) as IVsTrackSelectionEx;
      if (track != null)
      {
        track.OnSelectChange(this);
      }
    }

    public string Caption
    {
      get
      {
        string catalog = "main";
        if (_view != null) catalog = _view.Catalog;

        return String.Format(CultureInfo.InvariantCulture, "{0}.{1} View (SQLite [{2}])", catalog, base.Name, ((DbConnection)_connection.ConnectionSupport.ProviderObject).DataSource);
      }
    }

    public override string CanonicalName
    {
      get
      {
        return _view.Name;
      }
    }
    public new string Name
    {
      get
      {
        if (_view != null)
          return _view.Name;
        else 
        return base.Name;
      }
      set
      {
        base.Name = value;

        if (_serviceProvider != null)
        {
          IVsWindowFrame frame = _serviceProvider.GetService(typeof(IVsWindowFrame)) as IVsWindowFrame;
          if (frame != null)
          {
            frame.SetProperty((int)__VSFPROPID.VSFPROPID_EditorCaption, Caption);
          }
        }
      }
    }

    public void NotifyChanges()
    {
      if (_serviceProvider == null) return;

      // Get a reference to the Running Document Table
      IVsRunningDocumentTable runningDocTable = (IVsRunningDocumentTable)_serviceProvider.GetService(typeof(SVsRunningDocumentTable));

      // Lock the document
      uint docCookie;
      IVsHierarchy hierarchy;
      uint itemID;
      IntPtr docData;
      int hr = runningDocTable.FindAndLockDocument(
          (uint)_VSRDTFLAGS.RDT_ReadLock,
          base.Name,
          out hierarchy,
          out itemID,
          out docData,
          out docCookie
      );
      ErrorHandler.ThrowOnFailure(hr);

      IVsUIShell shell = _serviceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;
      if (shell != null)
      {
        shell.UpdateDocDataIsDirtyFeedback(docCookie, (_dirty == true) ? 1 : 0);
      }

      // Unlock the document.
      // Note that we have to unlock the document even if the previous call failed.
      runningDocTable.UnlockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, docCookie);

      // Check ff the call to NotifyDocChanged failed.
      //ErrorHandler.ThrowOnFailure(hr);
    }

    #region IVsPersistDocData Members

    int IVsPersistDocData.Close()
    {
      return VSConstants.S_OK;
    }

    public int GetGuidEditorType(out Guid pClassID)
    {
      return ((IPersistFileFormat)this).GetClassID(out pClassID);
    }

    public int IsDocDataDirty(out int pfDirty)
    {
      pfDirty = _dirty == true ? 1 : 0;
      return VSConstants.S_OK;
    }

    public int IsDocDataReloadable(out int pfReloadable)
    {
      pfReloadable = 0;
      return VSConstants.S_OK;
    }

    public int LoadDocData(string pszMkDocument)
    {
      return ((IPersistFileFormat)this).Load(pszMkDocument, 0, 0);
    }

    public int OnRegisterDocData(uint docCookie, IVsHierarchy pHierNew, uint itemidNew)
    {
      return VSConstants.S_OK;
    }

    public int ReloadDocData(uint grfFlags)
    {
      return VSConstants.E_NOTIMPL;
    }

    public int RenameDocData(uint grfAttribs, IVsHierarchy pHierNew, uint itemidNew, string pszMkDocumentNew)
    {
      return VSConstants.E_NOTIMPL;
    }

    private void CommitQueryBuilder()
    {
      string query = _typeQB.InvokeMember("SqlText", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty, null, _queryDesigner, null) as string;
      _view.SqlText = query;
    }

    public int SaveDocData(VSSAVEFLAGS dwSave, out string pbstrMkDocumentNew, out int pfSaveCanceled)
    {
      pbstrMkDocumentNew = null; // _view.Name;
      pfSaveCanceled = 0;

      if (String.IsNullOrEmpty(_view.OriginalSql) == true)
      {
        using (TableNameDialog dlg = new TableNameDialog("View", _view.Name))
        {
          if (dlg.ShowDialog(this) == DialogResult.Cancel)
          {
            pfSaveCanceled = 1;
            return VSConstants.S_OK;
          }
          _view.Name = dlg.TableName;
        }
      }

      CommitQueryBuilder();

      string query = _view.GetSqlText();
      if (String.IsNullOrEmpty(query) == false)
      {
        using (DbTransaction trans = _view.GetConnection().BeginTransaction())
        {
          try
          {
            using (DbCommand cmd = _view.GetConnection().CreateCommand())
            {
              cmd.CommandText = query;
              cmd.ExecuteNonQuery();
            }
            trans.Commit();
          }
          catch (Exception)
          {
            trans.Rollback();
            throw;
          }
        }
      }

      _dirty = false;
      _view.Committed();
      NotifyChanges();

      SQLiteCommandHandler.Refresh(_accessor, _itemId);

      return VSConstants.S_OK;
    }

    public int SetUntitledDocPath(string pszDocDataPath)
    {
      return ((IPersistFileFormat)this).InitNew(0);
    }

    #endregion

    #region IVsWindowPane Members

    public int ClosePane()
    {
      this.Dispose(true);
      return VSConstants.S_OK;
    }

    public int CreatePaneWindow(IntPtr hwndParent, int x, int y, int cx, int cy, out IntPtr hwnd)
    {
      Win32Methods.SetParent(Handle, hwndParent);
      hwnd = Handle;

      Size = new System.Drawing.Size(cx - x, cy - y);
      return VSConstants.S_OK;
    }

    public int GetDefaultSize(Microsoft.VisualStudio.OLE.Interop.SIZE[] size)
    {
      if (size.Length >= 1)
      {
        size[0].cx = Size.Width;
        size[0].cy = Size.Height;
      }

      return VSConstants.S_OK;
    }

    public int LoadViewState(Microsoft.VisualStudio.OLE.Interop.IStream pStream)
    {
      return VSConstants.S_OK;
    }

    public int SaveViewState(Microsoft.VisualStudio.OLE.Interop.IStream pStream)
    {
      return VSConstants.S_OK;
    }

    public void RefreshToolbars()
    {
      if (_serviceProvider == null) return;

      IVsUIShell shell = _serviceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;

      if (shell != null)
      {
        shell.UpdateCommandUI(1);
      }
    }

    public int SetSite(Microsoft.VisualStudio.OLE.Interop.IServiceProvider psp)
    {
      _serviceProvider = new MyServiceProvider(psp);
      System.Reflection.MethodInfo mi = _typeQB.GetMethod("Init", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[] { typeof(System.IServiceProvider), typeof(string) }, null);
      mi.Invoke(_queryDesigner, new object[] { _serviceProvider, _view.SqlText });

      _qbole = _typeQB.InvokeMember("OleCommandTarget", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetProperty, null, _queryDesigner, null) as IOleCommandTarget;
      _qbbase = _typeQB.InvokeMember("OleInPlaceActiveObject", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetProperty, null, _queryDesigner, null) as IOleInPlaceActiveObject;

      return VSConstants.S_OK;
    }

    private bool EnumWindows(IntPtr hwnd, IntPtr lparam)
    {
      if (_qbsql != IntPtr.Zero) return false;

      StringBuilder builder = new StringBuilder(256);
      GetClassName(hwnd, builder, builder.Capacity);
      if (String.Compare(builder.ToString(), "RichEdit20W", StringComparison.OrdinalIgnoreCase) == 0)
      {
        _qbsql = hwnd;
        return false;
      }
      
      EnumChildWindows(hwnd, new EnumWindowsCallback(EnumWindows), IntPtr.Zero);

      return true;
    }

    public int TranslateAccelerator(Microsoft.VisualStudio.OLE.Interop.MSG[] lpmsg)
    {
      return VSConstants.S_FALSE;
    }

    #endregion

    public void MakeDirty()
    {
      if (_init == true) return;
      _dirty = true;
      NotifyChanges();
    }

    #region IOleCommandTarget Members

    public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
    {
      if (pguidCmdGroup == SQLiteCommandHandler.guidSQLiteCmdSet)
      {
        switch ((cmdid)nCmdID)
        {
          case cmdid.Triggers:
            ViewHolder holder = new ViewHolder(_view);
            _pg.SelectedObject = holder;
            _pg.SelectedGridItem = _pg.SelectedGridItem.Parent.GridItems[0];
            CommitQueryBuilder();
            TriggerEditor ted = new TriggerEditor(_view);
            ted.EditValue((ITypeDescriptorContext)_pg.SelectedGridItem, (System.IServiceProvider)_pg.SelectedGridItem, _pg.SelectedGridItem.Value);
            return VSConstants.S_OK;
        }
      }


      if (_qbole != null) return _qbole.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

      return (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
    }

    public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
      if (pguidCmdGroup == SQLiteCommandHandler.guidSQLiteCmdSet)
      {
        switch (prgCmds[0].cmdID)
        {
          case (uint)cmdid.Triggers:
            prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
            return VSConstants.S_OK;
        }
      }


      int retval = (int)(Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED);
      
      if (_qbole != null)
        retval = _qbole.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);

      //if (pguidCmdGroup == SQLiteCommandHandler.guidQueryGroup)
      //{
        // 0x83 -- show SQL pane
        // 0x84 -- show diagram pane
        // 0x0f --
        // 0x10 -- 
        // 0x1a --
        // 0xc9 -- execute SQL
        // 0x86 -- show criteria pane
        // 0x85 -- show results pane
        // 0x76 --
        // 0x6b -- verify sql syntax
        // 0x79 -- add group by
      //}

      return retval;
    }

    #endregion

    #region ISelectionContainer Members

    int ISelectionContainer.CountObjects(uint dwFlags, out uint pc)
    {
      pc = 1;
      return VSConstants.S_OK;
    }

    int ISelectionContainer.GetObjects(uint dwFlags, uint cObjects, object[] apUnkObjects)
    {
      apUnkObjects[0] = _view;
      return VSConstants.S_OK;
    }

    int ISelectionContainer.SelectObjects(uint cSelect, object[] apUnkSelect, uint dwFlags)
    {
      return VSConstants.S_OK;
    }

    #endregion

    #region IVsWindowPaneCommit Members

    int IVsWindowPaneCommit.CommitPendingEdit(out int pfCommitFailed)
    {
      pfCommitFailed = 0;
      return VSConstants.S_OK;
    }

    #endregion

    #region IVsWindowFrameNotify Members

    int IVsWindowFrameNotify.OnDockableChange(int fDockable)
    {
      return VSConstants.S_OK;
    }

    int IVsWindowFrameNotify.OnMove()
    {
      return VSConstants.S_OK;
    }

    private void _timer_Tick(object sender, EventArgs e)
    {
      _timer.Enabled = false;
      if (_serviceProvider != null)
      {
        EnvDTE.DTE dte = (EnvDTE.DTE)_serviceProvider.GetService(typeof(EnvDTE.DTE));

        if (_qdinit == false)
        {
          _qdinit = true;
          _init = true;
          try
          {
            _typeQB.InvokeMember("PostInit", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod, null, _queryDesigner, null);

            if (_qbbase != null)
            {
              EnumChildWindows(Handle, new EnumWindowsCallback(EnumWindows), IntPtr.Zero);
            }

            _check_Tick(this, EventArgs.Empty);

            _typeQB.InvokeMember("ShowAddTableDialogIfNeeded", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod, null, _queryDesigner, null);
          }
          finally
          {
            _init = false;
            _check.Enabled = true;
          }
        }
      }
    }

    int IVsWindowFrameNotify.OnShow(int fShow)
    {
      switch ((__FRAMESHOW)fShow)
      {
        case __FRAMESHOW.FRAMESHOW_WinShown:
        case __FRAMESHOW.FRAMESHOW_WinRestored:
          _timer.Enabled = true;
          SetPropertyWindow();
          if (_warned == false)
          {
            _warned = true;
            MessageBox.Show(this, "The view designer is still in development.  Please report bugs to robert@blackcastlesoft.com", "Feature Under Review", MessageBoxButtons.OK);
          }
          break;
      }
      return VSConstants.S_OK;
    }

    int IVsWindowFrameNotify.OnSize()
    {
      return VSConstants.S_OK;
    }

    #endregion

    private void _check_Tick(object sender, EventArgs e)
    {
      string str = GetRichText();

      _view.SqlText = str;
    }
  }

  internal class MyServiceProvider : ServiceProvider
  {
    Microsoft.VisualStudio.OLE.Interop.IServiceProvider _psp;

    internal MyServiceProvider(Microsoft.VisualStudio.OLE.Interop.IServiceProvider psp)
    {
      _psp = psp;
    }

    protected override object GetServiceImpl(Guid serviceGuid)
    {
      IntPtr zero = IntPtr.Zero;
      Guid unk = new Guid("00000000-0000-0000-c000-000000000046");
      Guid self = new Guid("6d5140c1-7436-11ce-8034-00aa006009fa");

      if (serviceGuid == self) return this;

      int status = _psp.QueryService(ref serviceGuid, ref unk, out zero);
      if (status < 0)
      {
        if ((status == -2147467259) || (status == -2147467262))
        {
          return null;
        }
        Marshal.ThrowExceptionForHR(status);
      }
      object objectForIUnknown = Marshal.GetObjectForIUnknown(zero);
      Marshal.Release(zero);
      return objectForIUnknown;
    }

    protected override object GetServiceImpl(Type serviceType)
    {
      return this.GetService(serviceType.GUID);
    }
  }

  internal class ViewHolder
  {
    private List<ViewTrigger> _triggers;

    internal ViewHolder(SQLite.Designer.Design.View parent)
    {
      _triggers = parent.Triggers as List<ViewTrigger>;
    }

    public List<ViewTrigger> Triggers
    {
      get { return _triggers; }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/Editors/ViewDesignerDoc.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="_timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
    <value>17, 17</value>
  </metadata>
  <metadata name="_check.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
    <value>102, 17</value>
  </metadata>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































Deleted SQLite.Designer/PkgCmd.vsct.
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
<?xml version="1.0" encoding="utf-8"?>
<CommandTable language="en-US" xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable">
  <Extern href="PkgCmd.h" />
  <Commands package="guidVSPackageBasedProviderPkg">
    <Buttons>
      
      <Button guid="guidVSPackageBasedProviderCmdSet" id="cmdidVacuum" type="Button">
        <CommandFlag>DefaultInvisible</CommandFlag>
        <CommandFlag>DynamicVisibility</CommandFlag>
        <CommandFlag>DefaultDisabled</CommandFlag>
        <Strings>
          <ButtonText>&amp;Vacuum</ButtonText>
        </Strings>
      </Button>
      
      <Button guid="guidVSPackageBasedProviderCmdSet" id="cmdidRekey" type="Button">
        <CommandFlag>DefaultInvisible</CommandFlag>
        <CommandFlag>DynamicVisibility</CommandFlag>
        <CommandFlag>DefaultDisabled</CommandFlag>
        <Strings>
          <ButtonText>Change &amp;Password ...</ButtonText>
        </Strings>
      </Button>

      <Button guid="guidVSPackageBasedProviderCmdSet" id="cmdidTriggers" priority="0x0700" type="Button">
        <Icon guid="guidSharedBmps8" id="bmpid8LayoutDiagram"/>
        <CommandFlag>DynamicVisibility</CommandFlag>
        <CommandFlag>DefaultInvisible</CommandFlag>
        <CommandFlag>DefaultDisabled</CommandFlag>
        <Strings>
          <ButtonText>Manage &amp;Triggers</ButtonText>
          <ToolTipText>Manage Triggers</ToolTipText>
          <CommandName>Manage Triggers</CommandName>
        </Strings>
      </Button>

    </Buttons>
  </Commands>
  <CommandPlacements>
    <CommandPlacement guid="guidVSPackageBasedProviderCmdSet" id="cmdidVacuum" priority="0x0100">
      <Parent guid="guidVSData" id="IDG_DV_CONNECTION" />
    </CommandPlacement>
    <CommandPlacement guid="guidVSPackageBasedProviderCmdSet" id="cmdidRekey" priority="0x0100">
      <Parent guid="guidVSData" id="IDG_DV_CONNECTION" />
    </CommandPlacement>

    <CommandPlacement guid="guidVSPackageBasedProviderCmdSet" id="cmdidTriggers" priority="0x0700">
      <Parent guid="guidDavDataGrpId" id="IDG_SCH_TOOLBAR_TABLEOPS" />
    </CommandPlacement>

    <CommandPlacement guid="guidVSPackageBasedProviderCmdSet" id="cmdidTriggers" priority="0x1000">
      <Parent guid="guidDavDataGrpId" id="IDG_QRY_TOOLBAR_VIEWSHAPE" />
    </CommandPlacement>


  </CommandPlacements>  
  <Symbols>
    <GuidSymbol name="Group_Undefined" value="{83285929-227c-11d3-b870-00c04f79f802}" />
    <GuidSymbol name="Pkg_Undefined" value="{8328592a-227c-11d3-b870-00c04f79f802}" />
    <GuidSymbol name="guidVSPackageBasedProviderPkg" value="{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" />
    <GuidSymbol name="guidVSData" value="{4614107f-217d-4bbf-9dfe-b9e165c65572}">
      <IDSymbol name="IDG_DV_CONNECTION" value="0x4101" />
    </GuidSymbol>
    <GuidSymbol name="guidVSPackageBasedProviderCmdSet" value="{814658ee-a28e-4b97-bc33-4b1bc81ebecb}">
      <IDSymbol name="cmdidRekey" value="0x0107" />
      <IDSymbol name="cmdidVacuum" value="0x0106" />
      <IDSymbol name="cmdidTriggers" value="0x0108" />
    </GuidSymbol>
    <GuidSymbol name="guidOfficeIcon" value="{d309f794-903f-11d0-9efc-00a0c911004f}">
      <IDSymbol name="msotcidNoIcon" value="0x02EA" />
    </GuidSymbol>
  </Symbols>
</CommandTable>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































Deleted SQLite.Designer/Pkgcmd.h.
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef _PKGCMDS_
#define _PKGCMDS_

#define guidSharedBmps8                             {2b671d3d-ab51-434a-8d38-cbf1728530bb}
#define guidDavDataGrpId                            {732abe74-cd80-11d0-a2db-00aa00a3efff}
#define GUID_Mode_TableDesigner                     {4194fee5-6777-419f-a5fc-47a536df1bdb}

#define bmpid8LayoutDiagram                         0x0004
#define IDG_SCH_TOOLBAR_TABLEOPS                    0x1110
#define IDG_QRY_TOOLBAR_VIEWSHAPE                   0x1012

#endif
<
<
<
<
<
<
<
<
<
<
<
<
























Deleted SQLite.Designer/Resources/ToolboxItems.txt.
1
2
3
4
[SQLite]
System.Data.SQLite.SQLiteConnection, System.Data.SQLite
System.Data.SQLite.SQLiteDataAdapter, System.Data.SQLite
System.Data.SQLite.SQLiteCommand, System.Data.SQLite
<
<
<
<








Deleted SQLite.Designer/Resources/info.png.

cannot compute difference between binary files

Deleted SQLite.Designer/SQLite.Designer.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Designer.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>SQLite.Designer</RootNamespace>
    <AssemblyName>SQLite.Designer</AssemblyName>
    <OldToolsVersion>2.0</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)SQLite.Designer.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Design" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
    <Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.Data.ConnectionUI, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.CommandBars, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Data, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Data.Services, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.OLE.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Shell, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Shell.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="ChangePasswordDialog.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="ChangePasswordDialog.Designer.cs">
      <DependentUpon>ChangePasswordDialog.cs</DependentUpon>
    </Compile>
    <Compile Include="ChangeScriptDialog.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="ChangeScriptDialog.Designer.cs">
      <DependentUpon>ChangeScriptDialog.cs</DependentUpon>
    </Compile>
    <Compile Include="Design\Check.cs" />
    <Compile Include="Design\Column.cs" />
    <Compile Include="Design\ForeignKey.cs" />
    <Compile Include="Design\Index.cs" />
    <Compile Include="Design\PrimaryKey.cs" />
    <Compile Include="Design\SimpleTokenizer.cs" />
    <Compile Include="Design\Table.cs" />
    <Compile Include="Design\Trigger.cs" />
    <Compile Include="Design\Unique.cs" />
    <Compile Include="Design\View.cs" />
    <Compile Include="Editors\AutoCompleteColumn.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Editors\TableDesignerDoc.cs">
      <SubType>UserControl</SubType>
    </Compile>
    <Compile Include="Editors\TableDesignerDoc.Designer.cs">
      <DependentUpon>TableDesignerDoc.cs</DependentUpon>
    </Compile>
    <Compile Include="Editors\ViewDesignerDoc.cs">
      <SubType>UserControl</SubType>
    </Compile>
    <Compile Include="Editors\ViewDesignerDoc.Designer.cs">
      <DependentUpon>ViewDesignerDoc.cs</DependentUpon>
    </Compile>
    <Compile Include="SQLiteAdapterDesigner.cs" />
    <Compile Include="SQLiteCommandDesigner.cs" />
    <Compile Include="SQLiteCommandHandler.cs" />
    <Compile Include="SQLiteConnectionProperties.cs" />
    <Compile Include="SQLiteConnectionStringEditor.cs" />
    <Compile Include="SQLiteConnectionUIControl.cs">
      <SubType>UserControl</SubType>
    </Compile>
    <Compile Include="SQLiteConnectionUIControl.Designer.cs">
      <DependentUpon>SQLiteConnectionUIControl.cs</DependentUpon>
    </Compile>
    <Compile Include="SQLiteDataAdapterToolboxItem.cs" />
    <Compile Include="SQLiteDataConnectionSupport.cs" />
    <Compile Include="SQLiteDataObjectIdentifierResolver.cs" />
    <Compile Include="SQLiteDataObjectSupport.cs" />
    <Compile Include="SQLiteDataSourceInformation.cs" />
    <Compile Include="SQLiteDataViewSupport.cs" />
    <Compile Include="SQLitePackage.cs" />
    <Compile Include="SQLiteProviderObjectFactory.cs" />
    <Compile Include="TableNameDialog.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="TableNameDialog.Designer.cs">
      <DependentUpon>TableNameDialog.cs</DependentUpon>
    </Compile>
    <Compile Include="VSPackage.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>VSPackage.resx</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <VSCTCompile Include="PkgCmd.vsct">
      <ResourceName>1000</ResourceName>
    </VSCTCompile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="SQLiteDataViewSupport2005.xml" />
    <EmbeddedResource Include="SQLiteDataViewSupport2008.xml" />
    <EmbeddedResource Include="SQLiteDataViewSupport2010.xml" />
    <EmbeddedResource Include="VSPackage.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>VSPackage.Designer.cs</LastGenOutput>
      <MergeWithCTO>true</MergeWithCTO>
      <SubType>Designer</SubType>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="ChangePasswordDialog.resx">
      <SubType>Designer</SubType>
      <DependentUpon>ChangePasswordDialog.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="Editors\TableDesignerDoc.resx">
      <SubType>Designer</SubType>
      <DependentUpon>TableDesignerDoc.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="Editors\ViewDesignerDoc.resx">
      <DependentUpon>ViewDesignerDoc.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="SQLiteConnectionUIControl.resx">
      <SubType>Designer</SubType>
      <DependentUpon>SQLiteConnectionUIControl.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="SQLiteDataObjectSupport.xml" />
    <EmbeddedResource Include="TableNameDialog.resx">
      <DependentUpon>TableNameDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="ChangeScriptDialog.resx">
      <DependentUpon>ChangeScriptDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\info.png" />
    <None Include="Resources\ToolboxItems.txt" />
    <None Include="source.extension.vsixmanifest" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































Deleted SQLite.Designer/SQLite.Designer.2010.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Designer.2010.csproj -
 *
 * 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>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.30319</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>SQLite.Designer</RootNamespace>
    <AssemblyName>SQLite.Designer</AssemblyName>
    <OldToolsVersion>3.5</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <ConfigurationYear>2010</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)SQLite.Designer.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Design" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
    <Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.Data.ConnectionUI, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.CommandBars, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Data, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Data.Services, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.OLE.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Shell, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Shell.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="ChangePasswordDialog.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="ChangePasswordDialog.Designer.cs">
      <DependentUpon>ChangePasswordDialog.cs</DependentUpon>
    </Compile>
    <Compile Include="ChangeScriptDialog.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="ChangeScriptDialog.Designer.cs">
      <DependentUpon>ChangeScriptDialog.cs</DependentUpon>
    </Compile>
    <Compile Include="Design\Check.cs" />
    <Compile Include="Design\Column.cs" />
    <Compile Include="Design\ForeignKey.cs" />
    <Compile Include="Design\Index.cs" />
    <Compile Include="Design\PrimaryKey.cs" />
    <Compile Include="Design\SimpleTokenizer.cs" />
    <Compile Include="Design\Table.cs" />
    <Compile Include="Design\Trigger.cs" />
    <Compile Include="Design\Unique.cs" />
    <Compile Include="Design\View.cs" />
    <Compile Include="Editors\AutoCompleteColumn.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Editors\TableDesignerDoc.cs">
      <SubType>UserControl</SubType>
    </Compile>
    <Compile Include="Editors\TableDesignerDoc.Designer.cs">
      <DependentUpon>TableDesignerDoc.cs</DependentUpon>
    </Compile>
    <Compile Include="Editors\ViewDesignerDoc.cs">
      <SubType>UserControl</SubType>
    </Compile>
    <Compile Include="Editors\ViewDesignerDoc.Designer.cs">
      <DependentUpon>ViewDesignerDoc.cs</DependentUpon>
    </Compile>
    <Compile Include="SQLiteAdapterDesigner.cs" />
    <Compile Include="SQLiteCommandDesigner.cs" />
    <Compile Include="SQLiteCommandHandler.cs" />
    <Compile Include="SQLiteConnectionProperties.cs" />
    <Compile Include="SQLiteConnectionStringEditor.cs" />
    <Compile Include="SQLiteConnectionUIControl.cs">
      <SubType>UserControl</SubType>
    </Compile>
    <Compile Include="SQLiteConnectionUIControl.Designer.cs">
      <DependentUpon>SQLiteConnectionUIControl.cs</DependentUpon>
    </Compile>
    <Compile Include="SQLiteDataAdapterToolboxItem.cs" />
    <Compile Include="SQLiteDataConnectionSupport.cs" />
    <Compile Include="SQLiteDataObjectIdentifierResolver.cs" />
    <Compile Include="SQLiteDataObjectSupport.cs" />
    <Compile Include="SQLiteDataSourceInformation.cs" />
    <Compile Include="SQLiteDataViewSupport.cs" />
    <Compile Include="SQLitePackage.cs" />
    <Compile Include="SQLiteProviderObjectFactory.cs" />
    <Compile Include="TableNameDialog.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="TableNameDialog.Designer.cs">
      <DependentUpon>TableNameDialog.cs</DependentUpon>
    </Compile>
    <Compile Include="VSPackage.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>VSPackage.resx</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <VSCTCompile Include="PkgCmd.vsct">
      <ResourceName>1000</ResourceName>
    </VSCTCompile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="SQLiteDataViewSupport2005.xml" />
    <EmbeddedResource Include="SQLiteDataViewSupport2008.xml" />
    <EmbeddedResource Include="SQLiteDataViewSupport2010.xml" />
    <EmbeddedResource Include="VSPackage.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>VSPackage.Designer.cs</LastGenOutput>
      <MergeWithCTO>true</MergeWithCTO>
      <SubType>Designer</SubType>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="ChangePasswordDialog.resx">
      <SubType>Designer</SubType>
      <DependentUpon>ChangePasswordDialog.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="Editors\TableDesignerDoc.resx">
      <SubType>Designer</SubType>
      <DependentUpon>TableDesignerDoc.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="Editors\ViewDesignerDoc.resx">
      <DependentUpon>ViewDesignerDoc.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="SQLiteConnectionUIControl.resx">
      <SubType>Designer</SubType>
      <DependentUpon>SQLiteConnectionUIControl.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="SQLiteDataObjectSupport.xml" />
    <EmbeddedResource Include="TableNameDialog.resx">
      <DependentUpon>TableNameDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="ChangeScriptDialog.resx">
      <DependentUpon>ChangeScriptDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\info.png" />
    <None Include="Resources\ToolboxItems.txt" />
    <None Include="source.extension.vsixmanifest" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































Deleted SQLite.Designer/SQLiteAdapterDesigner.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.ComponentModel;
  using System.ComponentModel.Design;
  using System.Data.Common;
  using System.Collections;
  using System.Reflection;

  /// <summary>
  /// The purpose of this class is to provide context menus and event support when designing a 
  /// SQLite DataSet.  Most of the functionality is implemented by MS's VSDesigner object which we
  /// instantiate through reflection since I don't really have a design-time reference to the object
  /// and many of the objects in VSDesigner are internal.
  /// </summary>
  internal sealed class SQLiteAdapterDesigner : ComponentDesigner, IExtenderProvider
  {
    private ComponentDesigner _designer;

    /// <summary>
    /// Empty constructor
    /// </summary>
    public SQLiteAdapterDesigner()
    {
    }

    /// <summary>
    /// Initialize the designer by creating a SqlDataAdapterDesigner and delegating most of our
    /// functionality to it.
    /// </summary>
    /// <param name="component"></param>
    public override void Initialize(IComponent component)
    {
      base.Initialize(component);

      // Initialize a SqlDataAdapterDesigner through reflection and set it up to work on our behalf
      if (SQLiteDataAdapterToolboxItem._vsdesigner != null)
      {
        Type type = SQLiteDataAdapterToolboxItem._vsdesigner.GetType("Microsoft.VSDesigner.Data.VS.SqlDataAdapterDesigner");
        if (type != null)
        {
          _designer = (ComponentDesigner)Activator.CreateInstance(type);
          _designer.Initialize(component);
        }
      }
    }

    protected override void Dispose(bool disposing)
    {
      if (_designer != null && disposing)
        ((IDisposable)_designer).Dispose();

      base.Dispose(disposing);
    }

    /// <summary>
    /// Forwards to the SqlDataAdapterDesigner object
    /// </summary>
    public override DesignerVerbCollection Verbs
    {
      get
      {
        return (_designer != null) ? _designer.Verbs : null;
      }
    }

    /// <summary>
    /// Forwards to the SqlDataAdapterDesigner object
    /// </summary>
    public override ICollection AssociatedComponents
    {
      get
      {
        return (_designer != null) ? _designer.AssociatedComponents : null;
      }
    }

    #region IExtenderProvider Members
    /// <summary>
    /// We extend support for DbDataAdapter-derived objects
    /// </summary>
    /// <param name="extendee">The object wanting to be extended</param>
    /// <returns>Whether or not we extend that object</returns>
    public bool CanExtend(object extendee)
    {
      return (extendee is DbDataAdapter);
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted SQLite.Designer/SQLiteCommandDesigner.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.ComponentModel;
  using System.ComponentModel.Design;
  using System.Data.Common;
  using System.Data;

  /// <summary>
  /// This object provides a designer for a SQLiteCommand.  The reason we provide an additional
  /// CommandDesignTimeVisible property is because certain MS designer components will look for it and
  /// fail if its not there.
  /// </summary>
  [ProvideProperty("CommandDesignTimeVisible", typeof(IDbCommand))]
  internal sealed class SQLiteCommandDesigner : ComponentDesigner, IExtenderProvider
  {
    public SQLiteCommandDesigner()
    {
    }

    /// <summary>
    /// Initialize the instance with the given SQLiteCommand component
    /// </summary>
    /// <param name="component"></param>
    public override void Initialize(IComponent component)
    {
      base.Initialize(component);
    }

    /// <summary>
    /// Add our designtimevisible attribute to the attributes for the item
    /// </summary>
    /// <param name="attributes"></param>
    protected override void PreFilterAttributes(System.Collections.IDictionary attributes)
    {
      base.PreFilterAttributes(attributes);
      DesignTimeVisibleAttribute att = new DesignTimeVisibleAttribute(((DbCommand)Component).DesignTimeVisible);
      attributes[att.TypeId] = att;
    }

    /// <summary>
    /// Provide a get method for the CommandDesignTimeVisible provided property
    /// </summary>
    /// <param name="command">The SQLiteCommand we're designing for</param>
    /// <returns>True or false if the object is visible in design mode</returns>
    [Browsable(false), DesignOnly(true), DefaultValue(true)]
    public bool GetCommandDesignTimeVisible(IDbCommand command)
    {
      return ((DbCommand)command).DesignTimeVisible;
    }

    /// <summary>
    /// Provide a set method for our supplied CommandDesignTimeVisible property
    /// </summary>
    /// <param name="command">The SQLiteCommand to set</param>
    /// <param name="visible">The new designtime visible property to assign to the command</param>
    public void SetCommandDesignTimeVisible(IDbCommand command, bool visible)
    {
      ((DbCommand)command).DesignTimeVisible = visible;
    }

    #region IExtenderProvider Members

    /// <summary>
    /// We extend any DbCommand
    /// </summary>
    /// <param name="extendee">The object being tested</param>
    /// <returns>True if the object derives from DbCommand</returns>
    public bool CanExtend(object extendee)
    {
      return (extendee is DbCommand);
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted SQLite.Designer/SQLiteCommandHandler.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using Microsoft.VisualStudio.Data;
  using System.Windows.Forms.Design;
  using Microsoft.VisualStudio.Shell.Interop;
  using Microsoft.VisualStudio;
  using Microsoft.VisualStudio.OLE.Interop;
  using System.Data.Common;
  using System.Globalization;
  using SQLite.Designer.Editors;

  enum cmdid
  {
    CreateTable = 0x3520,
    CreateView = 0x3521,
    Alter = 0x3003,
    Refresh = 0x3004,
    Delete = 17,
    Vacuum = 262,
    Rekey = 263,
    Triggers = 264,
  }

  internal sealed class SQLiteCommandHandler : DataViewCommandHandler
  {
    internal static readonly Guid guidDataCmdSet = new Guid("501822E1-B5AF-11d0-B4DC-00A0C91506EF");
    internal static readonly Guid guidSQLiteCmdSet = new Guid("814658EE-A28E-4b97-BC33-4B1BC81EBECB");
    internal static readonly Guid guidIFCmdId = new Guid("{74d21311-2aee-11d1-8bfb-00a0c90f26f7}");
    internal static readonly Guid guidDavinci = new Guid("{732abe75-cd80-11d0-a2db-00aa00a3efff}");
    internal static readonly Guid guidDavinciGrp = new Guid("{732abe74-cd80-11d0-a2db-00aa00a3efff}");
    internal static readonly Guid guidQueryGroup = new Guid("5efc7975-14bc-11cf-9b2b-00aa00573819");
    internal static Guid guidTableDesignContext = new Guid("4194fee5-6777-419f-a5fc-47a536df1bdb");
    internal static Guid guidViewDesignContext = new Guid("b968e165-98e0-41f0-8fbe-a8ed1d246a90");

    public SQLiteCommandHandler()
    {
    }

    public override OleCommandStatus GetCommandStatus(int[] itemIds, OleCommand command, OleCommandTextType textType, OleCommandStatus status)
    {
      if (command.GroupGuid == guidSQLiteCmdSet)
      {
        switch ((cmdid)command.CommandId)
        {
          case cmdid.CreateTable:
          case cmdid.Vacuum:
          case cmdid.Rekey:
            status.Supported = true;
            status.Visible = true;
            status.Enabled = true;
            return status;
        }
      }
      else if (command.GroupGuid == VSConstants.GUID_VSStandardCommandSet97)
      {
        switch ((VSConstants.VSStd97CmdID)command.CommandId)
        {
          case VSConstants.VSStd97CmdID.Delete:
            status.Supported = true;
            status.Visible = true;
            status.Enabled = (SystemTableSelected == false && SystemIndexSelected == false);
            return status;
        }
      }
      else if (command.GroupGuid == guidDataCmdSet)
      {
        switch ((cmdid)command.CommandId)
        {
          case cmdid.Alter:
            status.Supported = true;
            status.Visible = true;
            status.Enabled = (SystemTableSelected == false && SystemIndexSelected == false);
            return status;
          case cmdid.CreateTable:
          case cmdid.CreateView:
            status.Supported = true;
            status.Visible = true;
            status.Enabled = true;
            return status;
        }
      }
      base.GetCommandStatus(itemIds, command, textType, status);

      return status;
    }

    private bool SystemTableSelected
    {
      get
      {
        int[] items = DataViewHierarchyAccessor.GetSelectedItems();
        int n;
        object[] parts;

        for (n = 0; n < items.Length; n++)
        {
          parts = DataViewHierarchyAccessor.GetObjectIdentifier(items[n]);
          if (parts == null) return true;

          if (parts[2].ToString().StartsWith("sqlite_", StringComparison.OrdinalIgnoreCase))
            return true;
        }
        return false;
      }
    }

    private bool SystemIndexSelected
    {
      get
      {
        int[] items = DataViewHierarchyAccessor.GetSelectedItems();
        int n;
        object[] parts;

        for (n = 0; n < items.Length; n++)
        {
          parts = DataViewHierarchyAccessor.GetObjectIdentifier(items[n]);
          if (parts == null) return true;

          if (parts[2].ToString().StartsWith("sqlite_", StringComparison.OrdinalIgnoreCase))
            return true;

          if (parts.Length > 3)
          {
            if (parts[3].ToString().StartsWith("sqlite_autoindex_", StringComparison.OrdinalIgnoreCase)
              || parts[3].ToString().StartsWith("sqlite_master_PK_", StringComparison.OrdinalIgnoreCase))
              return true;
          }
        }
        return false;
      }
    }

    public override object[] ExecuteCommand(int[] itemIds, OleCommand command, OleCommandExecutionOption executionOption, object arguments)
    {
      return base.ExecuteCommand(itemIds, command, executionOption, arguments);
    }
    /// <summary>
    /// This method executes a specified command, potentially based
    /// on parameters passed in from the data view support XML.
    /// </summary>
    public override object ExecuteCommand(int itemId, OleCommand command, OleCommandExecutionOption executionOption, object arguments)
    {
      object returnValue = null;
      object[] args = arguments as object[];

      if (command.GroupGuid == guidSQLiteCmdSet)
      {
        switch ((cmdid)command.CommandId)
        {
          case cmdid.Vacuum:
            Vacuum();
            break;
          case cmdid.Rekey:
            ChangePassword(itemId);
            break;
          default:
            returnValue = base.ExecuteCommand(itemId, command, executionOption, arguments);
            break;
        }
      }
      else if (command.GroupGuid == VSConstants.GUID_VSStandardCommandSet97)
      {
        switch ((VSConstants.VSStd97CmdID)command.CommandId)
        {
          case VSConstants.VSStd97CmdID.Delete:
            switch ((string)args[0])
            {
              case "Table":
                DropSelectedTables();
                break;
              case "Index":
                DropSelectedIndexes();
                break;
              case "View":
                DropSelectedViews();
                break;
            }
            break;
        }
      }
      else if (command.GroupGuid == guidDataCmdSet)
      {
        switch ((cmdid)command.CommandId)
        {
          case cmdid.CreateTable:
            DesignTable(itemId, null);
            break;
          case cmdid.CreateView:
            DesignView(itemId, null);
            break;
          case cmdid.Alter:
            switch ((string)args[0])
            {
              case "Table":
                {
                  object[] parts;
                  int[] items = DataViewHierarchyAccessor.GetSelectedItems();
                  parts = DataViewHierarchyAccessor.GetObjectIdentifier(items[0]);
                  DesignTable(itemId, parts[2].ToString());
                }
                break;
              case "Index":
                break;
              case "View":
                {
                  object[] parts;
                  int[] items = DataViewHierarchyAccessor.GetSelectedItems();
                  parts = DataViewHierarchyAccessor.GetObjectIdentifier(items[0]);
                  DesignView(itemId, parts[2].ToString());
                }
                break;
            }
            break;
        }
      }
      else
      {
        returnValue = base.ExecuteCommand(itemId, command, executionOption, arguments);
      }
      return returnValue;
    }

    private void DesignTable(int itemId, string tableName)
    {
      Microsoft.VisualStudio.OLE.Interop.IServiceProvider provider = DataViewHierarchyAccessor.ServiceProvider as Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
      IVsUIShell shell = DataViewHierarchyAccessor.ServiceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;
      IVsUIHierarchy hier = DataViewHierarchyAccessor.Hierarchy;
      IVsWindowFrame frame;

      if (shell != null)
      {
        TableDesignerDoc form = new TableDesignerDoc(itemId, DataViewHierarchyAccessor, tableName);
        IntPtr formptr = System.Runtime.InteropServices.Marshal.GetIUnknownForObject(form);
        Guid empty = Guid.Empty;
        FakeHierarchy fake = new FakeHierarchy(form, hier);

        int code = shell.CreateDocumentWindow(
          0, // (uint)(__VSCREATEDOCWIN.CDW_fCreateNewWindow | __VSCREATEDOCWIN.CDW_RDTFLAGS_MASK) | (uint)(_VSRDTFLAGS.RDT_CanBuildFromMemory | _VSRDTFLAGS.RDT_NonCreatable | _VSRDTFLAGS.RDT_VirtualDocument | _VSRDTFLAGS.RDT_DontAddToMRU),
          form.Name, fake, (uint)itemId, formptr, formptr, ref empty, null, ref guidTableDesignContext, provider, "", form.Caption, null, out frame);

        if (frame != null)
        {
          object ret;
          int prop = (int)__VSFPROPID.VSFPROPID_Caption;
          
          code = frame.GetProperty(prop, out ret);

          code = frame.Show();
        }
      }
    }

    private void DesignView(int itemId, string viewName)
    {
      Microsoft.VisualStudio.OLE.Interop.IServiceProvider provider = DataViewHierarchyAccessor.ServiceProvider as Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
      IVsUIShell shell = DataViewHierarchyAccessor.ServiceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell;
      IVsUIHierarchy hier = DataViewHierarchyAccessor.Hierarchy;
      IVsWindowFrame frame;

      if (shell != null)
      {
        ViewDesignerDoc form = new ViewDesignerDoc(itemId, DataViewHierarchyAccessor, viewName);
        IntPtr formptr = System.Runtime.InteropServices.Marshal.GetIUnknownForObject(form);
        Guid empty = Guid.Empty;
        FakeHierarchy fake = new FakeHierarchy(form, hier);

        int code = shell.CreateDocumentWindow(
          0, // (uint)(__VSCREATEDOCWIN.CDW_fCreateNewWindow | __VSCREATEDOCWIN.CDW_RDTFLAGS_MASK) | (uint)(_VSRDTFLAGS.RDT_CanBuildFromMemory | _VSRDTFLAGS.RDT_NonCreatable | _VSRDTFLAGS.RDT_VirtualDocument | _VSRDTFLAGS.RDT_DontAddToMRU),
          form.Name, fake, (uint)itemId, formptr, formptr, ref empty, null, ref guidViewDesignContext, provider, "", form.Caption, null, out frame);

        if (frame != null)
        {
          object ret;
          int prop = (int)__VSFPROPID.VSFPROPID_Caption;

          code = frame.GetProperty(prop, out ret);

          code = frame.Show();
        }
      }
    }

    private void DropSelectedTables()
    {
      int[] items = DataViewHierarchyAccessor.GetSelectedItems();
      int n;
      object[] parts;

      for (n = 0; n < items.Length; n++)
      {
        parts = DataViewHierarchyAccessor.GetObjectIdentifier(items[n]);
        if (parts == null) continue;

        if (System.Windows.Forms.MessageBox.Show(String.Format(CultureInfo.InvariantCulture, "Drop table {0} ({1}), are you sure?", parts[2], parts[0]), "Confirm delete", System.Windows.Forms.MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
        {
          string sql = String.Format(CultureInfo.InvariantCulture, "DROP TABLE [{0}].[{1}]", parts[0], parts[2]);

          DataViewHierarchyAccessor.Connection.Command.ExecuteWithoutResults(sql, (int)System.Data.CommandType.Text, null, 0);
          DataViewHierarchyAccessor.DropObjectNode(items[n]);
        }
        else throw new OperationCanceledException();
      }
    }

    private void DropSelectedViews()
    {
      int[] items = DataViewHierarchyAccessor.GetSelectedItems();
      int n;
      object[] parts;

      for (n = 0; n < items.Length; n++)
      {
        parts = DataViewHierarchyAccessor.GetObjectIdentifier(items[n]);
        if (parts == null) continue;

        if (System.Windows.Forms.MessageBox.Show(String.Format(CultureInfo.InvariantCulture, "Drop view {0} ({1}), are you sure?", parts[2], parts[0]), "Confirm delete", System.Windows.Forms.MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
        {
          string sql = String.Format(CultureInfo.InvariantCulture, "DROP VIEW [{0}].[{1}]", parts[0], parts[2]);

          DataViewHierarchyAccessor.Connection.Command.ExecuteWithoutResults(sql, (int)System.Data.CommandType.Text, null, 0);
          DataViewHierarchyAccessor.DropObjectNode(items[n]);
        }
        else throw new OperationCanceledException();
      }
    }

    private void DropSelectedIndexes()
    {
      int[] items = DataViewHierarchyAccessor.GetSelectedItems();
      int n;
      object[] parts;

      for (n = 0; n < items.Length; n++)
      {
        parts = DataViewHierarchyAccessor.GetObjectIdentifier(items[n]);
        if (parts == null) continue;

        if (System.Windows.Forms.MessageBox.Show(String.Format(CultureInfo.InvariantCulture, "Drop index {0} ({1}), are you sure?", parts[3], parts[0]), "Confirm delete", System.Windows.Forms.MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
        {
          string sql = String.Format(CultureInfo.InvariantCulture, "DROP INDEX [{0}].[{1}]", parts[0], parts[3]);

          DataViewHierarchyAccessor.Connection.Command.ExecuteWithoutResults(sql, (int)System.Data.CommandType.Text, null, 0);
          DataViewHierarchyAccessor.DropObjectNode(items[n]);
        }
        else throw new OperationCanceledException();
      }
    }

    private void Vacuum()
    {
      DataViewHierarchyAccessor.Connection.Command.ExecuteWithoutResults("VACUUM", (int)System.Data.CommandType.Text, null, 0);
    }

    private void ChangePassword(int itemId)
    {
      DataConnection dataConn = DataViewHierarchyAccessor.Connection;
      DbConnection cnn = DataViewHierarchyAccessor.Connection.ConnectionSupport.ProviderObject as DbConnection;
      if (cnn == null) return;

      SQLiteConnectionProperties props = new SQLiteConnectionProperties(cnn.ConnectionString);

      using (ChangePasswordDialog dlg = new ChangePasswordDialog(props))
      {
        if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
          if (String.IsNullOrEmpty(dlg.Password))
            props.Remove("Password");
          else
            props["Password"] = dlg.Password;

          System.Reflection.MethodInfo method = cnn.GetType().GetMethod("ChangePassword", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.InvokeMethod, null, new Type[] { typeof(string) }, null);

          if (method != null)
          {
            method.Invoke(cnn, new object[] { dlg.Password });

            dataConn.Close();
            dataConn.DisplayConnectionString = props.ToDisplayString();
            dataConn.Open();

            Refresh(itemId);
          }
        }
      }
    }

    public void Refresh(int itemId)
    {
      Refresh(DataViewHierarchyAccessor, itemId);
    }

    public static void Refresh(DataViewHierarchyAccessor accessor, int itemId)
    {
      IVsUIHierarchy hier = accessor.Hierarchy as IVsUIHierarchy;
      Guid g = VSConstants.GUID_VSStandardCommandSet97;
      hier.ExecCommand((uint)itemId, ref g, (uint)0xbd, (uint)OleCommandExecutionOption.DoDefault, IntPtr.Zero, IntPtr.Zero);
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/SQLiteConnectionProperties.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using Microsoft.VisualStudio.Data.AdoDotNet;
  using Microsoft.VisualStudio.Data;
  using Microsoft.Win32;

  /// <summary>
  /// Provides rudimentary connectionproperties support
  /// </summary>
  internal sealed class SQLiteConnectionProperties : AdoDotNetConnectionProperties
  {
    public SQLiteConnectionProperties()
      : this(null)
    {
    }

    public SQLiteConnectionProperties(string connectionString)
      : base("System.Data.SQLite", connectionString)
    {
    }

    public override string[] GetBasicProperties()
    {
      return new string[] { "data source" };
    }

    protected override bool ShouldPersistProperty(string propertyName)
    {
      if (String.Compare(propertyName, "Database", StringComparison.OrdinalIgnoreCase) == 0) return false;

      return base.ShouldPersistProperty(propertyName);
    }

    public override bool Contains(string propertyName)
    {
      if (String.Compare(propertyName, "Database", StringComparison.OrdinalIgnoreCase) == 0)
        return (base.Contains("data source") || base.Contains("uri"));

      return base.Contains(propertyName);
    }

    public override object this[string propertyName]
    {
      get
      {
        if (String.Compare(propertyName, "Database", StringComparison.OrdinalIgnoreCase) == 0)
          return System.IO.Path.GetFileNameWithoutExtension(GetDatabaseFile());

        return base[propertyName];
      }
      set
      {
        base[propertyName] = value;
      }
    }

    internal string GetDatabaseFile()
    {
      if (this["data source"] is string && ((string)this["data source"]).Length > 0)
        return (string)this["data source"];
      else if (this["uri"] is string)
        return MapUriPath((string)this["uri"]);
      return String.Empty;
    }

    public override bool  IsComplete
    {
      get 
      {
        if (Contains("data source") == true)
        {
          if (this["data source"] is string && ((string)this["data source"]).Length > 0)
            return true;
        }
        else if (Contains("uri") == true)
        {
          if (this["uri"] is string && MapUriPath((string)this["uri"]).Length > 0)
            return true;
        }

        return false;
      }
    }

    internal static string MapUriPath(string path)
    {
      if (path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
        return path.Substring(7);
      else if (path.StartsWith("file:", StringComparison.OrdinalIgnoreCase))
        return path.Substring(5);
      else if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase))
        return path;
      else
        return String.Empty;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































Deleted SQLite.Designer/SQLiteConnectionStringEditor.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Reflection;
  using System.Data;
  using System.Data.Common;
  using System.ComponentModel.Design;
  using System.ComponentModel;

  /// <summary>
  /// This class provides connectionstring editing support in the properties window when
  /// using a SQLiteConnection as a toolbox component on a form (for example).
  /// 
  /// In order to provide the dropdown list, unless someone knows a better way, I have to use
  /// the internal VsConnectionManager class since it utilizes some interfaces in the designer
  /// that are internal to the VSDesigner object.  We instantiate it and utilize it through reflection.
  /// </summary>
  internal sealed class SQLiteConnectionStringEditor : ObjectSelectorEditor
  {
    private ObjectSelectorEditor.Selector _selector;

    private static Type _managerType;

    static SQLiteConnectionStringEditor()
    {
      Assembly assm = SQLiteDataAdapterToolboxItem._vsdesigner;
      if (assm != null)
      {
        _managerType = assm.GetType("Microsoft.VSDesigner.Data.VS.VsConnectionManager");
      }
    }

    public SQLiteConnectionStringEditor()
    {
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
      if (provider == null || context == null) return value;
      if (context.Instance == null) return value;

      try
      {
        context.OnComponentChanging();
        object newConnection = base.EditValue(context, provider, value);
        string connectionString = newConnection as string;
        int index = -1;

        if (connectionString == null && newConnection != null)
        {
          if (_managerType != null)
          {
            object manager = Activator.CreateInstance(_managerType, new object[] { provider });
            if (manager != null)
            {
              index = (int)_managerType.InvokeMember("AddNewConnection", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, manager, new object[] { "System.Data.SQLite" });
              if (index > -1 && _selector != null)
              {
                connectionString = (string)_managerType.InvokeMember("GetConnectionString", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, manager, new object[] { index });
                _selector.SelectedNode = _selector.AddNode((string)_managerType.InvokeMember("GetConnectionName", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, manager, new object[] { index }), connectionString, null);
              }
            }
          }
        }

        if (String.IsNullOrEmpty(connectionString) == false)
        {
          value = connectionString;
        }
        context.OnComponentChanged();
      }
      catch
      {
      }
      return value;
    }

    protected override void FillTreeWithData(Selector selector, ITypeDescriptorContext context, IServiceProvider provider)
    {
      object manager = Activator.CreateInstance(_managerType, new object[] { provider });
      DbConnection connection = (DbConnection)context.Instance;
      ObjectSelectorEditor.SelectorNode node;

      _selector = selector;

      _selector.Clear();

      if (manager != null)
      {
        int items = (int)_managerType.InvokeMember("GetConnectionCount", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, manager, null);
        string dataProvider;
        string connectionString;
        string connectionName;

        for (int n = 0; n < items; n++)
        {
          connectionString = (string)_managerType.InvokeMember("GetConnectionString", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, manager, new object[] { n });
          connectionName = (string)_managerType.InvokeMember("GetConnectionName", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, manager, new object[] { n });
          dataProvider = (string)_managerType.InvokeMember("GetProvider", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, manager, new object[] { n });
          if (String.Compare(dataProvider, "System.Data.SQLite", StringComparison.OrdinalIgnoreCase) == 0)
          {
            node = selector.AddNode(connectionName, connectionString, null);
            
            if (String.Compare(connectionString, connection.ConnectionString, StringComparison.OrdinalIgnoreCase) == 0)
              selector.SelectedNode = node;
          }
        }
        selector.AddNode("<New Connection...>", this, null);
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































Deleted SQLite.Designer/SQLiteConnectionUIControl.Designer.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  partial class SQLiteConnectionUIControl
  {
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      System.Windows.Forms.Label labelPassword;
      System.Windows.Forms.GroupBox securityGroup;
      System.Windows.Forms.GroupBox encodingGroup;
      System.Windows.Forms.GroupBox dateTimeGroup;
      System.Windows.Forms.GroupBox databaseGroup;
      System.Windows.Forms.Label cacheSizeLabel;
      System.Windows.Forms.Label pageSizeLabel;
      System.Windows.Forms.GroupBox syncGroup;
      this.passwordTextBox = new System.Windows.Forms.TextBox();
      this.utf16RadioButton = new System.Windows.Forms.RadioButton();
      this.utf8RadioButton = new System.Windows.Forms.RadioButton();
      this.ticksRadioButton = new System.Windows.Forms.RadioButton();
      this.iso8601RadioButton = new System.Windows.Forms.RadioButton();
      this.cacheSizeTextbox = new System.Windows.Forms.TextBox();
      this.pageSizeTextBox = new System.Windows.Forms.TextBox();
      this.fileTextBox = new System.Windows.Forms.TextBox();
      this.browseButton = new System.Windows.Forms.Button();
      this.newDatabase = new System.Windows.Forms.Button();
      this.offRadioButton = new System.Windows.Forms.RadioButton();
      this.normalRadioButton = new System.Windows.Forms.RadioButton();
      this.fullRadioButton = new System.Windows.Forms.RadioButton();
      this.julianRadioButton = new System.Windows.Forms.RadioButton();
      labelPassword = new System.Windows.Forms.Label();
      securityGroup = new System.Windows.Forms.GroupBox();
      encodingGroup = new System.Windows.Forms.GroupBox();
      dateTimeGroup = new System.Windows.Forms.GroupBox();
      databaseGroup = new System.Windows.Forms.GroupBox();
      cacheSizeLabel = new System.Windows.Forms.Label();
      pageSizeLabel = new System.Windows.Forms.Label();
      syncGroup = new System.Windows.Forms.GroupBox();
      securityGroup.SuspendLayout();
      encodingGroup.SuspendLayout();
      dateTimeGroup.SuspendLayout();
      databaseGroup.SuspendLayout();
      syncGroup.SuspendLayout();
      this.SuspendLayout();
      // 
      // labelPassword
      // 
      labelPassword.AutoSize = true;
      labelPassword.Location = new System.Drawing.Point(6, 23);
      labelPassword.Name = "labelPassword";
      labelPassword.Size = new System.Drawing.Size(53, 13);
      labelPassword.TabIndex = 0;
      labelPassword.Text = "Password";
      // 
      // securityGroup
      // 
      securityGroup.Controls.Add(this.passwordTextBox);
      securityGroup.Controls.Add(labelPassword);
      securityGroup.Location = new System.Drawing.Point(3, 263);
      securityGroup.Name = "securityGroup";
      securityGroup.Size = new System.Drawing.Size(306, 56);
      securityGroup.TabIndex = 10;
      securityGroup.TabStop = false;
      securityGroup.Text = "Encryption";
      // 
      // passwordTextBox
      // 
      this.passwordTextBox.Location = new System.Drawing.Point(65, 20);
      this.passwordTextBox.Name = "passwordTextBox";
      this.passwordTextBox.Size = new System.Drawing.Size(235, 21);
      this.passwordTextBox.TabIndex = 1;
      this.passwordTextBox.UseSystemPasswordChar = true;
      this.passwordTextBox.Leave += new System.EventHandler(this.passwordTextBox_Leave);
      // 
      // encodingGroup
      // 
      encodingGroup.Controls.Add(this.utf16RadioButton);
      encodingGroup.Controls.Add(this.utf8RadioButton);
      encodingGroup.Location = new System.Drawing.Point(3, 159);
      encodingGroup.Name = "encodingGroup";
      encodingGroup.Size = new System.Drawing.Size(75, 98);
      encodingGroup.TabIndex = 7;
      encodingGroup.TabStop = false;
      encodingGroup.Text = "Encoding";
      // 
      // utf16RadioButton
      // 
      this.utf16RadioButton.AutoSize = true;
      this.utf16RadioButton.Location = new System.Drawing.Point(6, 44);
      this.utf16RadioButton.Name = "utf16RadioButton";
      this.utf16RadioButton.Size = new System.Drawing.Size(60, 17);
      this.utf16RadioButton.TabIndex = 1;
      this.utf16RadioButton.TabStop = true;
      this.utf16RadioButton.Text = "UTF-16";
      this.utf16RadioButton.UseVisualStyleBackColor = true;
      this.utf16RadioButton.CheckedChanged += new System.EventHandler(this.encoding_Changed);
      // 
      // utf8RadioButton
      // 
      this.utf8RadioButton.AutoSize = true;
      this.utf8RadioButton.Checked = true;
      this.utf8RadioButton.Location = new System.Drawing.Point(7, 21);
      this.utf8RadioButton.Name = "utf8RadioButton";
      this.utf8RadioButton.Size = new System.Drawing.Size(54, 17);
      this.utf8RadioButton.TabIndex = 0;
      this.utf8RadioButton.TabStop = true;
      this.utf8RadioButton.Text = "UTF-8";
      this.utf8RadioButton.UseVisualStyleBackColor = true;
      this.utf8RadioButton.CheckedChanged += new System.EventHandler(this.encoding_Changed);
      // 
      // dateTimeGroup
      // 
      dateTimeGroup.Controls.Add(this.julianRadioButton);
      dateTimeGroup.Controls.Add(this.ticksRadioButton);
      dateTimeGroup.Controls.Add(this.iso8601RadioButton);
      dateTimeGroup.Location = new System.Drawing.Point(84, 159);
      dateTimeGroup.Name = "dateTimeGroup";
      dateTimeGroup.Size = new System.Drawing.Size(113, 98);
      dateTimeGroup.TabIndex = 8;
      dateTimeGroup.TabStop = false;
      dateTimeGroup.Text = "Date/Time Format";
      // 
      // ticksRadioButton
      // 
      this.ticksRadioButton.AutoSize = true;
      this.ticksRadioButton.Location = new System.Drawing.Point(7, 66);
      this.ticksRadioButton.Name = "ticksRadioButton";
      this.ticksRadioButton.Size = new System.Drawing.Size(48, 17);
      this.ticksRadioButton.TabIndex = 1;
      this.ticksRadioButton.TabStop = true;
      this.ticksRadioButton.Text = "Ticks";
      this.ticksRadioButton.UseVisualStyleBackColor = true;
      this.ticksRadioButton.CheckedChanged += new System.EventHandler(this.datetime_Changed);
      // 
      // iso8601RadioButton
      // 
      this.iso8601RadioButton.AutoSize = true;
      this.iso8601RadioButton.Checked = true;
      this.iso8601RadioButton.Location = new System.Drawing.Point(7, 21);
      this.iso8601RadioButton.Name = "iso8601RadioButton";
      this.iso8601RadioButton.Size = new System.Drawing.Size(71, 17);
      this.iso8601RadioButton.TabIndex = 0;
      this.iso8601RadioButton.TabStop = true;
      this.iso8601RadioButton.Text = "ISO-8601";
      this.iso8601RadioButton.UseVisualStyleBackColor = true;
      this.iso8601RadioButton.CheckedChanged += new System.EventHandler(this.datetime_Changed);
      // 
      // databaseGroup
      // 
      databaseGroup.Controls.Add(cacheSizeLabel);
      databaseGroup.Controls.Add(this.cacheSizeTextbox);
      databaseGroup.Controls.Add(pageSizeLabel);
      databaseGroup.Controls.Add(this.pageSizeTextBox);
      databaseGroup.Controls.Add(this.fileTextBox);
      databaseGroup.Controls.Add(this.browseButton);
      databaseGroup.Controls.Add(this.newDatabase);
      databaseGroup.Location = new System.Drawing.Point(3, 3);
      databaseGroup.Name = "databaseGroup";
      databaseGroup.Size = new System.Drawing.Size(306, 150);
      databaseGroup.TabIndex = 8;
      databaseGroup.TabStop = false;
      databaseGroup.Text = "Database";
      // 
      // cacheSizeLabel
      // 
      cacheSizeLabel.AutoSize = true;
      cacheSizeLabel.Location = new System.Drawing.Point(7, 116);
      cacheSizeLabel.Name = "cacheSizeLabel";
      cacheSizeLabel.Size = new System.Drawing.Size(59, 13);
      cacheSizeLabel.TabIndex = 5;
      cacheSizeLabel.Text = "Cache Size";
      // 
      // cacheSizeTextbox
      // 
      this.cacheSizeTextbox.Location = new System.Drawing.Point(72, 113);
      this.cacheSizeTextbox.Name = "cacheSizeTextbox";
      this.cacheSizeTextbox.Size = new System.Drawing.Size(100, 21);
      this.cacheSizeTextbox.TabIndex = 6;
      this.cacheSizeTextbox.Text = "2000";
      this.cacheSizeTextbox.Leave += new System.EventHandler(this.cacheSizeTextbox_Leave);
      // 
      // pageSizeLabel
      // 
      pageSizeLabel.AutoSize = true;
      pageSizeLabel.Location = new System.Drawing.Point(13, 89);
      pageSizeLabel.Name = "pageSizeLabel";
      pageSizeLabel.Size = new System.Drawing.Size(53, 13);
      pageSizeLabel.TabIndex = 3;
      pageSizeLabel.Text = "Page Size";
      // 
      // pageSizeTextBox
      // 
      this.pageSizeTextBox.Location = new System.Drawing.Point(72, 86);
      this.pageSizeTextBox.Name = "pageSizeTextBox";
      this.pageSizeTextBox.Size = new System.Drawing.Size(100, 21);
      this.pageSizeTextBox.TabIndex = 4;
      this.pageSizeTextBox.Text = "1024";
      this.pageSizeTextBox.Leave += new System.EventHandler(this.pageSizeTextBox_Leave);
      // 
      // fileTextBox
      // 
      this.fileTextBox.Location = new System.Drawing.Point(6, 20);
      this.fileTextBox.Name = "fileTextBox";
      this.fileTextBox.Size = new System.Drawing.Size(294, 21);
      this.fileTextBox.TabIndex = 0;
      this.fileTextBox.Leave += new System.EventHandler(this.fileTextBox_Leave);
      // 
      // browseButton
      // 
      this.browseButton.Location = new System.Drawing.Point(6, 47);
      this.browseButton.Name = "browseButton";
      this.browseButton.Size = new System.Drawing.Size(75, 23);
      this.browseButton.TabIndex = 1;
      this.browseButton.Text = "&Browse ...";
      this.browseButton.UseVisualStyleBackColor = true;
      this.browseButton.Click += new System.EventHandler(this.browseButton_Click);
      // 
      // newDatabase
      // 
      this.newDatabase.Location = new System.Drawing.Point(87, 47);
      this.newDatabase.Name = "newDatabase";
      this.newDatabase.Size = new System.Drawing.Size(75, 23);
      this.newDatabase.TabIndex = 2;
      this.newDatabase.Text = "&New ...";
      this.newDatabase.UseVisualStyleBackColor = true;
      this.newDatabase.Click += new System.EventHandler(this.newDatabase_Click);
      // 
      // syncGroup
      // 
      syncGroup.Controls.Add(this.offRadioButton);
      syncGroup.Controls.Add(this.normalRadioButton);
      syncGroup.Controls.Add(this.fullRadioButton);
      syncGroup.Location = new System.Drawing.Point(204, 159);
      syncGroup.Name = "syncGroup";
      syncGroup.Size = new System.Drawing.Size(105, 98);
      syncGroup.TabIndex = 9;
      syncGroup.TabStop = false;
      syncGroup.Text = "Synchronization";
      // 
      // offRadioButton
      // 
      this.offRadioButton.AutoSize = true;
      this.offRadioButton.Location = new System.Drawing.Point(6, 66);
      this.offRadioButton.Name = "offRadioButton";
      this.offRadioButton.Size = new System.Drawing.Size(41, 17);
      this.offRadioButton.TabIndex = 2;
      this.offRadioButton.Text = "Off";
      this.offRadioButton.UseVisualStyleBackColor = true;
      this.offRadioButton.CheckedChanged += new System.EventHandler(this.sync_Changed);
      // 
      // normalRadioButton
      // 
      this.normalRadioButton.AutoSize = true;
      this.normalRadioButton.Checked = true;
      this.normalRadioButton.Location = new System.Drawing.Point(6, 43);
      this.normalRadioButton.Name = "normalRadioButton";
      this.normalRadioButton.Size = new System.Drawing.Size(58, 17);
      this.normalRadioButton.TabIndex = 1;
      this.normalRadioButton.TabStop = true;
      this.normalRadioButton.Text = "Normal";
      this.normalRadioButton.UseVisualStyleBackColor = true;
      this.normalRadioButton.CheckedChanged += new System.EventHandler(this.sync_Changed);
      // 
      // fullRadioButton
      // 
      this.fullRadioButton.AutoSize = true;
      this.fullRadioButton.Location = new System.Drawing.Point(6, 20);
      this.fullRadioButton.Name = "fullRadioButton";
      this.fullRadioButton.Size = new System.Drawing.Size(41, 17);
      this.fullRadioButton.TabIndex = 0;
      this.fullRadioButton.Text = "Full";
      this.fullRadioButton.UseVisualStyleBackColor = true;
      this.fullRadioButton.CheckedChanged += new System.EventHandler(this.sync_Changed);
      // 
      // julianRadioButton
      // 
      this.julianRadioButton.AutoSize = true;
      this.julianRadioButton.Location = new System.Drawing.Point(7, 44);
      this.julianRadioButton.Name = "julianRadioButton";
      this.julianRadioButton.Size = new System.Drawing.Size(74, 17);
      this.julianRadioButton.TabIndex = 2;
      this.julianRadioButton.TabStop = true;
      this.julianRadioButton.Text = "Julian Day";
      this.julianRadioButton.UseVisualStyleBackColor = true;
      this.julianRadioButton.CheckedChanged += new System.EventHandler(this.datetime_Changed);
      // 
      // SQLiteConnectionUIControl
      // 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
      this.Controls.Add(syncGroup);
      this.Controls.Add(databaseGroup);
      this.Controls.Add(dateTimeGroup);
      this.Controls.Add(encodingGroup);
      this.Controls.Add(securityGroup);
      this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
      this.Name = "SQLiteConnectionUIControl";
      this.Size = new System.Drawing.Size(312, 322);
      securityGroup.ResumeLayout(false);
      securityGroup.PerformLayout();
      encodingGroup.ResumeLayout(false);
      encodingGroup.PerformLayout();
      dateTimeGroup.ResumeLayout(false);
      dateTimeGroup.PerformLayout();
      databaseGroup.ResumeLayout(false);
      databaseGroup.PerformLayout();
      syncGroup.ResumeLayout(false);
      syncGroup.PerformLayout();
      this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.TextBox fileTextBox;
    private System.Windows.Forms.Button browseButton;
    private System.Windows.Forms.Button newDatabase;
    private System.Windows.Forms.TextBox passwordTextBox;
    private System.Windows.Forms.RadioButton utf16RadioButton;
    private System.Windows.Forms.RadioButton utf8RadioButton;
    private System.Windows.Forms.RadioButton ticksRadioButton;
    private System.Windows.Forms.RadioButton iso8601RadioButton;
    private System.Windows.Forms.TextBox pageSizeTextBox;
    private System.Windows.Forms.TextBox cacheSizeTextbox;
    private System.Windows.Forms.RadioButton offRadioButton;
    private System.Windows.Forms.RadioButton normalRadioButton;
    private System.Windows.Forms.RadioButton fullRadioButton;
    private System.Windows.Forms.RadioButton julianRadioButton;
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/SQLiteConnectionUIControl.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Text;
  using System.Windows.Forms;
  using System.Globalization;
  using Microsoft.VisualStudio.Data;
  using Microsoft.Win32;

  /// <summary>
  /// Provides a UI to edit/create SQLite database connections
  /// </summary>
  [ToolboxItem(false)]
  public partial class SQLiteConnectionUIControl : DataConnectionUIControl
  {
    public SQLiteConnectionUIControl()
    {
      InitializeComponent();
    }

    private void browseButton_Click(object sender, EventArgs e)
    {
      OpenFileDialog dlg = new OpenFileDialog();
      dlg.FileName = fileTextBox.Text;
      dlg.Title = "Select SQLite Database File";

      if (dlg.ShowDialog(this) == DialogResult.OK)
      {
        fileTextBox.Text = dlg.FileName;
        fileTextBox_Leave(sender, e);
      }
    }

    private void newDatabase_Click(object sender, EventArgs e)
    {
      SaveFileDialog dlg = new SaveFileDialog();
      dlg.Title = "Create SQLite Database File";
      if (dlg.ShowDialog() == DialogResult.OK)
      {
        fileTextBox.Text = dlg.FileName;
        fileTextBox_Leave(sender, e);
      }
    }

    #region IDataConnectionUIControl Members

    public override void LoadProperties()
    {
      if (ConnectionProperties.Contains("data source"))
        fileTextBox.Text = ConnectionProperties["data source"] as string;
      else
        fileTextBox.Text = String.Empty;

      if (ConnectionProperties.Contains("password"))
        passwordTextBox.Text = ConnectionProperties["password"] as string;
      else
        passwordTextBox.Text = String.Empty;
    }

    #endregion

    private void passwordTextBox_Leave(object sender, EventArgs e)
    {
      if (String.IsNullOrEmpty(passwordTextBox.Text))
        ConnectionProperties.Remove("password");
      else
        ConnectionProperties["password"] = passwordTextBox.Text;
    }

    private void encoding_Changed(object sender, EventArgs e)
    {
      if (utf8RadioButton.Checked == true)
        ConnectionProperties.Remove("useutf16encoding");
      else
        ConnectionProperties["useutf16encoding"] = utf16RadioButton.Checked;
    }

    private void datetime_Changed(object sender, EventArgs e)
    {
      if (iso8601RadioButton.Checked == true)
        ConnectionProperties.Remove("datetimeformat");
      else if (ticksRadioButton.Checked == true)
        ConnectionProperties["datetimeformat"] = "Ticks";
      else
        ConnectionProperties["datetimeformat"] = "JulianDay";
    }

    private void sync_Changed(object sender, EventArgs e)
    {
      string sync = "Normal";
      if (fullRadioButton.Checked == true) sync = "Full";
      else if (offRadioButton.Checked == true) sync = "Off";

      if (sync == "Normal")
        ConnectionProperties.Remove("synchronous");
      else
        ConnectionProperties["synchronous"] = sync;
    }

    private void pageSizeTextBox_Leave(object sender, EventArgs e)
    {
      int n = Convert.ToInt32(pageSizeTextBox.Text, CultureInfo.CurrentCulture);
      ConnectionProperties["page size"] = n;
    }

    private void cacheSizeTextbox_Leave(object sender, EventArgs e)
    {
      int n = Convert.ToInt32(cacheSizeTextbox.Text, CultureInfo.CurrentCulture);
      ConnectionProperties["cache size"] = n;
    }

    private void fileTextBox_Leave(object sender, EventArgs e)
    {
      ConnectionProperties["data source"] = fileTextBox.Text;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































Deleted SQLite.Designer/SQLiteConnectionUIControl.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="labelPassword.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="securityGroup.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="encodingGroup.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="dateTimeGroup.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="databaseGroup.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="cacheSizeLabel.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="pageSizeLabel.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="syncGroup.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































Deleted SQLite.Designer/SQLiteDataAdapterToolboxItem.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.ComponentModel;
  using System.ComponentModel.Design;
  using System.Drawing.Design;
  using System.Data.Common;
  using System.Reflection;
  using System.Collections.Generic;
  using System.Windows.Forms;
  using System.Drawing;
  using System.Runtime.Serialization;
  using System.Globalization;

  /// <summary>
  /// Provides a toolboxitem for a SQLiteDataAdapter.  This is required in order for us to 
  /// pop up the connection wizard when you drop the tool on a form, and to create the hidden commands
  /// that are assigned to the data adapter and keep them hidden.  The hiding at runtime of the controls
  /// is accomplished both here during the creation of the components and in the SQLiteCommandDesigner
  /// which provides properties to hide the objects when they're supposed to be hidden.
  /// 
  /// The connection wizard is instantiated in the VSDesigner through reflection.
  /// </summary>
  [Serializable]
  [ToolboxItem(typeof(SQLiteDataAdapterToolboxItem))]
  internal sealed class SQLiteDataAdapterToolboxItem : ToolboxItem
  {
    private static Type _wizard;
    
    internal static Assembly _vsdesigner;

    static SQLiteDataAdapterToolboxItem()
    {
      _vsdesigner = Assembly.Load("Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
      _wizard = _vsdesigner.GetType("Microsoft.VSDesigner.Data.VS.DataAdapterWizard");
    }

    public SQLiteDataAdapterToolboxItem(Type type) : this(type, (Bitmap)null)
    {
    }

    public SQLiteDataAdapterToolboxItem(Type type, Bitmap bmp) : base(type)
    {
      DisplayName = "SQLiteDataAdapter";
    }

    private SQLiteDataAdapterToolboxItem(SerializationInfo info, StreamingContext context)
    {
      Deserialize(info, context);
    }

    /// <summary>
    /// Creates the necessary components associated with this data adapter instance
    /// </summary>
    /// <param name="host">The designer host</param>
    /// <returns>The components created by this toolbox item</returns>
    protected override IComponent[] CreateComponentsCore(IDesignerHost host)
    {
      DbProviderFactory fact = DbProviderFactories.GetFactory("System.Data.SQLite");

      DbDataAdapter dataAdapter = fact.CreateDataAdapter();
      IContainer container = host.Container;
      
      using (DbCommand adapterCommand = fact.CreateCommand())
      {
        ICloneable adapter = (ICloneable)adapterCommand;

        adapterCommand.DesignTimeVisible = false;
        dataAdapter.SelectCommand = (DbCommand)adapter.Clone();
        container.Add(dataAdapter.SelectCommand, GenerateName(container, "SelectCommand"));

        dataAdapter.InsertCommand = (DbCommand)adapter.Clone();
        container.Add(dataAdapter.InsertCommand, GenerateName(container, "InsertCommand"));

        dataAdapter.UpdateCommand = (DbCommand)adapter.Clone();
        container.Add(dataAdapter.UpdateCommand, GenerateName(container, "UpdateCommand"));

        dataAdapter.DeleteCommand = (DbCommand)adapter.Clone();
        container.Add(dataAdapter.DeleteCommand, GenerateName(container, "DeleteCommand"));
      }

      ITypeResolutionService typeResService = (ITypeResolutionService)host.GetService(typeof(ITypeResolutionService));
      if (typeResService != null)
      {
        typeResService.ReferenceAssembly(dataAdapter.GetType().Assembly.GetName());
      }

      container.Add(dataAdapter);

      List<IComponent> list = new List<IComponent>();
      list.Add(dataAdapter);

      // Show the connection wizard if we have a type for it
      if (_wizard != null)
      {
        using (Form wizard = (Form)Activator.CreateInstance(_wizard, new object[] { host, dataAdapter }))
        {
          wizard.ShowDialog();
        }
      }

      if (dataAdapter.SelectCommand != null) list.Add(dataAdapter.SelectCommand);
      if (dataAdapter.InsertCommand != null) list.Add(dataAdapter.InsertCommand);
      if (dataAdapter.DeleteCommand != null) list.Add(dataAdapter.DeleteCommand);
      if (dataAdapter.UpdateCommand != null) list.Add(dataAdapter.UpdateCommand);

      return list.ToArray();      
    }

    /// <summary>
    /// Generates a unique name for the given object
    /// </summary>
    /// <param name="container">The container where we're being instantiated</param>
    /// <param name="baseName">The core name of the object to create a unique instance of</param>
    /// <returns>A unique name within the given container</returns>
    private static string GenerateName(IContainer container, string baseName)
    {
      ComponentCollection coll = container.Components;
      string uniqueName;
      int n = 1;
      do
      {
        uniqueName = String.Format(CultureInfo.InvariantCulture, "sqlite{0}{1}", baseName, n++);
      } while (coll[uniqueName] != null);

      return uniqueName;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































Deleted SQLite.Designer/SQLiteDataConnectionSupport.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using Microsoft.VisualStudio.Data;
  using Microsoft.VisualStudio.OLE.Interop;
  using Microsoft.VisualStudio.Data.AdoDotNet;
  using Microsoft.Win32;

  /// <summary>
  /// This class creates many of the DDEX components when asked for by the server explorer.
  /// </summary>
  internal sealed class SQLiteDataConnectionSupport : AdoDotNetConnectionSupport
  {
    private SQLiteDataViewSupport _dataViewSupport;
    private SQLiteDataObjectSupport _dataObjectSupport;
    private SQLiteDataObjectIdentifierResolver _dataObjectIdentifierResolver;

    public SQLiteDataConnectionSupport()
      : base("System.Data.SQLite")
    {
    }

    protected override DataSourceInformation CreateDataSourceInformation()
    {
      return new SQLiteDataSourceInformation(Site as DataConnection);
    }

    protected override object GetServiceImpl(Type serviceType)
    {
      if (serviceType == typeof(DataViewSupport))
      {
        if (_dataViewSupport == null) _dataViewSupport = new SQLiteDataViewSupport();
        return _dataViewSupport;
      }

      if (serviceType == typeof(DataObjectSupport))
      {
        if (_dataObjectSupport == null) _dataObjectSupport = new SQLiteDataObjectSupport();
        return _dataObjectSupport;
      }

      if (serviceType == typeof(DataObjectIdentifierResolver))
      {
        if (_dataObjectIdentifierResolver == null) _dataObjectIdentifierResolver = new SQLiteDataObjectIdentifierResolver(Site);
        return _dataObjectIdentifierResolver;
      }

      if (serviceType == typeof(DataConnectionSupport))
        return this;

      return base.GetServiceImpl(serviceType);
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































Deleted SQLite.Designer/SQLiteDataObjectIdentifierResolver.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using Microsoft.VisualStudio.Data;
  using Microsoft.VisualStudio.OLE.Interop;

  /// <summary>
  /// This class is used to build identifier arrays and contract them.  Typically they are 
  /// passed to SQLiteConnection.GetSchema() or are contracted for display on the screen or in the
  /// properties window.
  /// </summary>
  internal sealed class SQLiteDataObjectIdentifierResolver : DataObjectIdentifierResolver, IObjectWithSite
  {
    private DataConnection _connection;

    public SQLiteDataObjectIdentifierResolver()
    {
    }

    internal SQLiteDataObjectIdentifierResolver(object site)
    {
      _connection = site as DataConnection;
    }

    protected override object[] QuickExpandIdentifier(string typeName, object[] partialIdentifier)
    {
      if (typeName == null)
      {
        throw new ArgumentNullException("typeName");
      }

      // Create an identifier array of the correct full length based on
      // the object type
      object[] identifier = null;
      int length = 0;

      switch (typeName.ToLowerInvariant())
      {
        case "":
          length = 0;
          break;
        case "table":
        case "view":
          length = 3;
          break;
        case "column":
        case "index":
        case "foreignkey":
        case "viewcolumn":
        case "triggers":
          length = 4;
          break;
        case "indexcolumn":
        case "foreignkeycolumn":
          length = 5;
          break;
        default:
          throw new NotSupportedException();
      }
      identifier = new object[length];

      // If the input identifier is not null, copy it to the full
      // identifier array.  If the input identifier's length is less
      // than the full length we assume the more specific parts are
      // specified and thus copy into the rightmost portion of the
      // full identifier array.
      if (partialIdentifier != null)
      {
        if (partialIdentifier.Length > length)
        {
          throw new InvalidOperationException();
        }
        partialIdentifier.CopyTo(identifier, length - partialIdentifier.Length);
      }

      if (length > 0)
      {
        // Fill in the current database if not specified
        if (!(identifier[0] is string))
        {
          identifier[0] = _connection.SourceInformation[DataSourceInformation.DefaultCatalog] as string;
        }
      }

      if (length > 1)
      {
        identifier[1] = null;
      }

      return identifier;
    }

    /// <summary>
    /// Strips out the schema, which we don't really support but has to be there for certain operations internal
    /// to MS's designer implementation.
    /// </summary>
    /// <param name="typeName">The type of identifier to contract</param>
    /// <param name="fullIdentifier">The full identifier array</param>
    /// <returns>A contracted identifier array</returns>
    protected override object[] QuickContractIdentifier(string typeName, object[] fullIdentifier)
    {
      if (fullIdentifier.Length < 2) return fullIdentifier;

      object[] identifier = new object[fullIdentifier.Length - 1];

      for (int n = 1; n < fullIdentifier.Length; n++)
      {
        identifier[n - 1] = fullIdentifier[n];
      }

      identifier[0] = fullIdentifier[0];

      return identifier;
    }

    /// <summary>
    /// GetSite does not need to be implemented since
    /// DDEX only calls SetSite to site the object.
    /// </summary>
    void IObjectWithSite.GetSite(ref Guid riid, out IntPtr ppvSite)
    {
      ppvSite = IntPtr.Zero;
      throw new NotImplementedException();
    }

    void IObjectWithSite.SetSite(object pUnkSite)
    {
      _connection = (DataConnection)pUnkSite;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































Deleted SQLite.Designer/SQLiteDataObjectSupport.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using Microsoft.VisualStudio.Data;
  using Microsoft.VisualStudio.OLE.Interop;
  using Microsoft.VisualStudio.Data.AdoDotNet;

  /// <summary>
  /// Doesn't do much other than provide the DataObjectSupport base object with a location
  /// where the XML resource can be found.
  /// </summary>
  internal sealed class SQLiteDataObjectSupport : DataObjectSupport
  {
    public SQLiteDataObjectSupport()
      : base("SQLite.Designer.SQLiteDataObjectSupport", typeof(SQLiteDataObjectSupport).Assembly)
    {
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































Deleted SQLite.Designer/SQLiteDataObjectSupport.xml.
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
<?xml version="1.0" encoding="utf-8"?> 

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<VSDataObjectSupport xmlns="http://tempuri.org/VSDataObjectSupport.xsd">
	<Types>
		<RootType>
			<Properties>
        <Property name="Server" type="System.String" itemName="DataSource"/>
        <Property name="Database" type="System.String" itemName="Database"/>
      </Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetRootObjectEnumerator"/>
			</Actions>
		</RootType>

		<Type name="Table" defaultSort="Database,Name">
			<Concepts>
				<Concept name="Table" restrictions="{Catalog},null,{Name}"/>
			</Concepts>
			<Identifier>
				<Part name="Database" itemName="table_catalog">
					<Concepts>
						<Concept name="Identifier0"/>
					</Concepts>
				</Part>
				<Part name="Schema" itemName="table_schema">
					<Concepts>
						<Concept name="Identifier1"/>
					</Concepts>
				</Part>
				<Part name="Name" itemName="table_name">
					<Concepts>
						<Concept name="Identifier2"/>
					</Concepts>
				</Part>
			</Identifier>
			<Properties>
				<Property name="Name" type="System.String" itemName="table_name"/>
				<Property name="Schema" type="System.String" itemName="table_schema"/>
        <Property name="Type" type="System.String" itemName="table_type">
          <Concepts>
            <Concept name="Type">
              <Conversion>
                <Calculate expr="IIF({0}='TABLE','USER','SYSTEM')" type="System.String"/>
              </Conversion>
            </Concept>
          </Concepts>
        </Property>
      </Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
					<Parameter value="Tables"/>
				</Action>
				<Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
					<Parameter>
						<Parameter value="{2}"/>
						<Parameter value="{1}"/>
						<Parameter value="Table"/>
						<Parameter/>
						<Parameter>
							<!-- GUID_DSRefProperty_PreciseType -->
							<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
								<Parameter value="101" type="System.Int32"/> <!-- Table -->
							</Parameter>
						</Parameter>
					</Parameter>
				</Action>
			</Actions>
		</Type>

		<Type name="TableColumn" defaultSort="Database,Table,Ordinal">
			<Concepts>
				<Concept name="TableColumn" restrictions="{Catalog},null,{Table},{Name}"/>
			</Concepts>
			<Identifier>
				<Part name="Database" itemName="table_catalog">
					<Concepts>
						<Concept name="Identifier0"/>
					</Concepts>
				</Part>
				<Part name="Schema" itemName="table_schema">
					<Concepts>
						<Concept name="Identifier1"/>
					</Concepts>
				</Part>
				<Part name="Table" itemName="table_name">
					<Concepts>
						<Concept name="Identifier2"/>
					</Concepts>
				</Part>
				<Part name="Name" itemName="column_name">
					<Concepts>
						<Concept name="Identifier3"/>
					</Concepts>
				</Part>
			</Identifier>
			<Properties>
				<Property name="Name" type="System.String" itemName="column_name"/>
				<Property name="Ordinal" type="System.Int32" itemName="ordinal_position">
					<Concepts>
						<Concept name="Ordinal">
						</Concept>
					</Concepts>
				</Property>
        <Property name="DataType" type="System.String" itemName="data_type" />
        <Property name="SystemType" type="System.String" itemName="data_type">
          <Concepts>
            <Concept name="UserDataType"/>
            <Concept name="NativeDataType"/>
            <Concept name="ProviderDataType">
              <Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
            </Concept>
            <Concept name="ProviderDbType">
              <Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
            </Concept>
            <Concept name="FrameworkDataType">
              <Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
            </Concept>
          </Concepts>
        </Property>
        <Property name="Length" type="System.Int32" itemName='character_maximum_length'>
					<Concepts>
						<Concept name="Length"/>
					</Concepts>
				</Property>
				<Property name="Precision" type="System.Int32" itemName="numeric_precision">
					<Concepts>
						<Concept name="Precision">
						</Concept>
					</Concepts>
				</Property>
				<Property name="Scale" type="System.Int32" itemName="numeric_scale">
					<Concepts>
						<Concept name="Scale"/>
					</Concepts>
				</Property>
				<Property name="Nullable" type="System.Boolean" itemName="is_nullable">
					<Concepts>
						<Concept name="Nullable">
						</Concept>
					</Concepts>
				</Property>
				<Property name="Default" type="System.String" itemName="column_default">
					<Concepts>
						<Concept name="Default"/>
					</Concepts>
				</Property>
        <Property name="InPrimaryKey" type="System.Boolean" itemName="primary_key"/>
      </Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
					<Parameter value="Columns"/>
				</Action>
				<Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
					<Parameter>
						<Parameter value="{2}"/>
						<Parameter value="{1}"/>
						<Parameter value="Table"/>
						<Parameter/>
						<Parameter>
							<!-- GUID_DSRefProperty_PreciseType -->
							<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
								<Parameter value="101" type="System.Int32"/> <!-- Table -->
							</Parameter>
						</Parameter>
						<Parameter>
							<Parameter>
								<Parameter value="{3}"/>
								<Parameter/>
								<Parameter value="Field"/>
								<Parameter/>
								<Parameter>
									<!-- GUID_DSRefProperty_PreciseType -->
									<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
										<Parameter value="102" type="System.Int32"/> <!-- Table_Column -->
									</Parameter>
								</Parameter>
							</Parameter>
						</Parameter>
					</Parameter>
				</Action>
			</Actions>
		</Type>

		<Type name="View" defaultSort="Database,Name">
			<Concepts>
				<Concept name="View" restrictions="{Catalog},null,{Name}"/>
			</Concepts>
			<Identifier>
				<Part name="Database" itemName="table_catalog">
					<Concepts>
						<Concept name="Identifier0"/>
					</Concepts>
				</Part>
				<Part name="Schema" itemName="table_schema">
					<Concepts>
						<Concept name="Identifier1"/>
					</Concepts>
				</Part>
				<Part name="Name" itemName="table_name">
					<Concepts>
						<Concept name="Identifier2"/>
					</Concepts>
				</Part>
			</Identifier>
			<Properties>
				<Property name="Name" type="System.String" itemName="table_name"/>
				<Property name="Schema" type="System.String" itemName="table_schema">
					<Concepts>
						<Concept name="Schema"/>
					</Concepts>
				</Property>
				<Property name="CheckOption" type="System.Boolean" itemName="check_option"/>
				<Property name="IsUpdatable" type="System.Boolean" itemName="is_updatable"/>
			</Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
					<Parameter value="Views"/>
				</Action>
				<Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
					<Parameter>
						<Parameter value="{2}"/>
						<Parameter value="{1}"/>
						<Parameter value="View"/>
						<Parameter/>
						<Parameter>
							<!-- GUID_DSRefProperty_PreciseType -->
							<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
								<Parameter value="301" type="System.Int32"/> <!-- View -->
							</Parameter>
						</Parameter>
					</Parameter>
				</Action>
			</Actions>
		</Type>

		<!--
			Defines a type that represents a view column.
		-->
		<Type name="ViewColumn" defaultSort="Database,View,Ordinal">
			<Concepts>
				<Concept name="ViewColumn" restrictions="{Catalog},null,{View},{Name}"/>
			</Concepts>
			<Identifier>
				<Part name="Database" itemName="table_catalog">
					<Concepts>
						<Concept name="Identifier0"/>
					</Concepts>
				</Part>
				<Part name="Schema" itemName="table_schema">
					<Concepts>
						<Concept name="Identifier1"/>
					</Concepts>
				</Part>
				<Part name="View" itemName="table_name">
					<Concepts>
						<Concept name="Identifier2"/>
					</Concepts>
				</Part>
				<Part name="Name" itemName="column_name">
					<Concepts>
						<Concept name="Identifier3"/>
					</Concepts>
				</Part>
			</Identifier>
			<Properties>
				<Property name="Name" type="System.String" itemName="column_name"/>
				<Property name="Ordinal" type="System.Int32" itemName="ordinal_position">
					<Concepts>
						<Concept name="Ordinal">
						</Concept>
					</Concepts>
				</Property>
        <Property name="DataType" type="System.String" itemName="data_type" />
        <Property name="SystemType" type="System.String" itemName="data_type">
          <Concepts>
            <Concept name="UserDataType"/>
            <Concept name="NativeDataType"/>
            <Concept name="ProviderDataType">
              <Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
            </Concept>
            <Concept name="ProviderDbType">
              <Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
            </Concept>
            <Concept name="FrameworkDataType">
              <Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
            </Concept>
          </Concepts>
        </Property>
        <Property name="Length" type="System.Int32" itemName='character_maximum_length'>
					<Concepts>
						<Concept name="Length"/>
					</Concepts>
				</Property>
				<Property name="Precision" type="System.Int32" itemName="numeric_precision">
					<Concepts>
						<Concept name="Precision">
						</Concept>
					</Concepts>
				</Property>
				<Property name="Scale" type="System.Int32" itemName="numeric_scale">
					<Concepts>
						<Concept name="Scale"/>
					</Concepts>
				</Property>
				<Property name="Nullable" type="System.Boolean" itemName="is_nullable">
					<Concepts>
						<Concept name="Nullable">
						</Concept>
					</Concepts>
				</Property>
				<Property name="Default" type="System.String" itemName="column_default">
					<Concepts>
						<Concept name="Default"/>
					</Concepts>
				</Property>
			</Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
					<Parameter value="Columns"/>
				</Action>
				<Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
					<Parameter>
						<Parameter value="{2}"/>
						<Parameter value="{1}"/>
						<Parameter value="View"/>
						<Parameter/>
						<Parameter>
							<!-- GUID_DSRefProperty_PreciseType -->
							<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
								<Parameter value="301" type="System.Int32"/> <!-- View -->
							</Parameter>
						</Parameter>
						<Parameter>
							<Parameter>
								<Parameter value="{3}"/>
								<Parameter/>
								<Parameter value="Field"/>
								<Parameter/>
								<Parameter>
									<!-- GUID_DSRefProperty_PreciseType -->
									<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
										<Parameter value="302" type="System.Int32"/> <!-- View_Column -->
									</Parameter>
								</Parameter>
							</Parameter>
						</Parameter>
					</Parameter>
				</Action>
			</Actions>
		</Type>
    <!--
			Defines a type that represents an index.
		-->
    <Type name="Index" defaultSort="Database,Table,Name">
      <Concepts>
        <Concept name="TableUniqueKey" restrictions="{Catalog},null,{Table},{Name}" filter="IsUnique = true"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="index_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="index_name"/>
        <Property name="IsUnique" type="System.Boolean" itemName="UNIQUE">
          <Concepts>
            <Concept name="IsUnique"/>
          </Concepts>
        </Property>                  
        <Property name="IsPrimary" type="System.Boolean" itemName="PRIMARY_KEY">
          <Concepts>
            <Concept name="IsPrimary"/>
          </Concepts>
        </Property>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="Indexes"/>
        </Action>
        <Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
          <Parameter>
            <Parameter value="{2}"/>
            <Parameter value="{1}"/>
            <Parameter value="Table"/>
            <Parameter/>
            <Parameter>
              <!-- GUID_DSRefProperty_Qualifier -->
              <Parameter value="4656BAEA-F397-11ce-BFE1-00AA0057B34E">
                <Parameter value="{0}"/>
              </Parameter>
              <!-- GUID_DSRefProperty_PreciseType -->
              <Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
                <Parameter value="101" type="System.Int32"/>
                <!-- Table -->
              </Parameter>
            </Parameter>
            <Parameter>
              <Parameter>
                <Parameter value="{3}"/>
                <Parameter/>
                <Parameter value="Index"/>
              </Parameter>
            </Parameter>
          </Parameter>
        </Action>
      </Actions>
    </Type>

    <Type name="IndexColumn" defaultSort="Database,Table,Index,Ordinal">
      <Concepts>
        <Concept name="TableUniqueKeyColumn" restrictions="{Catalog},null,{Table},{TableUniqueKey},{Name}"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="Index" itemName="index_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="column_name">
          <Concepts>
            <Concept name="Identifier4"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="column_name"/>
        <Property name="Ordinal" type="System.Byte" itemName="ordinal_position">
          <Concepts>
            <Concept name="Ordinal">
              <Conversion>
                <ChangeType type="System.Int32"/>
              </Conversion>
            </Concept>
          </Concepts>
        </Property>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="IndexColumns"/>
        </Action>
        <Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
          <Parameter>
            <Parameter value="{2}"/>
            <Parameter value="{1}"/>
            <Parameter value="Table"/>
            <Parameter/>
            <Parameter>
              <!-- GUID_DSRefProperty_Qualifier -->
              <Parameter value="4656BAEA-F397-11ce-BFE1-00AA0057B34E">
                <Parameter value="{0}"/>
              </Parameter>
              <!-- GUID_DSRefProperty_PreciseType -->
              <Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
                <Parameter value="101" type="System.Int32"/>
                <!-- Table -->
              </Parameter>
            </Parameter>
            <Parameter>
              <Parameter>
                <Parameter value="{3}"/>
                <Parameter/>
                <Parameter value="Index"/>
                <Parameter/>
                <Parameter/>
                <Parameter>
                  <Parameter>
                    <Parameter value="{4}"/>
                    <Parameter/>
                    <Parameter value="Field"/>
                  </Parameter>
                </Parameter>
              </Parameter>
            </Parameter>
          </Parameter>
        </Action>
      </Actions>
    </Type>

    <Type name="Triggers" defaultSort="Database,Table,Name">
      <Concepts>
        <Concept name="TableTriggers" restrictions="{Catalog},null,{Table},{Name}"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="trigger_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="trigger_name"/>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="Triggers"/>
        </Action>
      </Actions>
    </Type>
    
    <Type name="ForeignKey" defaultSort="Database,Table,Name">
      <Concepts>
        <Concept name="TableForeignKey" restrictions="{Catalog},null,{Table},{Name}"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="constraint_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="constraint_name"/>
        <Property name="ReferencedColumnName" type="System.String" itemName="fkey_to_column"/>
        <Property name="ColumnName" type="System.String" itemName="fkey_from_column"/>
        <Property name="ReferencedTableDatabase" type="System.String" itemName="fkey_to_catalog">
          <Concepts>
            <Concept name="ReferencedTableId0"/>
          </Concepts>
        </Property>
        <Property name="ReferencedTableSchema" type="System.String" itemName="fkey_to_schema">
          <Concepts>
            <Concept name="ReferencedTableId1"/>
          </Concepts>
        </Property>
        <Property name="ReferencedTableName" type="System.String" itemName="fkey_to_table">
          <Concepts>
            <Concept name="ReferencedTableId2"/>
          </Concepts>
        </Property>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="ForeignKeys"/>
        </Action>
      </Actions>
    </Type>

    <Type name="ForeignKeyColumn" defaultSort="Database,Table,ForeignKey,Ordinal">
      <Concepts>
        <Concept name="TableForeignKeyColumn" restrictions="{Catalog},null,{Table},{TableForeignKey},{Name}"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="ForeignKey" itemName="constraint_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="fkey_from_column">
          <Concepts>
            <Concept name="Identifier4"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="fkey_from_column"/>
        <Property name="Ordinal" type="System.Int32" itemName="fkey_from_ordinal_position">
          <Concepts>
            <Concept name="Ordinal"/>
          </Concepts>
        </Property>
        <Property name="ReferencedColumnName" type="System.String" itemName="fkey_to_column">
          <Concepts>
            <Concept name="ReferencedTableColumn"/>
          </Concepts>
        </Property>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="ForeignKeys"/>
        </Action>
      </Actions>
    </Type>
  </Types>
</VSDataObjectSupport>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/SQLiteDataSourceInformation.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using Microsoft.VisualStudio.Data;
  using Microsoft.VisualStudio.Data.AdoDotNet;

  /// <summary>
  /// Provides basic DataSourceInformation about the underlying connection
  /// </summary>
  internal sealed class SQLiteDataSourceInformation : AdoDotNetDataSourceInformation
  {
    public SQLiteDataSourceInformation(DataConnection connection) : base(connection)
    {
      Initialize();
    }

    private void Initialize()
    {
      AddProperty(DefaultSchema);
      AddProperty(DefaultCatalog, "main");
      AddProperty(SupportsAnsi92Sql, true);
      AddProperty(SupportsQuotedIdentifierParts, true);
      AddProperty(IdentifierOpenQuote, "[");
      AddProperty(IdentifierCloseQuote, "]");
      AddProperty(CatalogSeparator, ".");
      AddProperty(CatalogSupported, true);
      AddProperty(CatalogSupportedInDml, true);
      AddProperty(SchemaSupported, false);
      AddProperty(SchemaSupportedInDml, false);
      AddProperty(SchemaSeparator, "");
      AddProperty(ParameterPrefix, "@");
      AddProperty(ParameterPrefixInName, true);
      AddProperty("DeskTopDataSource", true);
      AddProperty("LocalDatabase", true);
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































Deleted SQLite.Designer/SQLiteDataViewSupport.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Globalization;
  using Microsoft.VisualStudio.Data;
  using Microsoft.VisualStudio.OLE.Interop;
  using Microsoft.VisualStudio.Data.AdoDotNet;

  /// <summary>
  /// Provides DataViewSupport with a location where the XML file is for the Server Explorer's view.
  /// </summary>
  internal sealed class SQLiteDataViewSupport : DataViewSupport
  {
    public SQLiteDataViewSupport()
      : base(String.Format(CultureInfo.InvariantCulture, "SQLite.Designer.SQLiteDataViewSupport{0}", GetVSVersion()), typeof(SQLiteDataViewSupport).Assembly)
    {
    }

    private static string GetVSVersion()
    {
      switch (System.Diagnostics.FileVersionInfo.GetVersionInfo(Environment.GetCommandLineArgs()[0]).FileMajorPart)
      {
        case 8:
          return "2005";
		case 10:
		  return "2010";
        default:
          return "2008";
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































Deleted SQLite.Designer/SQLiteDataViewSupport2005.xml.
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
<?xml version="1.0" encoding="utf-8"?>

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<VSDataViewSupport xmlns="http://tempuri.org/VSDataViewSupport.xsd">
	<DataViews>
		<!-- This sample defines a single data view -->
		<DataView name="SQLite">
      <DisplayName>SQLite</DisplayName>
			<!-- The connection node is static, i.e. has no underlying object -->
			<StaticConnectionNode>
				<!-- We can always specify data from the root object -->
				<InitialDisplayName>SQLite [{Root.Server}]</InitialDisplayName>
				<CommandBindings>
          <CommandBinding name="NewTable" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13600" handler="SQLite.Designer.SQLiteCommandHandler"/>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
          <CommandBinding name="Vacuum"   guid="814658EE-A28E-4b97-BC33-4B1BC81EBECB" cmdid="262" handler="SQLite.Designer.SQLiteCommandHandler"/>
          <CommandBinding name="Rekey"    guid="814658EE-A28E-4b97-BC33-4B1BC81EBECB" cmdid="263" handler="SQLite.Designer.SQLiteCommandHandler"/>
        </CommandBindings>
				<Children>
          
					<StaticNode nid="Tables">
            <DisplayName>Tables</DisplayName>
						<CommandBindings>
              <CommandBinding name="NewTable" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13600" handler="SQLite.Designer.SQLiteCommandHandler"/>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
            </CommandBindings>
						<Children>
              <Selection type="Table" filter="TYPE='TABLE'">
                <SelectionNode nid="Table">
                  <Icon name="Table"/>
                  <Children>
                    <SubHierarchyRef name="Table children"/>
                  </Children>
                </SelectionNode>
              </Selection>
            </Children>
					</StaticNode>

          <StaticNode nid="Tables">
            <DisplayName>System Tables</DisplayName>
            <CommandBindings>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
            </CommandBindings>
            <Children>
              <Selection type="Table" filter="TYPE='SYSTEM_TABLE'">
                <SelectionNode nid="Table">
                  <Icon name="Table"/>
                  <Children>
                    <SubHierarchyRef name="Table children"/>
                  </Children>
                </SelectionNode>
              </Selection>
            </Children>
          </StaticNode>

          <StaticNode nid="Views">
            <DisplayName>Views</DisplayName>
						<CommandBindings>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
              <CommandBinding name="NewView" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13601" handler="SQLite.Designer.SQLiteCommandHandler" />
            </CommandBindings>
						<Children>
							<Selection type="View">
								<SelectionNode nid="View">
                  <DisplayName>{View.Name}</DisplayName>
                  <Icon name="View"/>
									<Children>
                    <SubHierarchyRef name="View children"/>
									</Children>
								</SelectionNode>
							</Selection>
						</Children>
					</StaticNode>
                  
        </Children>
			</StaticConnectionNode>
		</DataView>
	</DataViews>
  <SubHierarchies>
    <SubHierarchy name="table children">      
      <StaticNode nid="Columns">
        <DisplayName>Columns</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="TableColumn" restrictions="{Table.Database},null,{Table.Name}" filter="InPrimaryKey=True">
            <SelectionNode>
              <Icon name="PrimaryKey"/>
            </SelectionNode>
          </Selection>
          <Selection type="TableColumn" restrictions="{Table.Database},null,{Table.Name}" filter="InPrimaryKey=False">
            <SelectionNode>
              <Icon name="Column"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
      
      <StaticNode nid="Indexes">
        <DisplayName>Indexes</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="Index" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon when="{IsPrimary}=true" name="PrimaryKey"/>
              <Icon when="{IsUnique}=true" name="UniqueKey"/>
              <Icon name="Index"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>

      <StaticNode nid="ForeignKeys">
        <DisplayName>Foreign Keys</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="ForeignKey" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon name="ForeignKey"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>

      <StaticNode nid="Triggers">
        <DisplayName>Triggers</DisplayName>
        <Children>
          <Selection type="Triggers" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon name="Index" />
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
    </SubHierarchy>
    <SubHierarchy name="view children">      
      <StaticNode nid="Columns">
        <DisplayName>Columns</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="ViewColumn" restrictions="{View.Database},null,{View.Name}">
            <SelectionNode>
              <Icon name="Column"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
      
      <StaticNode nid="Triggers">
        <DisplayName>Triggers</DisplayName>
        <Children>
          <Selection type="Triggers" restrictions="{View.Database},null,{View.Name}">
            <SelectionNode>
              <Icon name="Index" />
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
    </SubHierarchy>
  </SubHierarchies>
  <TypeExtensions>
    
    <TypeExtension name="Table">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropTable" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Table"/>
        </CommandBinding>
        <CommandBinding name="Browse_DataVS2005" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12384" handler="Microsoft.VisualStudio.DataTools.DBPackage.VDT_OLEDB_CommandHandler_TableTools">
          <Parameter value="Open"/>
        </CommandBinding>
        <CommandBinding name="Design" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12291" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Table"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="View">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="IsUpdatable">
          <DisplayName>Updatable</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropView" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="View"/>
        </CommandBinding>
        <CommandBinding name="Design" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12291" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="View"/>
        </CommandBinding>
        <CommandBinding name="Browse_DataVS2005" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12384" handler="Microsoft.VisualStudio.DataTools.DBPackage.VDT_OLEDB_CommandHandler_TableTools">
          <Parameter value="Open"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="ViewColumn">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="View">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Ordinal"/>
        <Property name="Length"/>
        <Property name="DataType">
          <DisplayName>Data Type</DisplayName>
        </Property>
        <Property name="Nullable">
          <DisplayName>Allow Nulls</DisplayName>
        </Property>
        <Property name="Default">
          <DisplayName>Default Value</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="Index">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="IsUnique">
          <DisplayName>Is Unique</DisplayName>
        </Property>
        <Property name="IsPrimary">
          <DisplayName>Primary Key</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropIndex" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Index"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>

    <TypeExtension name="Triggers">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
    </TypeExtension>

    <TypeExtension name="TableColumn">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Ordinal"/>
        <Property name="Length"/>
        <Property name="DataType">
          <DisplayName>Data Type</DisplayName>
        </Property>
        <Property name="Nullable">
          <DisplayName>Allow Nulls</DisplayName>
        </Property>
        <Property name="Default">
          <DisplayName>Default Value</DisplayName>
        </Property>
        <Property name="InPrimaryKey">
          <DisplayName>Primary Key</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>

    <TypeExtension name="ForeignKey">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <!--<Property name="ColumnName">
          <DisplayName>Source Column</DisplayName>
          <Category resource="Category_Source"/>
        </Property>-->
        <Property name="ReferencedTableDatabase">
          <DisplayName>Referenced Database</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>
        <Property name="ReferencedTableName">
          <DisplayName>Referenced Table</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>
        <!--<Property name="ReferencedColumnName">
          <DisplayName>Referenced Column</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>-->
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>
  </TypeExtensions>

  <Resources baseName="SQLite.Designer.VSPackage">
    <Resource name="Category_Identity">(Identity)</Resource>
    <Resource name="Category_Location">(Location)</Resource>
    <Resource name="Category_Source">(Source)</Resource>
    <Resource name="Category_Refs">References</Resource>
  </Resources>
</VSDataViewSupport>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/SQLiteDataViewSupport2008.xml.
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
<?xml version="1.0" encoding="utf-8"?>

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<VSDataViewSupport xmlns="http://tempuri.org/VSDataViewSupport.xsd">
	<DataViews>
		<!-- This sample defines a single data view -->
		<DataView name="SQLite">
      <DisplayName>SQLite</DisplayName>
			<!-- The connection node is static, i.e. has no underlying object -->
			<StaticConnectionNode>
				<!-- We can always specify data from the root object -->
				<InitialDisplayName>SQLite [{Root.Server}]</InitialDisplayName>
				<CommandBindings>
          <CommandBinding name="NewTable" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13600" handler="SQLite.Designer.SQLiteCommandHandler"/>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
          <CommandBinding name="Vacuum"   guid="814658EE-A28E-4b97-BC33-4B1BC81EBECB" cmdid="262" handler="SQLite.Designer.SQLiteCommandHandler"/>
          <CommandBinding name="Rekey"    guid="814658EE-A28E-4b97-BC33-4B1BC81EBECB" cmdid="263" handler="SQLite.Designer.SQLiteCommandHandler"/>
        </CommandBindings>
				<Children>
          
					<StaticNode nid="Tables">
            <DisplayName>Tables</DisplayName>
						<CommandBindings>
              <CommandBinding name="NewTable" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13600" handler="SQLite.Designer.SQLiteCommandHandler"/>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
            </CommandBindings>
						<Children>
              <Selection type="Table" filter="TYPE='TABLE'">
                <SelectionNode nid="Table">
                  <Icon name="Table"/>
                  <Children>
                    <SubHierarchyRef name="Table children"/>
                  </Children>
                </SelectionNode>
              </Selection>
            </Children>
					</StaticNode>

          <StaticNode nid="Tables">
            <DisplayName>System Tables</DisplayName>
            <CommandBindings>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
            </CommandBindings>
            <Children>
              <Selection type="Table" filter="TYPE='SYSTEM_TABLE'">
                <SelectionNode nid="Table">
                  <Icon name="Table"/>
                  <Children>
                    <SubHierarchyRef name="Table children"/>
                  </Children>
                </SelectionNode>
              </Selection>
            </Children>
          </StaticNode>

          <StaticNode nid="Views">
            <DisplayName>Views</DisplayName>
						<CommandBindings>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
              <CommandBinding name="NewView" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13601" handler="SQLite.Designer.SQLiteCommandHandler" />
            </CommandBindings>
						<Children>
							<Selection type="View">
								<SelectionNode nid="View">
                  <DisplayName>{View.Name}</DisplayName>
                  <Icon name="View"/>
									<Children>
                    <SubHierarchyRef name="View children"/>
									</Children>
								</SelectionNode>
							</Selection>
						</Children>
					</StaticNode>   
          
				</Children>
			</StaticConnectionNode>
		</DataView>
	</DataViews>
  
  <SubHierarchies>
    <SubHierarchy name="table children">      
      <StaticNode nid="Columns">
        <DisplayName>Columns</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="TableColumn" restrictions="{Table.Database},null,{Table.Name}" filter="InPrimaryKey=True">
            <SelectionNode>
              <Icon name="PrimaryKey"/>
            </SelectionNode>
          </Selection>
          <Selection type="TableColumn" restrictions="{Table.Database},null,{Table.Name}" filter="InPrimaryKey=False">
            <SelectionNode>
              <Icon name="Column"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
      
      <StaticNode nid="Indexes">
        <DisplayName>Indexes</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="Index" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon when="{IsPrimary}=true" name="PrimaryKey"/>
              <Icon when="{IsUnique}=true" name="UniqueKey"/>
              <Icon name="Index"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>

      <StaticNode nid="ForeignKeys">
        <DisplayName>Foreign Keys</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="ForeignKey" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon name="ForeignKey"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>

      <StaticNode nid="Triggers">
        <DisplayName>Triggers</DisplayName>
        <Children>
          <Selection type="Triggers" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon name="Index" />
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
    </SubHierarchy>
    
    <SubHierarchy name="view children">      
      <StaticNode nid="Columns">
        <DisplayName>Columns</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="ViewColumn" restrictions="{View.Database},null,{View.Name}">
            <SelectionNode>
              <Icon name="Column"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
      
      <StaticNode nid="Triggers">
        <DisplayName>Triggers</DisplayName>
        <Children>
          <Selection type="Triggers" restrictions="{View.Database},null,{View.Name}">
            <SelectionNode>
              <Icon name="Index" />
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
    </SubHierarchy>
    
  </SubHierarchies>
  <TypeExtensions>
    
    <TypeExtension name="Table">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropTable" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Table"/>
        </CommandBinding>
        <CommandBinding name="Browse_Data" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12384" handler="884DD964-5327-461f-9F06-6484DD540F8F">
          <Parameter value="Open"/>
        </CommandBinding>
        <CommandBinding name="Design" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12291" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Table"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="View">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="IsUpdatable">
          <DisplayName>Updatable</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropView" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="View"/>
        </CommandBinding>
        <CommandBinding name="Design" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12291" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="View"/>
        </CommandBinding>
        <CommandBinding name="Browse_Data" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12384" handler="884DD964-5327-461f-9F06-6484DD540F8F">
          <Parameter value="Open"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="ViewColumn">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="View">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Ordinal"/>
        <Property name="Length"/>
        <Property name="DataType">
          <DisplayName>Data Type</DisplayName>
        </Property>
        <Property name="Nullable">
          <DisplayName>Allow Nulls</DisplayName>
        </Property>
        <Property name="Default">
          <DisplayName>Default Value</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="Index">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="IsUnique">
          <DisplayName>Is Unique</DisplayName>
        </Property>
        <Property name="IsPrimary">
          <DisplayName>Primary Key</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropIndex" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Index"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>

    <TypeExtension name="Triggers">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
    </TypeExtension>

    <TypeExtension name="TableColumn">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Ordinal"/>
        <Property name="Length"/>
        <Property name="DataType">
          <DisplayName>Data Type</DisplayName>
        </Property>
        <Property name="Nullable">
          <DisplayName>Allow Nulls</DisplayName>
        </Property>
        <Property name="Default">
          <DisplayName>Default Value</DisplayName>
        </Property>
        <Property name="InPrimaryKey">
          <DisplayName>Primary Key</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>

    <TypeExtension name="ForeignKey">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <!--<Property name="ColumnName">
          <DisplayName>Source Column</DisplayName>
          <Category resource="Category_Source"/>
        </Property>-->
        <Property name="ReferencedTableDatabase">
          <DisplayName>Referenced Database</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>
        <Property name="ReferencedTableName">
          <DisplayName>Referenced Table</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>
        <!--<Property name="ReferencedColumnName">
          <DisplayName>Referenced Column</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>-->
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>
  </TypeExtensions>

  <Resources baseName="SQLite.Designer.VSPackage">
    <Resource name="Category_Identity">(Identity)</Resource>
    <Resource name="Category_Location">(Location)</Resource>
    <Resource name="Category_Source">(Source)</Resource>
    <Resource name="Category_Refs">References</Resource>
  </Resources>
</VSDataViewSupport>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/SQLiteDataViewSupport2010.xml.
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
<?xml version="1.0" encoding="utf-8"?>

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<VSDataViewSupport xmlns="http://tempuri.org/VSDataViewSupport.xsd">
	<DataViews>
		<!-- This sample defines a single data view -->
		<DataView name="SQLite">
      <DisplayName>SQLite</DisplayName>
			<!-- The connection node is static, i.e. has no underlying object -->
			<StaticConnectionNode>
				<!-- We can always specify data from the root object -->
				<InitialDisplayName>SQLite [{Root.Server}]</InitialDisplayName>
				<CommandBindings>
          <CommandBinding name="NewTable" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13600" handler="SQLite.Designer.SQLiteCommandHandler"/>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
          <CommandBinding name="Vacuum"   guid="814658EE-A28E-4b97-BC33-4B1BC81EBECB" cmdid="262" handler="SQLite.Designer.SQLiteCommandHandler"/>
          <CommandBinding name="Rekey"    guid="814658EE-A28E-4b97-BC33-4B1BC81EBECB" cmdid="263" handler="SQLite.Designer.SQLiteCommandHandler"/>
        </CommandBindings>
				<Children>
          
					<StaticNode nid="Tables">
            <DisplayName>Tables</DisplayName>
						<CommandBindings>
              <CommandBinding name="NewTable" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13600" handler="SQLite.Designer.SQLiteCommandHandler"/>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
            </CommandBindings>
						<Children>
              <Selection type="Table" filter="TYPE='TABLE'">
                <SelectionNode nid="Table">
                  <Icon name="Table"/>
                  <Children>
                    <SubHierarchyRef name="Table children"/>
                  </Children>
                </SelectionNode>
              </Selection>
            </Children>
					</StaticNode>

          <StaticNode nid="Tables">
            <DisplayName>System Tables</DisplayName>
            <CommandBindings>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
            </CommandBindings>
            <Children>
              <Selection type="Table" filter="TYPE='SYSTEM_TABLE'">
                <SelectionNode nid="Table">
                  <Icon name="Table"/>
                  <Children>
                    <SubHierarchyRef name="Table children"/>
                  </Children>
                </SelectionNode>
              </Selection>
            </Children>
          </StaticNode>

          <StaticNode nid="Views">
            <DisplayName>Views</DisplayName>
						<CommandBindings>
              <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
              <CommandBinding name="NewView" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13601" handler="SQLite.Designer.SQLiteCommandHandler" />
            </CommandBindings>
						<Children>
							<Selection type="View">
								<SelectionNode nid="View">
                  <DisplayName>{View.Name}</DisplayName>
                  <Icon name="View"/>
									<Children>
                    <SubHierarchyRef name="View children"/>
									</Children>
								</SelectionNode>
							</Selection>
						</Children>
					</StaticNode>   
          
				</Children>
			</StaticConnectionNode>
		</DataView>
	</DataViews>
  
  <SubHierarchies>
    <SubHierarchy name="table children">      
      <StaticNode nid="Columns">
        <DisplayName>Columns</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="TableColumn" restrictions="{Table.Database},null,{Table.Name}" filter="InPrimaryKey=True">
            <SelectionNode>
              <Icon name="PrimaryKey"/>
            </SelectionNode>
          </Selection>
          <Selection type="TableColumn" restrictions="{Table.Database},null,{Table.Name}" filter="InPrimaryKey=False">
            <SelectionNode>
              <Icon name="Column"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
      
      <StaticNode nid="Indexes">
        <DisplayName>Indexes</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="Index" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon when="{IsPrimary}=true" name="PrimaryKey"/>
              <Icon when="{IsUnique}=true" name="UniqueKey"/>
              <Icon name="Index"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>

      <StaticNode nid="ForeignKeys">
        <DisplayName>Foreign Keys</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="ForeignKey" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon name="ForeignKey"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>

      <StaticNode nid="Triggers">
        <DisplayName>Triggers</DisplayName>
        <Children>
          <Selection type="Triggers" restrictions="{Table.Database},null,{Table.Name}">
            <SelectionNode>
              <Icon name="Index" />
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
    </SubHierarchy>
    
    <SubHierarchy name="view children">      
      <StaticNode nid="Columns">
        <DisplayName>Columns</DisplayName>
        <CommandBindings>
          <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        </CommandBindings>
        <Children>
          <Selection type="ViewColumn" restrictions="{View.Database},null,{View.Name}">
            <SelectionNode>
              <Icon name="Column"/>
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
      
      <StaticNode nid="Triggers">
        <DisplayName>Triggers</DisplayName>
        <Children>
          <Selection type="Triggers" restrictions="{View.Database},null,{View.Name}">
            <SelectionNode>
              <Icon name="Index" />
            </SelectionNode>
          </Selection>
        </Children>
      </StaticNode>
    </SubHierarchy>
    
  </SubHierarchies>
  <TypeExtensions>
    
    <TypeExtension name="Table">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropTable" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Table"/>
        </CommandBinding>
        <CommandBinding name="Browse_Data" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12384" handler="884DD964-5327-461f-9F06-6484DD540F8F">
          <Parameter value="Open"/>
        </CommandBinding>
        <CommandBinding name="Design" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12291" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Table"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="View">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="IsUpdatable">
          <DisplayName>Updatable</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropView" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="View"/>
        </CommandBinding>
        <CommandBinding name="Design" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12291" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="View"/>
        </CommandBinding>
        <CommandBinding name="Browse_Data" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12384" handler="884DD964-5327-461f-9F06-6484DD540F8F">
          <Parameter value="Open"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="ViewColumn">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="View">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Ordinal"/>
        <Property name="Length"/>
        <Property name="DataType">
          <DisplayName>Data Type</DisplayName>
        </Property>
        <Property name="Nullable">
          <DisplayName>Allow Nulls</DisplayName>
        </Property>
        <Property name="Default">
          <DisplayName>Default Value</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>
    
    <TypeExtension name="Index">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="IsUnique">
          <DisplayName>Is Unique</DisplayName>
        </Property>
        <Property name="IsPrimary">
          <DisplayName>Primary Key</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
        <CommandBinding name="DropIndex" guid="5efc7975-14bc-11cf-9b2b-00aa00573819" cmdid="17" handler="SQLite.Designer.SQLiteCommandHandler">
          <Parameter value="Index"/>
        </CommandBinding>
      </CommandBindings>
    </TypeExtension>

    <TypeExtension name="Triggers">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
    </TypeExtension>

    <TypeExtension name="TableColumn">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Ordinal"/>
        <Property name="Length"/>
        <Property name="DataType">
          <DisplayName>Data Type</DisplayName>
        </Property>
        <Property name="Nullable">
          <DisplayName>Allow Nulls</DisplayName>
        </Property>
        <Property name="Default">
          <DisplayName>Default Value</DisplayName>
        </Property>
        <Property name="InPrimaryKey">
          <DisplayName>Primary Key</DisplayName>
        </Property>
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>

    <TypeExtension name="ForeignKey">
      <Identifier>
        <Part name="Name">
          <Category resource="Category_Identity"/>
        </Part>
        <Part name="Database">
          <DisplayName>Catalog</DisplayName>
          <Category resource="Category_Location"/>
        </Part>
        <Part name="Table">
          <Category resource="Category_Location"/>
        </Part>
      </Identifier>
      <Properties>
        <!--<Property name="ColumnName">
          <DisplayName>Source Column</DisplayName>
          <Category resource="Category_Source"/>
        </Property>-->
        <Property name="ReferencedTableDatabase">
          <DisplayName>Referenced Database</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>
        <Property name="ReferencedTableName">
          <DisplayName>Referenced Table</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>
        <!--<Property name="ReferencedColumnName">
          <DisplayName>Referenced Column</DisplayName>
          <Category resource="Category_Refs"/>
        </Property>-->
      </Properties>
      <CommandBindings>
        <CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
      </CommandBindings>
    </TypeExtension>
  </TypeExtensions>

  <Resources baseName="SQLite.Designer.VSPackage">
    <Resource name="Category_Identity">(Identity)</Resource>
    <Resource name="Category_Location">(Location)</Resource>
    <Resource name="Category_Source">(Source)</Resource>
    <Resource name="Category_Refs">References</Resource>
  </Resources>
</VSDataViewSupport>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Designer/SQLitePackage.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using Microsoft.VisualStudio.Shell;
  using System.Runtime.InteropServices;
  using System.ComponentModel.Design;
  using Microsoft.VisualStudio.Shell.Interop;

  /// <summary>
  /// Ideally we'd be a package provider, but the VS Express Editions don't support us, so this class
  /// exists so that in the future we can perhaps work with the Express Editions.
  /// </summary>
  [Guid("DCBE6C8D-0E57-4099-A183-98FF74C64D9C")]
  internal sealed class SQLitePackage : Package
  {
    public SQLitePackage()
    {
    }

    protected override void Initialize()
    {
      IServiceContainer sc = (IServiceContainer)this;
      sc.AddService(typeof(SQLiteProviderObjectFactory), new ServiceCreatorCallback(CreateService), true);

      ToolboxInitialized += new EventHandler(SQLitePackage_ToolboxInitialized);
      ToolboxUpgraded += new EventHandler(SQLitePackage_ToolboxUpgraded);
      base.Initialize();
    }

    void SQLitePackage_ToolboxUpgraded(object sender, EventArgs e)
    {
      IVsToolbox vstbx = GetService(typeof(SVsToolbox)) as IVsToolbox;

      vstbx.RemoveTab("SQLite");

      SQLitePackage_ToolboxInitialized(sender, e);
    }

    void SQLitePackage_ToolboxInitialized(object sender, EventArgs e)
    {
      ParseToolboxResource(new System.IO.StringReader(VSPackage.ToolboxItems), null);
    }

    private object CreateService(IServiceContainer container, Type serviceType)
    {
      if (serviceType == typeof(SQLiteProviderObjectFactory))
        return new SQLiteProviderObjectFactory();

      return null;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































Deleted SQLite.Designer/SQLiteProviderObjectFactory.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using Microsoft.VisualStudio.Data.AdoDotNet;
  using Microsoft.VisualStudio.Data;
  using System.Runtime.InteropServices;
  using Microsoft.Data.ConnectionUI;

  /// <summary>
  /// For a package-based provider, this factory creates instances of the main objects we support
  /// </summary>
  [Guid("DCBE6C8D-0E57-4099-A183-98FF74C64D9D")]
  internal sealed class SQLiteProviderObjectFactory : AdoDotNetProviderObjectFactory
  {
    public SQLiteProviderObjectFactory()
    {
    }

    public override object CreateObject(Type objType)
    {
      if (objType == typeof(DataConnectionSupport))
        return new SQLiteDataConnectionSupport();

      if (objType == typeof(IDataConnectionProperties) || objType == typeof(DataConnectionProperties))
        return new SQLiteConnectionProperties();

      if (objType == typeof(IDataConnectionUIControl) || objType == typeof(DataConnectionUIControl))
        return new SQLiteConnectionUIControl();

      return base.CreateObject(objType);
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































Deleted SQLite.Designer/TableNameDialog.Designer.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  partial class TableNameDialog
  {
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      System.Windows.Forms.Button _ok;
      System.Windows.Forms.Button _cancel;
      this.label1 = new System.Windows.Forms.Label();
      this._name = new System.Windows.Forms.TextBox();
      _ok = new System.Windows.Forms.Button();
      _cancel = new System.Windows.Forms.Button();
      this.SuspendLayout();
      // 
      // _ok
      // 
      _ok.Location = new System.Drawing.Point(211, 51);
      _ok.Name = "_ok";
      _ok.Size = new System.Drawing.Size(75, 23);
      _ok.TabIndex = 2;
      _ok.Text = "OK";
      _ok.UseVisualStyleBackColor = true;
      _ok.Click += new System.EventHandler(this._ok_Click);
      // 
      // _cancel
      // 
      _cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
      _cancel.Location = new System.Drawing.Point(292, 51);
      _cancel.Name = "_cancel";
      _cancel.Size = new System.Drawing.Size(75, 23);
      _cancel.TabIndex = 3;
      _cancel.Text = "Cancel";
      _cancel.UseVisualStyleBackColor = true;
      _cancel.Click += new System.EventHandler(this._cancel_Click);
      // 
      // label1
      // 
      this.label1.AutoSize = true;
      this.label1.Location = new System.Drawing.Point(12, 9);
      this.label1.Name = "label1";
      this.label1.Size = new System.Drawing.Size(126, 13);
      this.label1.TabIndex = 0;
      this.label1.Text = "Choose a &name for this %";
      // 
      // _name
      // 
      this._name.Location = new System.Drawing.Point(12, 25);
      this._name.Name = "_name";
      this._name.Size = new System.Drawing.Size(355, 20);
      this._name.TabIndex = 1;
      // 
      // TableNameDialog
      // 
      this.AcceptButton = _ok;
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.CancelButton = _cancel;
      this.ClientSize = new System.Drawing.Size(379, 86);
      this.Controls.Add(this._name);
      this.Controls.Add(this.label1);
      this.Controls.Add(_cancel);
      this.Controls.Add(_ok);
      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
      this.MaximizeBox = false;
      this.MinimizeBox = false;
      this.Name = "TableNameDialog";
      this.Font = new System.Drawing.Font("MS Shell Dlg 2", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
      this.Text = "% Name";
      this.ResumeLayout(false);
      this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.Label label1;
    private System.Windows.Forms.TextBox _name;

  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































Deleted SQLite.Designer/TableNameDialog.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Text;
  using System.Windows.Forms;

  public partial class TableNameDialog : Form
  {
    public TableNameDialog()
      : this("Table", null)
    {
    }

    public TableNameDialog(string type, string defaultName)
    {
      InitializeComponent();
      Text = Text.Replace("%", type);
      label1.Text = label1.Text.Replace("%", type.ToLowerInvariant());
      _name.Text = defaultName;
    }

    public string TableName
    {
      get { return _name.Text; }
      set { _name.Text = value; }
    }

    private void _ok_Click(object sender, EventArgs e)
    {
      DialogResult = DialogResult.OK;
      Close();
    }

    private void _cancel_Click(object sender, EventArgs e)
    {
      DialogResult = DialogResult.Cancel;
      Close();
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































Deleted SQLite.Designer/TableNameDialog.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="_ok.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="_cancel.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































Deleted SQLite.Designer/VSDesign/Microsoft.Data.ConnectionUI.dll.

cannot compute difference between binary files

Deleted SQLite.Designer/VSDesign/Microsoft.VisualStudio.CommandBars.dll.

cannot compute difference between binary files

Deleted SQLite.Designer/VSDesign/Microsoft.VisualStudio.Data.dll.

cannot compute difference between binary files

Deleted SQLite.Designer/VSDesign/Microsoft.VisualStudio.OLE.Interop.dll.

cannot compute difference between binary files

Deleted SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.Interop.8.0.dll.

cannot compute difference between binary files

Deleted SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.Interop.dll.

cannot compute difference between binary files

Deleted SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.dll.

cannot compute difference between binary files

Deleted SQLite.Designer/VSDesign/envdte.dll.

cannot compute difference between binary files

Deleted SQLite.Designer/VSPackage.Designer.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
/********************************************************
 * 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!
 ********************************************************/

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace SQLite.Designer {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class VSPackage {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal VSPackage() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SQLite.Designer.VSPackage", typeof(VSPackage).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to MHM2ZQETQKDTJEPTC1MTQCZ1R1KQEMAPZHETDZPZI9RPJ0E0DHAHKCHZPKQ8AQZICADHKIZ1JAQED8IDEHZPZKZEIKAQERHPRCQMAMRKDEZZQRDRDHJEZIKECZPDIIKC.
        /// </summary>
        internal static string _400 {
            get {
                return ResourceManager.GetString("400", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to The database and its metadata will be un-encrypted.  No password will be required to open the database and view its contents..
        /// </summary>
        internal static string Decrypt {
            get {
                return ResourceManager.GetString("Decrypt", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to The database and its metadata will be encrypted using the supplied password as a hash..
        /// </summary>
        internal static string Encrypt {
            get {
                return ResourceManager.GetString("Encrypt", resourceCulture);
            }
        }
        
        internal static System.Drawing.Bitmap info {
            get {
                object obj = ResourceManager.GetObject("info", resourceCulture);
                return ((System.Drawing.Bitmap)(obj));
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to The database and its metadata will be re-encrypted using the supplied password as a hash..
        /// </summary>
        internal static string ReEncrypt {
            get {
                return ResourceManager.GetString("ReEncrypt", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to [SQLite]
        ///System.Data.SQLite.SQLiteConnection, System.Data.SQLite
        ///System.Data.SQLite.SQLiteDataAdapter, System.Data.SQLite
        ///System.Data.SQLite.SQLiteCommand, System.Data.SQLite
        ///.
        /// </summary>
        internal static string ToolboxItems {
            get {
                return ResourceManager.GetString("ToolboxItems", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































Deleted SQLite.Designer/VSPackage.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="Decrypt" xml:space="preserve">
    <value>The database and its metadata will be un-encrypted.  No password will be required to open the database and view its contents.</value>
  </data>
  <data name="Encrypt" xml:space="preserve">
    <value>The database and its metadata will be encrypted using the supplied password as a hash.</value>
  </data>
  <data name="ReEncrypt" xml:space="preserve">
    <value>The database and its metadata will be re-encrypted using the supplied password as a hash.</value>
  </data>
  <data name="400" xml:space="preserve">
    <value>MHM2ZQETQKDTJEPTC1MTQCZ1R1KQEMAPZHETDZPZI9RPJ0E0DHAHKCHZPKQ8AQZICADHKIZ1JAQED8IDEHZPZKZEIKAQERHPRCQMAMRKDEZZQRDRDHJEZIKECZPDIIKC</value>
  </data>
  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <data name="info" type="System.Resources.ResXFileRef, System.Windows.Forms">
    <value>Resources\info.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
  </data>
  <data name="ToolboxItems" type="System.Resources.ResXFileRef, System.Windows.Forms">
    <value>Resources\ToolboxItems.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































Deleted SQLite.Designer/source.extension.vsixmanifest.
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"?>
<Vsix Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
  <Identifier Id="67b5f3a9-cde1-430f-a12b-af95bb064851">
    <Name>SQLite Designer</Name>
    <Author>Robert Simpson</Author>
    <Version>1.0.38.1</Version>
    <Description>ADO.NET Data Designer for SQLite</Description>
    <Locale>1033</Locale>
    <InstalledByMsi>false</InstalledByMsi>
    <SupportedProducts>
      <VisualStudio Version="10.0">
        <Edition>Pro</Edition>
      </VisualStudio>
    </SupportedProducts>
    <SupportedFrameworkRuntimeEdition MinVersion="4.0" MaxVersion="4.0" />
  </Identifier>
  <References />
  <Content>
    <VsPackage>|SQLite.Designer;PkgdefProjectOutputGroup|</VsPackage>
  </Content>
</Vsix>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted SQLite.Interop/SQLite.Interop.2008.vcproj.
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
<?xml version="1.0" encoding="Windows-1252"?>
<!--
 *
 * SQLite.Interop.2008.vcproj -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<VisualStudioProject
	ProjectType="Visual C++"
	Version="9.00"
	Name="SQLite.Interop.2008"
	ProjectGUID="{53784BC1-A8BC-4AC8-8A3E-158D6807345A}"
	RootNamespace="SQLite.Interop"
	Keyword="Win32Proj"
	TargetFrameworkVersion="131072"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>
		<Platform
			Name="x64"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="false"
				ExceptionHandling="0"
				BasicRuntimeChecks="0"
				RuntimeLibrary="3"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions="$(INTEROP_ASSEMBLY_RESOURCES)"
				AdditionalDependencies="$(ProjectDir)..\bin\$(ConfigurationYear)\$(ConfigurationName)Module\bin\System.Data.SQLite.netmodule"
				OutputFile="$(OutDir)\$(INTEROP_MIXED_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				AssemblyDebug="1"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_MIXED_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				LinkTimeCodeGeneration="1"
				ImportLibrary="$(TargetDir)$(INTEROP_MIXED_NAME).lib"
				TargetMachine="1"
				KeyFile="$(INTEROP_KEY_FILE)"
				DelaySign="true"
				CLRUnmanagedCodeCheck="true"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_MIXED_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="&quot;$(FrameworkSDKDir)Bin\sn.exe&quot; -Ra &quot;$(OutDir)\$(INTEROP_MIXED_NAME).dll&quot; &quot;$(INTEROP_KEY_FILE)&quot;"
			/>
		</Configuration>
		<Configuration
			Name="Debug|x64"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="false"
				ExceptionHandling="0"
				BasicRuntimeChecks="0"
				RuntimeLibrary="3"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions="$(INTEROP_ASSEMBLY_RESOURCES)"
				AdditionalDependencies="$(ProjectDir)..\bin\$(ConfigurationYear)\$(ConfigurationName)Module\bin\System.Data.SQLite.netmodule"
				OutputFile="$(OutDir)\$(INTEROP_MIXED_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				AssemblyDebug="1"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_MIXED_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				LinkTimeCodeGeneration="1"
				ImportLibrary="$(TargetDir)$(INTEROP_MIXED_NAME).lib"
				TargetMachine="17"
				KeyFile="$(INTEROP_KEY_FILE)"
				DelaySign="true"
				CLRUnmanagedCodeCheck="true"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_MIXED_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="&quot;$(FrameworkSDKDir)Bin\sn.exe&quot; -Ra &quot;$(OutDir)\$(INTEROP_MIXED_NAME).dll&quot; &quot;$(INTEROP_KEY_FILE)&quot;"
			/>
		</Configuration>
		<Configuration
			Name="DebugNativeOnly|Win32"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="false"
				ExceptionHandling="0"
				BasicRuntimeChecks="0"
				RuntimeLibrary="3"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)\$(INTEROP_NATIVE_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				AssemblyDebug="1"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_NATIVE_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(TargetDir)$(INTEROP_NATIVE_NAME).lib"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_NATIVE_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="IF /I &quot;%PROCESSOR_ARCHITECTURE%&quot; == &quot;x86&quot; IF /I &quot;%PROCESSOR_ARCHITEW6432%&quot; == &quot;&quot; XCOPY &quot;$(TargetPath)&quot; &quot;$(OutDir)..\..\..\Debug\bin\&quot; /D /E /V /I /F /H /Y"
			/>
		</Configuration>
		<Configuration
			Name="DebugNativeOnly|x64"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="false"
				ExceptionHandling="0"
				BasicRuntimeChecks="0"
				RuntimeLibrary="3"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)\$(INTEROP_NATIVE_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				AssemblyDebug="1"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_NATIVE_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(TargetDir)$(INTEROP_NATIVE_NAME).lib"
				TargetMachine="17"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_NATIVE_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="IF /I &quot;%PROCESSOR_ARCHITECTURE%&quot; == &quot;x86&quot; IF /I &quot;%PROCESSOR_ARCHITEW6432%&quot; == &quot;AMD64&quot; XCOPY &quot;$(TargetPath)&quot; &quot;$(OutDir)..\..\..\Debug\bin\&quot; /D /E /V /I /F /H /Y"
			/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="3"
				EnableIntrinsicFunctions="true"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="2"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions="$(INTEROP_ASSEMBLY_RESOURCES)"
				AdditionalDependencies="$(ProjectDir)..\bin\$(ConfigurationYear)\$(ConfigurationName)Module\bin\System.Data.SQLite.netmodule"
				OutputFile="$(OutDir)\$(INTEROP_MIXED_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_MIXED_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				LargeAddressAware="0"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				LinkTimeCodeGeneration="1"
				ImportLibrary="$(TargetDir)$(INTEROP_MIXED_NAME).lib"
				TargetMachine="1"
				KeyFile="$(INTEROP_KEY_FILE)"
				DelaySign="true"
				CLRUnmanagedCodeCheck="true"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_MIXED_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="&quot;$(FrameworkSDKDir)Bin\sn.exe&quot; -Ra &quot;$(OutDir)\$(INTEROP_MIXED_NAME).dll&quot; &quot;$(INTEROP_KEY_FILE)&quot;"
			/>
		</Configuration>
		<Configuration
			Name="Release|x64"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="3"
				EnableIntrinsicFunctions="true"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="2"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions="$(INTEROP_ASSEMBLY_RESOURCES)"
				AdditionalDependencies="$(ProjectDir)..\bin\$(ConfigurationYear)\$(ConfigurationName)Module\bin\System.Data.SQLite.netmodule"
				OutputFile="$(OutDir)\$(INTEROP_MIXED_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_MIXED_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				LargeAddressAware="0"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				LinkTimeCodeGeneration="1"
				ImportLibrary="$(TargetDir)$(INTEROP_MIXED_NAME).lib"
				TargetMachine="17"
				KeyFile="$(INTEROP_KEY_FILE)"
				DelaySign="true"
				CLRUnmanagedCodeCheck="true"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_MIXED_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="&quot;$(FrameworkSDKDir)Bin\sn.exe&quot; -Ra &quot;$(OutDir)\$(INTEROP_MIXED_NAME).dll&quot; &quot;$(INTEROP_KEY_FILE)&quot;"
			/>
		</Configuration>
		<Configuration
			Name="ReleaseNativeOnly|Win32"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="3"
				EnableIntrinsicFunctions="true"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="2"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)\$(INTEROP_NATIVE_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_NATIVE_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				LargeAddressAware="0"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(TargetDir)$(INTEROP_NATIVE_NAME).lib"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_NATIVE_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="IF /I &quot;%PROCESSOR_ARCHITECTURE%&quot; == &quot;x86&quot; IF /I &quot;%PROCESSOR_ARCHITEW6432%&quot; == &quot;&quot; XCOPY &quot;$(TargetPath)&quot; &quot;$(OutDir)..\..\..\Release\bin\&quot; /D /E /V /I /F /H /Y"
			/>
		</Configuration>
		<Configuration
			Name="ReleaseNativeOnly|x64"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="3"
				EnableIntrinsicFunctions="true"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="2"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)\$(INTEROP_NATIVE_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_NATIVE_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				LargeAddressAware="0"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(TargetDir)$(INTEROP_NATIVE_NAME).lib"
				TargetMachine="17"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_NATIVE_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="IF /I &quot;%PROCESSOR_ARCHITECTURE%&quot; == &quot;x86&quot; IF /I &quot;%PROCESSOR_ARCHITEW6432%&quot; == &quot;AMD64&quot; XCOPY &quot;$(TargetPath)&quot; &quot;$(OutDir)..\..\..\Release\bin\&quot; /D /E /V /I /F /H /Y"
			/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
			>
			<File
				RelativePath=".\src\win\AssemblyInfo.cpp"
				>
				<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\win\crypt.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\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\win\interop.c"
				>
			</File>
			<File
				RelativePath=".\src\core\sqlite3.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>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
			>
			<File
				RelativePath=".\src\core\sqlite3.h"
				>
			</File>
			<File
				RelativePath=".\src\core\sqlite3ext.h"
				>
			</File>
			<File
				RelativePath=".\src\win\interop.h"
				>
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
			>
			<File
				RelativePath=".\src\win\SQLite.Interop.rc"
				>
			</File>
			<File
				RelativePath="..\System.Data.SQLite\SR.resx"
				>
				<FileConfiguration
					Name="Debug|Win32"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
						ResourceFileName="$(IntDir)\$(INTEROP_MIXED_NAME).$(InputName).resources"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
						ResourceFileName="$(IntDir)\$(INTEROP_MIXED_NAME).$(InputName).resources"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
						ResourceFileName="$(IntDir)\$(INTEROP_MIXED_NAME).$(InputName).resources"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
						ResourceFileName="$(IntDir)\$(INTEROP_MIXED_NAME).$(InputName).resources"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
					/>
				</FileConfiguration>
			</File>
		</Filter>
		<Filter
			Name="Property Files"
			>
			<File
				RelativePath=".\props\SQLite.Interop.vsprops"
				>
			</File>
			<File
				RelativePath=".\props\sqlite3.vsprops"
				>
			</File>
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/SQLite.Interop.2010.vcxproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.2010.vcxproj -
 *
 * 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">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="DebugNativeOnly|x64">
      <Configuration>DebugNativeOnly</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="DebugNativeOnly|Win32">
      <Configuration>DebugNativeOnly</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="ReleaseNativeOnly|x64">
      <Configuration>ReleaseNativeOnly</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="ReleaseNativeOnly|Win32">
      <Configuration>ReleaseNativeOnly</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectName>SQLite.Interop.2010</ProjectName>
    <ProjectGuid>{53784BC1-A8BC-4AC8-8A3E-158D6807345A}</ProjectGuid>
    <RootNamespace>SQLite.Interop</RootNamespace>
    <Keyword>Win32Proj</Keyword>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="props\sqlite3.props" />
  <Import Project="props\SQLite.Interop.props" />
  <PropertyGroup Condition="('$(Configuration)' == 'DebugNativeOnly' Or
                             '$(Configuration)' == 'ReleaseNativeOnly') And
                            (('$(Platform)' == 'Win32' And
                             ('$(PROCESSOR_ARCHITECTURE)' != 'x86' Or
                              '$(PROCESSOR_ARCHITEW6432)' != '')) Or
                             ('$(Platform)' == 'x64' And
                             ('$(PROCESSOR_ARCHITECTURE)' != 'x86' Or
                              '$(PROCESSOR_ARCHITEW6432)' != 'AMD64')))"
                 Label="PostBuildEvent">
    <PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <TargetName>$(INTEROP_MIXED_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <TargetName>$(INTEROP_MIXED_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|Win32'" Label="Configuration">
    <TargetName>$(INTEROP_NATIVE_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|x64'" Label="Configuration">
    <TargetName>$(INTEROP_NATIVE_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <TargetName>$(INTEROP_MIXED_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <TargetName>$(INTEROP_MIXED_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|Win32'" Label="Configuration">
    <TargetName>$(INTEROP_NATIVE_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|x64'" Label="Configuration">
    <TargetName>$(INTEROP_NATIVE_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  <PropertyGroup>
    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
    <OutDir>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Platform)\$(Configuration)\</OutDir>
    <IntDir>..\obj\$(ConfigurationYear)\$(Platform)\$(Configuration)\</IntDir>
    <LinkIncremental>false</LinkIncremental>
    <LinkKeyFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(INTEROP_KEY_FILE)</LinkKeyFile>
    <LinkKeyFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(INTEROP_KEY_FILE)</LinkKeyFile>
    <LinkKeyFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(INTEROP_KEY_FILE)</LinkKeyFile>
    <LinkKeyFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(INTEROP_KEY_FILE)</LinkKeyFile>
    <LinkDelaySign Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkDelaySign>
    <LinkDelaySign Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkDelaySign>
    <LinkDelaySign Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkDelaySign>
    <LinkDelaySign Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkDelaySign>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <AdditionalOptions>$(INTEROP_ASSEMBLY_RESOURCES) %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Configuration)Module\bin\System.Data.SQLite.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AssemblyDebug>true</AssemblyDebug>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
      <TargetMachine>MachineX86</TargetMachine>
      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
      <KeyFile>$(INTEROP_KEY_FILE)</KeyFile>
      <DelaySign>true</DelaySign>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>"$(FrameworkSDKDir)Bin\sn.exe" -Ra "$(TargetPath)" "$(INTEROP_KEY_FILE)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <AdditionalOptions>$(INTEROP_ASSEMBLY_RESOURCES) %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Configuration)Module\bin\System.Data.SQLite.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AssemblyDebug>true</AssemblyDebug>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
      <TargetMachine>MachineX64</TargetMachine>
      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
      <KeyFile>$(INTEROP_KEY_FILE)</KeyFile>
      <DelaySign>true</DelaySign>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>"$(FrameworkSDKDir)Bin\sn.exe" -Ra "$(TargetPath)" "$(INTEROP_KEY_FILE)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|Win32'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX86</TargetMachine>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|x64'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX64</TargetMachine>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <Optimization>Full</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <StringPooling>true</StringPooling>
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <AdditionalOptions>$(INTEROP_ASSEMBLY_RESOURCES) %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Configuration)Module\bin\System.Data.SQLite.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
      <TargetMachine>MachineX86</TargetMachine>
      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
      <KeyFile>$(INTEROP_KEY_FILE)</KeyFile>
      <DelaySign>true</DelaySign>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>"$(FrameworkSDKDir)Bin\sn.exe" -Ra "$(TargetPath)" "$(INTEROP_KEY_FILE)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <Optimization>Full</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <PreprocessorDefinitions>WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <StringPooling>true</StringPooling>
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <AdditionalOptions>$(INTEROP_ASSEMBLY_RESOURCES) %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Configuration)Module\bin\System.Data.SQLite.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
      <TargetMachine>MachineX64</TargetMachine>
      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
      <KeyFile>$(INTEROP_KEY_FILE)</KeyFile>
      <DelaySign>true</DelaySign>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>"$(FrameworkSDKDir)Bin\sn.exe" -Ra "$(TargetPath)" "$(INTEROP_KEY_FILE)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|Win32'">
    <ClCompile>
      <Optimization>Full</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <StringPooling>true</StringPooling>
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX86</TargetMachine>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|x64'">
    <ClCompile>
      <Optimization>Full</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <PreprocessorDefinitions>WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <StringPooling>true</StringPooling>
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX64</TargetMachine>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="src\win\AssemblyInfo.cpp">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </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\win\interop.c" />
    <ClCompile Include="src\core\sqlite3.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <None Include="props\SQLite.Interop.props" />
    <None Include="props\sqlite3.props" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="src\core\sqlite3.h" />
    <ClInclude Include="src\core\sqlite3ext.h" />
    <ClInclude Include="src\win\interop.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="src\win\SQLite.Interop.rc" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="..\System.Data.SQLite\SR.resx">
      <LogicalName>System.Data.SQLite.%(Filename).resources</LogicalName>
      <SubType>Designer</SubType>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|Win32'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|x64'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|Win32'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|x64'">true</ExcludedFromBuild>
    </EmbeddedResource>
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/SQLite.Interop.2010.vcxproj.filters.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.2010.vcxproj.filters -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
    </Filter>
    <Filter Include="Resource Files">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
    </Filter>
    <Filter Include="Property Files">
      <UniqueIdentifier>{d69d5c95-1d03-4325-ad06-fce223ab4e42}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="src\win\AssemblyInfo.cpp">
      <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\win\interop.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\sqlite3.c">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <None Include="props\sqlite3.props">
      <Filter>Property Files</Filter>
    </None>
    <None Include="props\SQLite.Interop.props">
      <Filter>Property Files</Filter>
    </None>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="src\core\sqlite3.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\core\sqlite3ext.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\win\interop.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="src\win\SQLite.Interop.rc">
      <Filter>Resource Files</Filter>
    </ResourceCompile>
    <EmbeddedResource Include="..\System.Data.SQLite\SR.resx">
      <Filter>Resource Files</Filter>
    </EmbeddedResource>
  </ItemGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































Deleted SQLite.Interop/SQLite.Interop.CE.2008.vcproj.
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
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="9.00"
	Name="SQLite.Interop.CE.2008"
	ProjectGUID="{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}"
	Keyword="Win32Proj"
	TargetFrameworkVersion="196613"
	>
	<Platforms>
		<Platform
			Name="Pocket PC 2003 (ARMV4)"
		/>
		<Platform
			Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
		/>
		<Platform
			Name="Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Debug|Pocket PC 2003 (ARMV4)"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="1"
			/>
			<Tool
				Name="VCCLCompilerTool"
				ExecutionBucket="7"
				Optimization="0"
				PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_WINDOWS;_USRDLL;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;$(SQLITE_WINCE_DEFINES);$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="true"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				DebugInformationFormat="3"
				CompileAs="1"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
				Culture="1033"
				AdditionalIncludeDirectories="$(IntDir)"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions=" /subsystem:windowsce,4.20 /machine:ARM /ARMPADCODE"
				AdditionalDependencies="secchk.lib"
				OutputFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="2"
				GenerateManifest="true"
				DelayLoadDLLs="$(NOINHERIT)"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).pdb"
				GenerateMapFile="true"
				SubSystem="0"
				StackReserveSize="65536"
				StackCommitSize="4096"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				ImportLibrary="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).lib"
				TargetMachine="0"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCCodeSignTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
			<DeploymentTool
				ForceDirty="-1"
				RemoteDirectory="%CSIDL_PROGRAM_FILES%\testce"
				RegisterOutput="0"
				AdditionalFiles=""
			/>
			<DebuggerTool
			/>
		</Configuration>
		<Configuration
			Name="Release|Pocket PC 2003 (ARMV4)"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="1"
			/>
			<Tool
				Name="VCCLCompilerTool"
				ExecutionBucket="7"
				Optimization="2"
				FavorSizeOrSpeed="2"
				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_WINDOWS;_USRDLL;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;$(SQLITE_WINCE_DEFINES);$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				RuntimeLibrary="0"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				DebugInformationFormat="3"
				CompileAs="1"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
				Culture="1033"
				AdditionalIncludeDirectories="$(IntDir)"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions=" /subsystem:windowsce,4.20 /machine:ARM /ARMPADCODE"
				AdditionalDependencies="secchk.lib"
				OutputFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateManifest="true"
				DelayLoadDLLs="$(NOINHERIT)"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).pdb"
				GenerateMapFile="true"
				SubSystem="0"
				StackReserveSize="65536"
				StackCommitSize="4096"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				ImportLibrary="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).lib"
				TargetMachine="0"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCCodeSignTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
			<DeploymentTool
				ForceDirty="-1"
				RemoteDirectory="%CSIDL_PROGRAM_FILES%\testce"
				RegisterOutput="0"
				AdditionalFiles=""
			/>
			<DebuggerTool
			/>
		</Configuration>
		<Configuration
			Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				ExecutionBucket="7"
				Optimization="0"
				PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_WINDOWS;_USRDLL;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;$(SQLITE_WINCE_DEFINES);$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="true"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				DebugInformationFormat="3"
				CompileAs="1"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
				Culture="1033"
				AdditionalIncludeDirectories="$(IntDir)"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions=" /subsystem:windowsce,5.01"
				OutputFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="2"
				GenerateManifest="true"
				DelayLoadDLLs="$(NOINHERIT)"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).pdb"
				GenerateMapFile="true"
				SubSystem="0"
				StackReserveSize="65536"
				StackCommitSize="4096"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				ImportLibrary="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).lib"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCCodeSignTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
			<DeploymentTool
				ForceDirty="-1"
				RemoteDirectory="%CSIDL_PROGRAM_FILES%\testce"
				RegisterOutput="0"
				AdditionalFiles=""
			/>
			<DebuggerTool
			/>
		</Configuration>
		<Configuration
			Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				ExecutionBucket="7"
				Optimization="0"
				PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_WINDOWS;_USRDLL;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;$(SQLITE_WINCE_DEFINES);$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="true"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				DebugInformationFormat="3"
				CompileAs="1"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
				Culture="1033"
				AdditionalIncludeDirectories="$(IntDir)"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions=" /subsystem:windowsce,5.01"
				OutputFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="2"
				GenerateManifest="true"
				DelayLoadDLLs="$(NOINHERIT)"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).pdb"
				GenerateMapFile="true"
				SubSystem="0"
				StackReserveSize="65536"
				StackCommitSize="4096"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				ImportLibrary="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).lib"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCCodeSignTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
			<DeploymentTool
				ForceDirty="-1"
				RemoteDirectory="%CSIDL_PROGRAM_FILES%\testce"
				RegisterOutput="0"
				AdditionalFiles=""
			/>
			<DebuggerTool
			/>
		</Configuration>
		<Configuration
			Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				ExecutionBucket="7"
				Optimization="2"
				FavorSizeOrSpeed="2"
				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_WINDOWS;_USRDLL;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;$(SQLITE_WINCE_DEFINES);$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				RuntimeLibrary="0"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				DebugInformationFormat="3"
				CompileAs="1"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
				Culture="1033"
				AdditionalIncludeDirectories="$(IntDir)"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions=" /subsystem:windowsce,5.01"
				OutputFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateManifest="true"
				DelayLoadDLLs="$(NOINHERIT)"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).pdb"
				GenerateMapFile="true"
				SubSystem="0"
				StackReserveSize="65536"
				StackCommitSize="4096"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				ImportLibrary="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).lib"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCCodeSignTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
			<DeploymentTool
				ForceDirty="-1"
				RemoteDirectory="%CSIDL_PROGRAM_FILES%\testce"
				RegisterOutput="0"
				AdditionalFiles=""
			/>
			<DebuggerTool
			/>
		</Configuration>
		<Configuration
			Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				ExecutionBucket="7"
				Optimization="2"
				FavorSizeOrSpeed="2"
				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_WINDOWS;_USRDLL;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;$(SQLITE_WINCE_DEFINES);$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				RuntimeLibrary="0"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				DebugInformationFormat="3"
				CompileAs="1"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
				Culture="1033"
				AdditionalIncludeDirectories="$(IntDir)"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions=" /subsystem:windowsce,5.01"
				OutputFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateManifest="true"
				DelayLoadDLLs="$(NOINHERIT)"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).pdb"
				GenerateMapFile="true"
				SubSystem="0"
				StackReserveSize="65536"
				StackCommitSize="4096"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				ImportLibrary="$(OutDir)/SQLite.Interop.$(INTEROP_BUILD_NUMBER).lib"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCCodeSignTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
			<DeploymentTool
				ForceDirty="-1"
				RemoteDirectory="%CSIDL_PROGRAM_FILES%\testce"
				RegisterOutput="0"
				AdditionalFiles=""
			/>
			<DebuggerTool
			/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
			>
			<File
				RelativePath=".\src\win\AssemblyInfo.cpp"
				>
				<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\win\crypt.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\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\win\interop.c"
				>
			</File>
			<File
				RelativePath=".\src\core\sqlite3.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>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
			>
			<File
				RelativePath=".\src\win\interop.h"
				>
			</File>
			<File
				RelativePath=".\src\core\sqlite3.h"
				>
			</File>
			<File
				RelativePath=".\src\core\sqlite3ext.h"
				>
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
			>
			<File
				RelativePath=".\src\win\SQLite.Interop.rc"
				>
			</File>
		</Filter>
		<Filter
			Name="Property Files"
			>
			<File
				RelativePath=".\props\SQLite.Interop.vsprops"
				>
			</File>
			<File
				RelativePath=".\props\sqlite3.vsprops"
				>
			</File>
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/SQLite.Interop.Static.2008.vcproj.
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
<?xml version="1.0" encoding="Windows-1252"?>
<!--
 *
 * SQLite.Interop.Static.2008.vcproj -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<VisualStudioProject
	ProjectType="Visual C++"
	Version="9.00"
	Name="SQLite.Interop.Static.2008"
	ProjectGUID="{490CBC51-A3B2-4397-89F9-16E858DCB4F8}"
	RootNamespace="SQLite.Interop"
	Keyword="Win32Proj"
	TargetFrameworkVersion="131072"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>
		<Platform
			Name="x64"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="false"
				ExceptionHandling="0"
				BasicRuntimeChecks="0"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions="$(INTEROP_ASSEMBLY_RESOURCES)"
				AdditionalDependencies="$(ProjectDir)..\bin\$(ConfigurationYear)\$(ConfigurationName)Module\bin\System.Data.SQLite.netmodule"
				OutputFile="$(OutDir)\$(INTEROP_MIXED_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				AssemblyDebug="1"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_MIXED_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				LinkTimeCodeGeneration="1"
				ImportLibrary="$(TargetDir)$(INTEROP_MIXED_NAME).lib"
				TargetMachine="1"
				KeyFile="$(INTEROP_KEY_FILE)"
				DelaySign="true"
				CLRUnmanagedCodeCheck="true"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_MIXED_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="&quot;$(FrameworkSDKDir)Bin\sn.exe&quot; -Ra &quot;$(OutDir)\$(INTEROP_MIXED_NAME).dll&quot; &quot;$(INTEROP_KEY_FILE)&quot;"
			/>
		</Configuration>
		<Configuration
			Name="Debug|x64"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="false"
				ExceptionHandling="0"
				BasicRuntimeChecks="0"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions="$(INTEROP_ASSEMBLY_RESOURCES)"
				AdditionalDependencies="$(ProjectDir)..\bin\$(ConfigurationYear)\$(ConfigurationName)Module\bin\System.Data.SQLite.netmodule"
				OutputFile="$(OutDir)\$(INTEROP_MIXED_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				AssemblyDebug="1"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_MIXED_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				LinkTimeCodeGeneration="1"
				ImportLibrary="$(TargetDir)$(INTEROP_MIXED_NAME).lib"
				TargetMachine="17"
				KeyFile="$(INTEROP_KEY_FILE)"
				DelaySign="true"
				CLRUnmanagedCodeCheck="true"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_MIXED_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="&quot;$(FrameworkSDKDir)Bin\sn.exe&quot; -Ra &quot;$(OutDir)\$(INTEROP_MIXED_NAME).dll&quot; &quot;$(INTEROP_KEY_FILE)&quot;"
			/>
		</Configuration>
		<Configuration
			Name="DebugNativeOnly|Win32"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="false"
				ExceptionHandling="0"
				BasicRuntimeChecks="0"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)\$(INTEROP_NATIVE_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				AssemblyDebug="1"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_NATIVE_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(TargetDir)$(INTEROP_NATIVE_NAME).lib"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_NATIVE_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="IF /I &quot;%PROCESSOR_ARCHITECTURE%&quot; == &quot;x86&quot; IF /I &quot;%PROCESSOR_ARCHITEW6432%&quot; == &quot;&quot; XCOPY &quot;$(TargetPath)&quot; &quot;$(OutDir)..\..\..\Debug\bin\&quot; /D /E /V /I /F /H /Y"
			/>
		</Configuration>
		<Configuration
			Name="DebugNativeOnly|x64"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES)"
				MinimalRebuild="false"
				ExceptionHandling="0"
				BasicRuntimeChecks="0"
				RuntimeLibrary="1"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="_DEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)\$(INTEROP_NATIVE_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				AssemblyDebug="1"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_NATIVE_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(TargetDir)$(INTEROP_NATIVE_NAME).lib"
				TargetMachine="17"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_NATIVE_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="IF /I &quot;%PROCESSOR_ARCHITECTURE%&quot; == &quot;x86&quot; IF /I &quot;%PROCESSOR_ARCHITEW6432%&quot; == &quot;AMD64&quot; XCOPY &quot;$(TargetPath)&quot; &quot;$(OutDir)..\..\..\Debug\bin\&quot; /D /E /V /I /F /H /Y"
			/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="3"
				EnableIntrinsicFunctions="true"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="0"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions="$(INTEROP_ASSEMBLY_RESOURCES)"
				AdditionalDependencies="$(ProjectDir)..\bin\$(ConfigurationYear)\$(ConfigurationName)Module\bin\System.Data.SQLite.netmodule"
				OutputFile="$(OutDir)\$(INTEROP_MIXED_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_MIXED_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				LargeAddressAware="0"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				LinkTimeCodeGeneration="1"
				ImportLibrary="$(TargetDir)$(INTEROP_MIXED_NAME).lib"
				TargetMachine="1"
				KeyFile="$(INTEROP_KEY_FILE)"
				DelaySign="true"
				CLRUnmanagedCodeCheck="true"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_MIXED_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="&quot;$(FrameworkSDKDir)Bin\sn.exe&quot; -Ra &quot;$(OutDir)\$(INTEROP_MIXED_NAME).dll&quot; &quot;$(INTEROP_KEY_FILE)&quot;"
			/>
		</Configuration>
		<Configuration
			Name="Release|x64"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="3"
				EnableIntrinsicFunctions="true"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="0"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalOptions="$(INTEROP_ASSEMBLY_RESOURCES)"
				AdditionalDependencies="$(ProjectDir)..\bin\$(ConfigurationYear)\$(ConfigurationName)Module\bin\System.Data.SQLite.netmodule"
				OutputFile="$(OutDir)\$(INTEROP_MIXED_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_MIXED_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				LargeAddressAware="0"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				LinkTimeCodeGeneration="1"
				ImportLibrary="$(TargetDir)$(INTEROP_MIXED_NAME).lib"
				TargetMachine="17"
				KeyFile="$(INTEROP_KEY_FILE)"
				DelaySign="true"
				CLRUnmanagedCodeCheck="true"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_MIXED_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="&quot;$(FrameworkSDKDir)Bin\sn.exe&quot; -Ra &quot;$(OutDir)\$(INTEROP_MIXED_NAME).dll&quot; &quot;$(INTEROP_KEY_FILE)&quot;"
			/>
		</Configuration>
		<Configuration
			Name="ReleaseNativeOnly|Win32"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="3"
				EnableIntrinsicFunctions="true"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="0"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)\$(INTEROP_NATIVE_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_NATIVE_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				LargeAddressAware="0"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(TargetDir)$(INTEROP_NATIVE_NAME).lib"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_NATIVE_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="IF /I &quot;%PROCESSOR_ARCHITECTURE%&quot; == &quot;x86&quot; IF /I &quot;%PROCESSOR_ARCHITEW6432%&quot; == &quot;&quot; XCOPY &quot;$(TargetPath)&quot; &quot;$(OutDir)..\..\..\Release\bin\&quot; /D /E /V /I /F /H /Y"
			/>
		</Configuration>
		<Configuration
			Name="ReleaseNativeOnly|x64"
			OutputDirectory="$(ProjectDir)..\bin\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			IntermediateDirectory="..\obj\$(ConfigurationYear)\$(PlatformName)\$(ConfigurationName)Static"
			ConfigurationType="2"
			InheritedPropertySheets=".\props\sqlite3.vsprops;.\props\SQLite.Interop.vsprops"
			CharacterSet="1"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="3"
				EnableIntrinsicFunctions="true"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES)"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="0"
				UsePrecompiledHeader="0"
				WarningLevel="4"
				DebugInformationFormat="3"
				CompileAs="0"
				DisableSpecificWarnings="$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS)"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;&quot;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION)&quot;"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)\$(INTEROP_NATIVE_NAME).dll"
				Version="$(INTEROP_MANIFEST_VERSION)"
				LinkIncremental="1"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(TargetDir)$(INTEROP_NATIVE_NAME).pdb"
				GenerateMapFile="true"
				MapExports="true"
				SubSystem="2"
				LargeAddressAware="0"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(TargetDir)$(INTEROP_NATIVE_NAME).lib"
				TargetMachine="17"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				VerboseOutput="true"
				AssemblyIdentity="$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32"
				UpdateFileHashes="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
				OutputFile="$(OutDir)/$(INTEROP_NATIVE_NAME).bsc"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine="IF /I &quot;%PROCESSOR_ARCHITECTURE%&quot; == &quot;x86&quot; IF /I &quot;%PROCESSOR_ARCHITEW6432%&quot; == &quot;AMD64&quot; XCOPY &quot;$(TargetPath)&quot; &quot;$(OutDir)..\..\..\Release\bin\&quot; /D /E /V /I /F /H /Y"
			/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
			>
			<File
				RelativePath=".\src\win\AssemblyInfo.cpp"
				>
				<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\win\crypt.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\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\win\interop.c"
				>
			</File>
			<File
				RelativePath=".\src\core\sqlite3.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>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
			>
			<File
				RelativePath=".\src\core\sqlite3.h"
				>
			</File>
			<File
				RelativePath=".\src\core\sqlite3ext.h"
				>
			</File>
			<File
				RelativePath=".\src\win\interop.h"
				>
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
			>
			<File
				RelativePath=".\src\win\SQLite.Interop.rc"
				>
			</File>
			<File
				RelativePath="..\System.Data.SQLite\SR.resx"
				>
				<FileConfiguration
					Name="Debug|Win32"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
						ResourceFileName="$(IntDir)\$(INTEROP_MIXED_NAME).$(InputName).resources"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
						ResourceFileName="$(IntDir)\$(INTEROP_MIXED_NAME).$(InputName).resources"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
						ResourceFileName="$(IntDir)\$(INTEROP_MIXED_NAME).$(InputName).resources"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
						ResourceFileName="$(IntDir)\$(INTEROP_MIXED_NAME).$(InputName).resources"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCManagedResourceCompilerTool"
					/>
				</FileConfiguration>
			</File>
		</Filter>
		<Filter
			Name="Property Files"
			>
			<File
				RelativePath=".\props\SQLite.Interop.vsprops"
				>
			</File>
			<File
				RelativePath=".\props\sqlite3.vsprops"
				>
			</File>
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.Static.2010.vcxproj -
 *
 * 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">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="DebugNativeOnly|x64">
      <Configuration>DebugNativeOnly</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="DebugNativeOnly|Win32">
      <Configuration>DebugNativeOnly</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="ReleaseNativeOnly|x64">
      <Configuration>ReleaseNativeOnly</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="ReleaseNativeOnly|Win32">
      <Configuration>ReleaseNativeOnly</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectName>SQLite.Interop.Static.2010</ProjectName>
    <ProjectGuid>{490CBC51-A3B2-4397-89F9-16E858DCB4F8}</ProjectGuid>
    <RootNamespace>SQLite.Interop</RootNamespace>
    <Keyword>Win32Proj</Keyword>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <Import Project="props\sqlite3.props" />
  <Import Project="props\SQLite.Interop.props" />
  <PropertyGroup Condition="('$(Configuration)' == 'DebugNativeOnly' Or
                             '$(Configuration)' == 'ReleaseNativeOnly') And
                            (('$(Platform)' == 'Win32' And
                             ('$(PROCESSOR_ARCHITECTURE)' != 'x86' Or
                              '$(PROCESSOR_ARCHITEW6432)' != '')) Or
                             ('$(Platform)' == 'x64' And
                             ('$(PROCESSOR_ARCHITECTURE)' != 'x86' Or
                              '$(PROCESSOR_ARCHITEW6432)' != 'AMD64')))"
                 Label="PostBuildEvent">
    <PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <TargetName>$(INTEROP_MIXED_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <TargetName>$(INTEROP_MIXED_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|Win32'" Label="Configuration">
    <TargetName>$(INTEROP_NATIVE_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|x64'" Label="Configuration">
    <TargetName>$(INTEROP_NATIVE_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <TargetName>$(INTEROP_MIXED_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <TargetName>$(INTEROP_MIXED_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|Win32'" Label="Configuration">
    <TargetName>$(INTEROP_NATIVE_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|x64'" Label="Configuration">
    <TargetName>$(INTEROP_NATIVE_NAME)</TargetName>
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>Unicode</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  <PropertyGroup>
    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
    <OutDir>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Platform)\$(Configuration)Static\</OutDir>
    <IntDir>..\obj\$(ConfigurationYear)\$(Platform)\$(Configuration)Static\</IntDir>
    <LinkIncremental>false</LinkIncremental>
    <LinkKeyFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(INTEROP_KEY_FILE)</LinkKeyFile>
    <LinkKeyFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(INTEROP_KEY_FILE)</LinkKeyFile>
    <LinkKeyFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(INTEROP_KEY_FILE)</LinkKeyFile>
    <LinkKeyFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(INTEROP_KEY_FILE)</LinkKeyFile>
    <LinkDelaySign Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkDelaySign>
    <LinkDelaySign Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkDelaySign>
    <LinkDelaySign Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkDelaySign>
    <LinkDelaySign Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkDelaySign>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <AdditionalOptions>$(INTEROP_ASSEMBLY_RESOURCES) %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Configuration)Module\bin\System.Data.SQLite.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AssemblyDebug>true</AssemblyDebug>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
      <TargetMachine>MachineX86</TargetMachine>
      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
      <KeyFile>$(INTEROP_KEY_FILE)</KeyFile>
      <DelaySign>true</DelaySign>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>"$(FrameworkSDKDir)Bin\sn.exe" -Ra "$(TargetPath)" "$(INTEROP_KEY_FILE)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <AdditionalOptions>$(INTEROP_ASSEMBLY_RESOURCES) %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Configuration)Module\bin\System.Data.SQLite.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AssemblyDebug>true</AssemblyDebug>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
      <TargetMachine>MachineX64</TargetMachine>
      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
      <KeyFile>$(INTEROP_KEY_FILE)</KeyFile>
      <DelaySign>true</DelaySign>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>"$(FrameworkSDKDir)Bin\sn.exe" -Ra "$(TargetPath)" "$(INTEROP_KEY_FILE)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|Win32'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX86</TargetMachine>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|x64'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX64</TargetMachine>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <Optimization>Full</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <StringPooling>true</StringPooling>
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <AdditionalOptions>$(INTEROP_ASSEMBLY_RESOURCES) %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Configuration)Module\bin\System.Data.SQLite.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
      <TargetMachine>MachineX86</TargetMachine>
      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
      <KeyFile>$(INTEROP_KEY_FILE)</KeyFile>
      <DelaySign>true</DelaySign>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>"$(FrameworkSDKDir)Bin\sn.exe" -Ra "$(TargetPath)" "$(INTEROP_KEY_FILE)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <Optimization>Full</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <PreprocessorDefinitions>WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <StringPooling>true</StringPooling>
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <AdditionalOptions>$(INTEROP_ASSEMBLY_RESOURCES) %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>$(ProjectDir)..\bin\$(ConfigurationYear)\$(Configuration)Module\bin\System.Data.SQLite.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
      <TargetMachine>MachineX64</TargetMachine>
      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
      <KeyFile>$(INTEROP_KEY_FILE)</KeyFile>
      <DelaySign>true</DelaySign>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>"$(FrameworkSDKDir)Bin\sn.exe" -Ra "$(TargetPath)" "$(INTEROP_KEY_FILE)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|Win32'">
    <ClCompile>
      <Optimization>Full</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <StringPooling>true</StringPooling>
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX86</TargetMachine>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|x64'">
    <ClCompile>
      <Optimization>Full</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <PreprocessorDefinitions>WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <StringPooling>true</StringPooling>
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
      <WarningLevel>Level4</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <CompileAs>Default</CompileAs>
      <DisableSpecificWarnings>$(SQLITE_DISABLE_WARNINGS);$(SQLITE_DISABLE_X64_WARNINGS);%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;INTEROP_RC_VERSION=$(INTEROP_RC_VERSION);%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <Version>$(INTEROP_MANIFEST_VERSION)</Version>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <GenerateMapFile>true</GenerateMapFile>
      <MapExports>true</MapExports>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX64</TargetMachine>
    </Link>
    <Manifest>
      <VerboseOutput>true</VerboseOutput>
      <AssemblyIdentity>$(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32</AssemblyIdentity>
      <UpdateFileHashes>true</UpdateFileHashes>
    </Manifest>
    <PostBuildEvent>
      <Command>XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="src\win\AssemblyInfo.cpp">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </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\win\interop.c" />
    <ClCompile Include="src\core\sqlite3.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <None Include="props\SQLite.Interop.props" />
    <None Include="props\sqlite3.props" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="src\core\sqlite3.h" />
    <ClInclude Include="src\core\sqlite3ext.h" />
    <ClInclude Include="src\win\interop.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="src\win\SQLite.Interop.rc" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="..\System.Data.SQLite\SR.resx">
      <LogicalName>System.Data.SQLite.%(Filename).resources</LogicalName>
      <SubType>Designer</SubType>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|Win32'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNativeOnly|x64'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|Win32'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseNativeOnly|x64'">true</ExcludedFromBuild>
    </EmbeddedResource>
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.filters.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.Static.2010.vcxproj.filters -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
    </Filter>
    <Filter Include="Resource Files">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
    </Filter>
    <Filter Include="Property Files">
      <UniqueIdentifier>{d69d5c95-1d03-4325-ad06-fce223ab4e42}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="src\win\AssemblyInfo.cpp">
      <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\win\interop.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\sqlite3.c">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <None Include="props\sqlite3.props">
      <Filter>Property Files</Filter>
    </None>
    <None Include="props\SQLite.Interop.props">
      <Filter>Property Files</Filter>
    </None>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="src\core\sqlite3.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\core\sqlite3ext.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\win\interop.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="src\win\SQLite.Interop.rc">
      <Filter>Resource Files</Filter>
    </ResourceCompile>
    <EmbeddedResource Include="..\System.Data.SQLite\SR.resx">
      <Filter>Resource Files</Filter>
    </EmbeddedResource>
  </ItemGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































Added SQLite.Interop/SQLite.Interop.vcproj.
























































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="8.00"
	Name="SQLite.Interop"
	ProjectGUID="{10B51CE8-A838-44DE-BD82-B658F0296F80}"
	RootNamespace="SQLite.Interop"
	Keyword="Win32Proj"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="Debug"
			IntermediateDirectory="Debug"
			ConfigurationType="2"
			CharacterSet="2"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE"
				StringPooling="true"
				ExceptionHandling="0"
				BasicRuntimeChecks="3"
				RuntimeLibrary="1"
				EnableFunctionLevelLinking="true"
				UsePrecompiledHeader="0"
				WarningLevel="1"
				DebugInformationFormat="3"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)/$(ProjectName).dll"
				LinkIncremental="1"
				GenerateManifest="false"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
				SubSystem="2"
				ImportLibrary="$(OutDir)/$(ProjectName).lib"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="Release"
			IntermediateDirectory="Release"
			ConfigurationType="2"
			CharacterSet="2"
			WholeProgramOptimization="0"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="2"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="0"
				BufferSecurityCheck="false"
				EnableFunctionLevelLinking="true"
				UsePrecompiledHeader="0"
				WarningLevel="1"
				DebugInformationFormat="0"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)/$(ProjectName).dll"
				LinkIncremental="1"
				GenerateManifest="false"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(OutDir)/$(ProjectName).lib"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
			>
			<File
				RelativePath=".\src\alter.c"
				>
			</File>
			<File
				RelativePath=".\src\attach.c"
				>
			</File>
			<File
				RelativePath=".\src\auth.c"
				>
			</File>
			<File
				RelativePath=".\src\btree.c"
				>
			</File>
			<File
				RelativePath=".\src\build.c"
				>
			</File>
			<File
				RelativePath=".\src\date.c"
				>
			</File>
			<File
				RelativePath=".\src\delete.c"
				>
			</File>
			<File
				RelativePath=".\src\expr.c"
				>
			</File>
			<File
				RelativePath=".\src\func.c"
				>
			</File>
			<File
				RelativePath=".\src\hash.c"
				>
			</File>
			<File
				RelativePath=".\src\insert.c"
				>
			</File>
			<File
				RelativePath=".\src\legacy.c"
				>
			</File>
			<File
				RelativePath=".\src\main.c"
				>
			</File>
			<File
				RelativePath=".\src\opcodes.c"
				>
			</File>
			<File
				RelativePath=".\src\os_unix.c"
				>
			</File>
			<File
				RelativePath=".\src\os_win.c"
				>
			</File>
			<File
				RelativePath=".\src\pager.c"
				>
			</File>
			<File
				RelativePath=".\src\parse.c"
				>
			</File>
			<File
				RelativePath=".\src\pragma.c"
				>
			</File>
			<File
				RelativePath=".\src\printf.c"
				>
			</File>
			<File
				RelativePath=".\src\random.c"
				>
			</File>
			<File
				RelativePath=".\src\select.c"
				>
			</File>
			<File
				RelativePath=".\src\table.c"
				>
			</File>
			<File
				RelativePath=".\src\tclsqlite.c"
				>
			</File>
			<File
				RelativePath=".\src\tokenize.c"
				>
			</File>
			<File
				RelativePath=".\src\trigger.c"
				>
			</File>
			<File
				RelativePath=".\src\update.c"
				>
			</File>
			<File
				RelativePath=".\src\utf.c"
				>
			</File>
			<File
				RelativePath=".\src\util.c"
				>
			</File>
			<File
				RelativePath=".\src\vacuum.c"
				>
			</File>
			<File
				RelativePath=".\src\vdbe.c"
				>
			</File>
			<File
				RelativePath=".\src\vdbeapi.c"
				>
			</File>
			<File
				RelativePath=".\src\vdbeaux.c"
				>
			</File>
			<File
				RelativePath=".\src\vdbemem.c"
				>
			</File>
			<File
				RelativePath=".\src\where.c"
				>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
			>
			<File
				RelativePath=".\interop.h"
				FileType="0"
				>
			</File>
			<File
				RelativePath=".\src\sqlite3.h"
				>
			</File>
		</Filter>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>
Added SQLite.Interop/interop.h.




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
   This interop file must be included at or near the top of the select.c file of the SQLite3 source distribution.

   generateColumnNames() in the select.c must be renamed to _generateColumnNames

*/
#include "os.h"
#include "sqliteint.h"

static void generateColumnTypes(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
);

static void _generateColumnNames(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
);

/*
** Generate code that will tell the VDBE the names of columns
** in the result set.  This information is used to provide the
** azCol[] values in the callback.
*/
static void generateColumnNames(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i, j;
  sqlite3 *db = pParse->db;
  int fullNames, shortNames;
  int realNames;                                     /*** ADDED - SQLite.Interop ***/

  realNames = (db->flags & 0x01000000)!=0;           /*** ADDED - SQLite.Interop ***/
  if (!realNames) // Default to normal Sqlite3       /*** ADDED - SQLite.Interop ***/
  {                                                  /*** ADDED - SQLite.Interop ***/
    _generateColumnNames(pParse, pTabList, pEList);  /*** ADDED - SQLite.Interop ***/
    return;                                          /*** ADDED - SQLite.Interop ***/
  }                                                  /*** ADDED - SQLite.Interop ***/

#ifndef SQLITE_OMIT_EXPLAIN
  /* If this is an EXPLAIN, skip this step */
  if( pParse->explain ){
    return;
  }
#endif

  assert( v!=0 );
  if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return;
  pParse->colNamesSet = 1;
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
  if (realNames) fullNames = 1;                      /*** ADDED - SQLite.Interop ***/

  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
    if( p==0 ) continue;
    if( pEList->a[i].zName && (realNames == 0 || p->op != TK_COLUMN)){   /*** CHANGED - SQLite.Interop ***/
      char *zName = pEList->a[i].zName;
      sqlite3VdbeSetColName(v, i, zName, strlen(zName));
      continue;
    }
    if( p->op==TK_COLUMN && pTabList ){
      Table *pTab;
      char *zCol;
      int iCol = p->iColumn;
      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
      assert( j<pTabList->nSrc );
      pTab = pTabList->a[j].pTab;
      if( iCol<0 ) iCol = pTab->iPKey;
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zCol = "rowid";
      }else{
        zCol = pTab->aCol[iCol].zName;
      }
      if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
        sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
        char *zName = 0;
        char *zTab;
        char *zDb = 0;                                                          /*** ADDED - SQLite.Interop ***/
 
        zTab = pTabList->a[j].zAlias;
        if( fullNames || zTab==0 ){
          if (pTab->iDb > 1) zDb = db->aDb[pTab->iDb].zName;                    /*** ADDED - SQLite.Interop ***/
          zTab = pTab->zName;
        }
        if (!zDb || !realNames) sqlite3SetString(&zName, zTab, ".", zCol, 0);   /*** CHANGED - SQLite.Interop ***/
        else sqlite3SetString(&zName, zDb, ".", zTab, ".", zCol, 0);            /*** ADDED - SQLite.Interop ***/
        sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
      }else{
        sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
      }
    }else if( p->span.z && p->span.z[0] ){
      sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
      /* sqlite3VdbeCompressSpace(v, addr); */
    }else{
      char zName[30];
      assert( p->op!=TK_COLUMN || pTabList==0 );
      sprintf(zName, "column%d", i+1);
      sqlite3VdbeSetColName(v, i, zName, 0);
    }
  }
  generateColumnTypes(pParse, pTabList, pEList);
}

#ifdef OS_WIN

typedef void (__stdcall *SQLITEUSERFUNC)(void *, int, void **);
typedef int  (__stdcall *SQLITECOLLATION)(int, const void *, int, const void*);

// Callback wrappers
int sqlite3_interop_collationfunc(void *pv, int len1, const void *pv1, int len2, const void *pv2)
{
  SQLITECOLLATION *p = (SQLITECOLLATION *)pv;
  return p[0](len1, pv1, len2, pv2);
}

void sqlite3_interop_func(sqlite3_context *pctx, int n, sqlite3_value **pv)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[0](pctx, n, pv);
}

void sqlite3_interop_step(sqlite3_context *pctx, int n, sqlite3_value **pv)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[1](pctx, n, pv);
}

void sqlite3_interop_final(sqlite3_context *pctx)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[2](pctx, 0, 0);
}

__declspec(dllexport) void __stdcall sqlite3_function_free_callbackcookie(void *pCookie)
{
  if (pCookie)
    free(pCookie);
}

// sqlite3 wrappers
__declspec(dllexport) const char * __stdcall sqlite3_libversion_interop(int *plen)
{
  const char *val = sqlite3_libversion();
  *plen = (val != 0) ? strlen(val) : 0;

  return val;
}

__declspec(dllexport) int __stdcall sqlite3_libversion_number_interop(void)
{
  return sqlite3_libversion_number();
}

__declspec(dllexport) int __stdcall sqlite3_close_interop(sqlite3 *db)
{
  return sqlite3_close(db);
}

__declspec(dllexport) int __stdcall sqlite3_exec_interop(sqlite3 *db, const char *sql, sqlite3_callback cb, void *pv, char **errmsg, int *plen)
{
  int n = sqlite3_exec(db, sql, cb, pv, errmsg);
  *plen = (*errmsg != 0) ? strlen(*errmsg) : 0;
  return n;
}

__declspec(dllexport) sqlite_int64 __stdcall sqlite3_last_insert_rowid_interop(sqlite3 *db)
{
  return sqlite3_last_insert_rowid(db);
}

__declspec(dllexport) int __stdcall sqlite3_changes_interop(sqlite3 *db)
{
  return sqlite3_changes(db);
}

__declspec(dllexport) int __stdcall sqlite3_total_changes_interop(sqlite3 *db)
{
  return sqlite3_total_changes(db);
}

__declspec(dllexport) void __stdcall sqlite3_interrupt_interop(sqlite3 *db)
{
  sqlite3_interrupt(db);
}

__declspec(dllexport) int __stdcall sqlite3_complete_interop(const char *sql)
{
  return sqlite3_complete(sql);
}

__declspec(dllexport) int __stdcall sqlite3_complete16_interop(const void *sql)
{
  return sqlite3_complete16(sql);
}

__declspec(dllexport) int __stdcall sqlite3_busy_handler_interop(sqlite3 *db, int(*cb)(void *, int), void *pv)
{
  return sqlite3_busy_handler(db, cb, pv);
}

__declspec(dllexport) int __stdcall sqlite3_busy_timeout_interop(sqlite3 *db, int ms)
{
  return sqlite3_busy_timeout(db, ms);
}

__declspec(dllexport) int __stdcall sqlite3_get_table_interop(sqlite3 *db, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg, int *plen)
{
  int n = sqlite3_get_table(db, sql, resultp, nrow, ncolumn, errmsg);
  *plen = (*errmsg != 0) ? strlen((char *)*errmsg) : 0;
  return n;
}

__declspec(dllexport) void __stdcall sqlite3_free_table_interop(char **result)
{
  sqlite3_free_table(result);
}

__declspec(dllexport) void __stdcall sqlite3_free_interop(char *z)
{
  sqlite3_free(z);
}

__declspec(dllexport) int __stdcall sqlite3_open_interop(const char*filename, sqlite3 **ppdb)
{
  return sqlite3_open(filename, ppdb);
}

__declspec(dllexport) int __stdcall sqlite3_open16_interop(const void *filename, sqlite3 **ppdb)
{
  return sqlite3_open16(filename, ppdb);
}

__declspec(dllexport) int __stdcall sqlite3_errcode_interop(sqlite3 *db)
{
  return sqlite3_errcode(db);
}

__declspec(dllexport) const char * __stdcall sqlite3_errmsg_interop(sqlite3 *db, int *plen)
{
  const char *pval = sqlite3_errmsg(db);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_errmsg16_interop(sqlite3 *db)
{
  return sqlite3_errmsg16(db);
}

__declspec(dllexport) int __stdcall sqlite3_prepare_interop(sqlite3 *db, const char *sql, int nbytes, sqlite3_stmt **ppstmt, const char **pztail, int *plen)
{
  int n = sqlite3_prepare(db, sql, nbytes, ppstmt, pztail);
  *plen = (*pztail != 0) ? strlen(*pztail) : 0;
  return n;
}

__declspec(dllexport) int __stdcall sqlite3_prepare16_interop(sqlite3 *db, const void *sql, int nbytes, sqlite3_stmt **ppstmt, const void **pztail)
{
  return sqlite3_prepare16(db, sql, nbytes, ppstmt, pztail);
}

__declspec(dllexport) int __stdcall sqlite3_bind_blob_interop(sqlite3_stmt *stmt, int iCol, const void *pv, int n, void(*cb)(void*))
{
  return sqlite3_bind_blob(stmt, iCol, pv, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_double_interop(sqlite3_stmt *stmt, int iCol, double *val)
{
	return sqlite3_bind_double(stmt,iCol,*val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_int_interop(sqlite3_stmt *stmt, int iCol, int val)
{
  return sqlite3_bind_int(stmt, iCol, val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	return sqlite3_bind_int64(stmt,iCol,*val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_null_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_bind_null(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_bind_text_interop(sqlite3_stmt *stmt, int iCol, const char *val, int n, void(*cb)(void *))
{
  return sqlite3_bind_text(stmt, iCol, val, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_text16_interop(sqlite3_stmt *stmt, int iCol, const void *val, int n, void(*cb)(void *))
{
  return sqlite3_bind_text16(stmt, iCol, val, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_parameter_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_bind_parameter_count(stmt);
}

__declspec(dllexport) const char * __stdcall sqlite3_bind_parameter_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_bind_parameter_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) int __stdcall sqlite3_bind_parameter_index_interop(sqlite3_stmt *stmt, const char *zName)
{
  return sqlite3_bind_parameter_index(stmt, zName);
}

__declspec(dllexport) int __stdcall sqlite3_column_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_column_count(stmt);
}

__declspec(dllexport) const char * __stdcall sqlite3_column_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_name16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_name16(stmt, iCol);
}

__declspec(dllexport) const char * __stdcall sqlite3_column_decltype_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_decltype(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_decltype16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_decltype16(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_step_interop(sqlite3_stmt *stmt)
{
  return sqlite3_step(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_data_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_data_count(stmt);
}

__declspec(dllexport) const void * __stdcall sqlite3_column_blob_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_blob(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_bytes_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_bytes(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_bytes16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_bytes16(stmt, iCol);
}

__declspec(dllexport) void __stdcall sqlite3_column_double_interop(sqlite3_stmt *stmt, int iCol, double *val)
{
	*val = sqlite3_column_double(stmt,iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_int_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_int(stmt, iCol);
}

__declspec(dllexport) void __stdcall sqlite3_column_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	*val = sqlite3_column_int64(stmt,iCol);
}

__declspec(dllexport) const unsigned char * __stdcall sqlite3_column_text_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const unsigned char *pval = sqlite3_column_text(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_text16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_text16(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_type_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_type(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_finalize_interop(sqlite3_stmt *stmt)
{
  return sqlite3_finalize(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_reset_interop(sqlite3_stmt *stmt)
{
  return sqlite3_reset(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_create_function_interop(sqlite3 *psql, const char *zFunctionName, int nArg, int eTextRep, SQLITEUSERFUNC func, SQLITEUSERFUNC funcstep, SQLITEUSERFUNC funcfinal, void **ppCookie)
{
  int n;
  SQLITEUSERFUNC *p = malloc(sizeof(SQLITEUSERFUNC) * 3);

  p[0] = func;
  p[1] = funcstep;
  p[2] = funcfinal;

  *ppCookie = 0;

  n = sqlite3_create_function(psql, zFunctionName, nArg, eTextRep, p, (func != 0) ? sqlite3_interop_func : 0, (funcstep != 0) ? sqlite3_interop_step : 0, (funcfinal != 0) ? sqlite3_interop_final : 0);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_function16_interop(sqlite3 *psql, void *zFunctionName, int nArg, int eTextRep, SQLITEUSERFUNC func, SQLITEUSERFUNC funcstep, SQLITEUSERFUNC funcfinal, void **ppCookie)
{
  int n;
  SQLITEUSERFUNC *p = malloc(sizeof(SQLITEUSERFUNC) * 3);

  p[0] = func;
  p[1] = funcstep;
  p[2] = funcfinal;

  *ppCookie = 0;

  n = sqlite3_create_function16(psql, zFunctionName, nArg, eTextRep, p, (func != 0) ? sqlite3_interop_func : 0, (funcstep != 0) ? sqlite3_interop_step : 0, (funcfinal != 0) ? sqlite3_interop_final : 0);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_collation_interop(sqlite3* db, const char *zName, int eTextRep, void* pvUser, SQLITECOLLATION func, void **ppCookie)
{
  int n;
  SQLITECOLLATION *p = malloc(sizeof(SQLITECOLLATION));
  
  p[0] = func;

  *ppCookie = 0;

  n = sqlite3_create_collation(db, zName, eTextRep, p, sqlite3_interop_collationfunc);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_collation16_interop(sqlite3* db, const void *zName, int eTextRep, void* pvUser, SQLITECOLLATION func, void **ppCookie)
{
  int n;
  SQLITECOLLATION *p = malloc(sizeof(SQLITECOLLATION));
  
  p[0] = func;

  *ppCookie = 0;

  n = sqlite3_create_collation16(db, (const char *)zName, eTextRep, p, sqlite3_interop_collationfunc);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_aggregate_count_interop(sqlite3_context *pctx)
{
  return sqlite3_aggregate_count(pctx);
}

__declspec(dllexport) const void * __stdcall sqlite3_value_blob_interop(sqlite3_value *val)
{
  return sqlite3_value_blob(val);
}

__declspec(dllexport) int __stdcall sqlite3_value_bytes_interop(sqlite3_value *val)
{
  return sqlite3_value_bytes(val);
}

__declspec(dllexport) int __stdcall sqlite3_value_bytes16_interop(sqlite3_value *val)
{
  return sqlite3_value_bytes16(val);
}

__declspec(dllexport) void __stdcall sqlite3_value_double_interop(sqlite3_value *pval, double *val)
{
  *val = sqlite3_value_double(pval);
}

__declspec(dllexport) int __stdcall sqlite3_value_int_interop(sqlite3_value *val)
{
  return sqlite3_value_int(val);
}

__declspec(dllexport) void __stdcall sqlite3_value_int64_interop(sqlite3_value *pval, sqlite_int64 *val)
{
  *val = sqlite3_value_int64(pval);
}

__declspec(dllexport) const unsigned char * __stdcall sqlite3_value_text_interop(sqlite3_value *val, int *plen)
{
  const unsigned char *pval = sqlite3_value_text(val);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_value_text16_interop(sqlite3_value *val)
{
  return sqlite3_value_text16(val);
}

__declspec(dllexport) int __stdcall sqlite3_value_type_interop(sqlite3_value *val)
{
  return sqlite3_value_type(val);
}

__declspec(dllexport) void * __stdcall sqlite3_aggregate_context_interop(sqlite3_context *pctx, int n)
{
  return sqlite3_aggregate_context(pctx, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_blob_interop(sqlite3_context *ctx, const void *pv, int n, void(*cb)(void *))
{
  sqlite3_result_blob(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_result_double_interop(sqlite3_context *pctx, double *val)
{
  sqlite3_result_double(pctx, *val);
}

__declspec(dllexport) void __stdcall sqlite3_result_int_interop(sqlite3_context *pctx, int val)
{
  sqlite3_result_int(pctx, val);
}

__declspec(dllexport) void __stdcall sqlite3_result_int64_interop(sqlite3_context *pctx, sqlite_int64 *val)
{
  sqlite3_result_int64(pctx, *val);
}

__declspec(dllexport) void __stdcall sqlite3_result_null_interop(sqlite3_context *pctx)
{
  sqlite3_result_null(pctx);
}

__declspec(dllexport) void __stdcall sqlite3_result_error_interop(sqlite3_context *ctx, const char *pv, int n)
{
  sqlite3_result_error(ctx, pv, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_error16_interop(sqlite3_context *ctx, const void *pv, int n)
{
  sqlite3_result_error16(ctx, pv, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_text_interop(sqlite3_context *ctx, const char *pv, int n, void(*cb)(void *))
{
  sqlite3_result_text(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_result_text16_interop(sqlite3_context *ctx, const void *pv, int n, void(*cb)(void *))
{
  sqlite3_result_text16(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_realcolnames(sqlite3 *db, int bOn)
{
  if (bOn)
    db->flags |= 0x01000000;
  else
    db->flags &= (~0x01000000);
}

#endif // OS_WIN
Deleted SQLite.Interop/props/SQLite.Interop.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
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.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>077</INTEROP_BUILD_NUMBER>
    <INTEROP_MANIFEST_VERSION>1.0.77.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,77,0</INTEROP_RC_VERSION>
    <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>
  <PropertyGroup>
    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
  </PropertyGroup>
  <ItemGroup>
    <BuildMacro Include="ConfigurationYear">
      <Value>$(ConfigurationYear)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="INTEROP_BUILD_NUMBER">
      <Value>$(INTEROP_BUILD_NUMBER)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="INTEROP_MANIFEST_VERSION">
      <Value>$(INTEROP_MANIFEST_VERSION)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="INTEROP_RC_VERSION">
      <Value>$(INTEROP_RC_VERSION)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="INTEROP_ASSEMBLY_RESOURCES">
      <Value>$(INTEROP_ASSEMBLY_RESOURCES)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="INTEROP_KEY_FILE">
      <Value>$(INTEROP_KEY_FILE)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="INTEROP_NATIVE_NAME">
      <Value>$(INTEROP_NATIVE_NAME)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="INTEROP_MIXED_NAME">
      <Value>$(INTEROP_MIXED_NAME)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
  </ItemGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































Deleted SQLite.Interop/props/SQLite.Interop.vsprops.
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
<?xml version="1.0" encoding="Windows-1252"?>
<!--
 *
 * SQLite.Interop.vsprops -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<VisualStudioPropertySheet
	ProjectType="Visual C++"
	Version="8.00"
	Name="SQLite.Interop"
	>
	<UserMacro
		Name="ConfigurationYear"
		Value="2008"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_BUILD_NUMBER"
		Value="077"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_MANIFEST_VERSION"
		Value="1.0.77.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_RC_VERSION"
		Value="1,0,77,0"
		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"
	/>
	<UserMacro
		Name="INTEROP_KEY_FILE"
		Value="$(ProjectDir)..\System.Data.SQLite\System.Data.SQLite.snk"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_NATIVE_NAME"
		Value="SQLite.Interop"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_MIXED_NAME"
		Value="System.Data.SQLite"
		PerformEnvironmentSet="true"
	/>
</VisualStudioPropertySheet>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































Deleted 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
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
<?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.7.9.0</SQLITE_MANIFEST_VERSION>
    <SQLITE_RC_VERSION>3,7,9,0</SQLITE_RC_VERSION>
    <SQLITE_COMMON_DEFINES>SQLITE_THREADSAFE=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT3=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=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_DEBUG_DEFINES>
    <SQLITE_RELEASE_DEFINES>SQLITE_WIN32_MALLOC=1</SQLITE_RELEASE_DEFINES>
    <SQLITE_DISABLE_WARNINGS>4018;4055;4057;4090;4100;4127;4132;4146;4152;4210;4232;4244;4245;4389;4701;4706;4996</SQLITE_DISABLE_WARNINGS>
    <SQLITE_DISABLE_X64_WARNINGS>4232;4267;4306</SQLITE_DISABLE_X64_WARNINGS>
  </PropertyGroup>
  <PropertyGroup>
    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
  </PropertyGroup>
  <ItemGroup>
    <BuildMacro Include="SQLITE_MANIFEST_VERSION">
      <Value>$(SQLITE_MANIFEST_VERSION)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="SQLITE_RC_VERSION">
      <Value>$(SQLITE_RC_VERSION)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="SQLITE_COMMON_DEFINES">
      <Value>$(SQLITE_COMMON_DEFINES)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="SQLITE_EXTRA_DEFINES">
      <Value>$(SQLITE_EXTRA_DEFINES)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="SQLITE_WINCE_DEFINES">
      <Value>$(SQLITE_WINCE_DEFINES)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="SQLITE_DEBUG_DEFINES">
      <Value>$(SQLITE_DEBUG_DEFINES)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="SQLITE_RELEASE_DEFINES">
      <Value>$(SQLITE_RELEASE_DEFINES)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="SQLITE_DISABLE_WARNINGS">
      <Value>$(SQLITE_DISABLE_WARNINGS)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="SQLITE_DISABLE_X64_WARNINGS">
      <Value>$(SQLITE_DISABLE_X64_WARNINGS)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
  </ItemGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted SQLite.Interop/props/sqlite3.vsprops.
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
<?xml version="1.0" encoding="Windows-1252"?>
<!--
 *
 * sqlite3.vsprops -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<VisualStudioPropertySheet
	ProjectType="Visual C++"
	Version="8.00"
	Name="sqlite3"
	>
	<UserMacro
		Name="SQLITE_MANIFEST_VERSION"
		Value="3.7.9.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_RC_VERSION"
		Value="3,7,9,0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_COMMON_DEFINES"
		Value="SQLITE_THREADSAFE=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT3=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_EXTRA_DEFINES"
		Value="SQLITE_HAS_CODEC=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_WINCE_DEFINES"
		Value="SQLITE_OMIT_WAL=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_DEBUG_DEFINES"
		Value="SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_RELEASE_DEFINES"
		Value="SQLITE_WIN32_MALLOC=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_DISABLE_WARNINGS"
		Value="4018;4055;4057;4090;4100;4127;4132;4146;4152;4210;4232;4244;4245;4389;4701;4706;4996"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_DISABLE_X64_WARNINGS"
		Value="4232;4267;4306"
		PerformEnvironmentSet="true"
	/>
</VisualStudioPropertySheet>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































Added SQLite.Interop/src/alter.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
/*
** 2005 February 15
**
** 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 file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.1 2005/03/01 16:04:26 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
*/
#ifndef SQLITE_OMIT_ALTERTABLE


/*
** This function is used by SQL generated to implement the 
** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
** CREATE INDEX command. The second is a table name. The table name in 
** the CREATE TABLE or CREATE INDEX statement is replaced with the second
** argument and the result returned. Examples:
**
** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
**     -> 'CREATE TABLE def(a, b, c)'
**
** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
**     -> 'CREATE INDEX i ON def(a, b, c)'
*/
static void renameTableFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);

  int token;
  Token tname;
  char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  /* The principle used to locate the table name in the CREATE TABLE 
  ** statement is that the table name is the first token that is immediatedly
  ** followed by a left parenthesis - TK_LP.
  */
  if( zSql ){
    do {
      /* Store the token that zCsr points to in tname. */
      tname.z = zCsr;
      tname.n = len;

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and it's length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite3GetToken(zCsr, &token);
      } while( token==TK_SPACE );
      assert( len>0 );
    } while( token!=TK_LP );

    zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite3_result_text(context, zRet, -1, sqlite3FreeX);
  }
}

#ifndef SQLITE_OMIT_TRIGGER
/* This function is used by SQL generated to implement the ALTER TABLE
** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
** statement. The second is a table name. The table name in the CREATE 
** TRIGGER statement is replaced with the second argument and the result 
** returned. This is analagous to renameTableFunc() above, except for CREATE
** TRIGGER, not CREATE INDEX and CREATE TABLE.
*/
static void renameTriggerFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);

  int token;
  Token tname;
  int dist = 3;
  char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  /* The principle used to locate the table name in the CREATE TRIGGER 
  ** statement is that the table name is the first token that is immediatedly
  ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
  ** of TK_WHEN, TK_BEGIN or TK_FOR.
  */
  if( zSql ){
    do {
      /* Store the token that zCsr points to in tname. */
      tname.z = zCsr;
      tname.n = len;

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and it's length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite3GetToken(zCsr, &token);
      }while( token==TK_SPACE );
      assert( len>0 );

      /* Variable 'dist' stores the number of tokens read since the most
      ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
      ** token is read and 'dist' equals 2, the condition stated above
      ** to be met.
      **
      ** Note that ON cannot be a database, table or column name, so
      ** there is no need to worry about syntax like 
      ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
      */
      dist++;
      if( token==TK_DOT || token==TK_ON ){
        dist = 0;
      }
    } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );

    /* Variable tname now contains the token that is the old table-name
    ** in the CREATE TRIGGER statement.
    */
    zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite3_result_text(context, zRet, -1, sqlite3FreeX);
  }
}
#endif   /* !SQLITE_OMIT_TRIGGER */

/*
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(sqlite3 *db){
  static const struct {
     char *zName;
     signed char nArg;
     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
  } aFuncs[] = {
    { "sqlite_rename_table",    2, renameTableFunc},
#ifndef SQLITE_OMIT_TRIGGER
    { "sqlite_rename_trigger",  2, renameTriggerFunc},
#endif
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
        SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
  }
}

/*
** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
** command. 
*/
void sqlite3AlterRenameTable(
  Parse *pParse,            /* Parser context. */
  SrcList *pSrc,            /* The table to rename. */
  Token *pName              /* The new table name. */
){
  int iDb;                  /* Database that contains the table */
  char *zDb;                /* Name of database iDb */
  Table *pTab;              /* Table being renamed */
  char *zName = 0;          /* NULL-terminated version of pName */ 
  char *zWhere = 0;         /* Where clause of schema elements to reparse */
  sqlite3 *db = pParse->db; /* Database connection */
  Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
  char *zTempTrig = 0;      /* Where clause to locate temp triggers */
#endif
  
  assert( pSrc->nSrc==1 );

  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_rename_table;
  iDb = pTab->iDb;
  zDb = db->aDb[iDb].zName;

  /* Get a NULL terminated version of the new table name. */
  zName = sqlite3NameFromToken(pName);
  if( !zName ) goto exit_rename_table;

  /* Check that a table or index named 'zName' does not already exist
  ** in database iDb. If so, this is an error.
  */
  if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
    sqlite3ErrorMsg(pParse, 
        "there is already another table or index with this name: %s", zName);
    goto exit_rename_table;
  }

  /* Make sure it is not a system table being altered, or a reserved name
  ** that the table is being renamed to.
  */
  if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){
    sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
    goto exit_rename_table;
  }
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto exit_rename_table;
  }

#ifndef SQLITE_OMIT_AUTHORIZATION
  /* Invoke the authorization callback. */
  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
    goto exit_rename_table;
  }
#endif

  /* Begin a transaction and code the VerifyCookie for database iDb. 
  ** Then modify the schema cookie (since the ALTER TABLE modifies the
  ** schema).
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    goto exit_rename_table;
  }
  sqlite3BeginWriteOperation(pParse, 0, iDb);
  sqlite3ChangeCookie(db, v, iDb);

  /* Modify the sqlite_master table to use the new table name. */
  sqlite3NestedParse(pParse,
      "UPDATE %Q.%s SET "
#ifdef SQLITE_OMIT_TRIGGER
          "sql = sqlite_rename_table(sql, %Q), "
#else
          "sql = CASE "
            "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
            "ELSE sqlite_rename_table(sql, %Q) END, "
#endif
          "tbl_name = %Q, "
          "name = CASE "
            "WHEN type='table' THEN %Q "
            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
              "'sqlite_autoindex_' || %Q || substr(name, %d+18,10) "
            "ELSE name END "
      "WHERE tbl_name=%Q AND "
          "(type='table' OR type='index' OR type='trigger');", 
      zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
#ifndef SQLITE_OMIT_TRIGGER
zName,
#endif
      zName, strlen(pTab->zName), pTab->zName
  );

#ifndef SQLITE_OMIT_AUTOINCREMENT
  /* If the sqlite_sequence table exists in this database, then update 
  ** it with the new table name.
  */
  if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
    sqlite3NestedParse(pParse,
        "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q",
        zDb, zName, pTab->zName);
  }
#endif

#ifndef SQLITE_OMIT_TRIGGER
  /* If there are TEMP triggers on this table, modify the sqlite_temp_master
  ** table. Don't do this if the table being ALTERed is itself located in
  ** the temp database.
  */
  if( iDb!=1 ){
    Trigger *pTrig;
    char *tmp = 0;
    for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
      if( pTrig->iDb==1 ){
        if( !zTempTrig ){
          zTempTrig = 
              sqlite3MPrintf("type = 'trigger' AND (name=%Q", pTrig->name);
        }else{
          tmp = zTempTrig;
          zTempTrig = sqlite3MPrintf("%s OR name=%Q", zTempTrig, pTrig->name);
          sqliteFree(tmp);
        }
      }
    }
    if( zTempTrig ){
      tmp = zTempTrig;
      zTempTrig = sqlite3MPrintf("%s)", zTempTrig);
      sqliteFree(tmp);
      sqlite3NestedParse(pParse, 
          "UPDATE sqlite_temp_master SET "
              "sql = sqlite_rename_trigger(sql, %Q), "
              "tbl_name = %Q "
              "WHERE %s;", zName, zName, zTempTrig);
    }
  }
#endif

  /* Drop the elements of the in-memory schema that refered to the table
  ** renamed and load the new versions from the database.
  */
  if( pParse->nErr==0 ){
#ifndef SQLITE_OMIT_TRIGGER
    Trigger *pTrig;
    for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
      assert( pTrig->iDb==iDb || pTrig->iDb==1 );
      sqlite3VdbeOp3(v, OP_DropTrigger, pTrig->iDb, 0, pTrig->name, 0);
    }
#endif
    sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
    zWhere = sqlite3MPrintf("tbl_name=%Q", zName);
    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
#ifndef SQLITE_OMIT_TRIGGER
    if( zTempTrig ){
      sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zTempTrig, P3_DYNAMIC);
    }
  }else{
    sqliteFree(zTempTrig);
#endif
  }

exit_rename_table:
  sqlite3SrcListDelete(pSrc);
  sqliteFree(zName);
}
#endif  /* SQLITE_ALTER_TABLE */
Added SQLite.Interop/src/attach.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
/*
** 2003 April 6
**
** 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 file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.1 2005/03/01 16:04:26 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
**
** The pFilename and pDbname arguments are the tokens that define the
** filename and dbname in the ATTACH statement.
*/
void sqlite3Attach(
  Parse *pParse,       /* The parser context */
  Token *pFilename,    /* Name of database file */
  Token *pDbname,      /* Name of the database to use internally */
  int keyType,         /* 0: no key.  1: TEXT,  2: BLOB */
  Token *pKey          /* Text of the key for keytype 1 and 2 */
){
  Db *aNew;
  int rc, i;
  char *zFile, *zName;
  sqlite3 *db;
  Vdbe *v;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
  if( pParse->explain ) return;
  db = pParse->db;
  if( db->nDb>=MAX_ATTACHED+2 ){
    sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 
       MAX_ATTACHED);
    pParse->rc = SQLITE_ERROR;
    return;
  }

  if( !db->autoCommit ){
    sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction");
    pParse->rc = SQLITE_ERROR;
    return;
  }

  zFile = sqlite3NameFromToken(pFilename);;
  if( zFile==0 ) return;
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
    sqliteFree(zFile);
    return;
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */

  zName = sqlite3NameFromToken(pDbname);
  if( zName==0 ) return;
  for(i=0; i<db->nDb; i++){
    char *z = db->aDb[i].zName;
    if( z && sqlite3StrICmp(z, zName)==0 ){
      sqlite3ErrorMsg(pParse, "database %z is already in use", zName);
      pParse->rc = SQLITE_ERROR;
      sqliteFree(zFile);
      return;
    }
  }

  if( db->aDb==db->aDbStatic ){
    aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
    if( aNew==0 ) return;
    memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
  }else{
    aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
    if( aNew==0 ) return;
  }
  db->aDb = aNew;
  aNew = &db->aDb[db->nDb++];
  memset(aNew, 0, sizeof(*aNew));
  sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
  aNew->zName = zName;
  aNew->safety_level = 3;
  rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc ){
    sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
  }
#if SQLITE_HAS_CODEC
  {
    extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
    char *zKey;
    int nKey;
    if( keyType==0 ){
      /* No key specified.  Use the key from the main database */
      extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
      sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
    }else if( keyType==1 ){
      /* Key specified as text */
      zKey = sqlite3NameFromToken(pKey);
      nKey = strlen(zKey);
    }else{
      /* Key specified as a BLOB */
      char *zTemp;
      assert( keyType==2 );
      pKey->z++;
      pKey->n--;
      zTemp = sqlite3NameFromToken(pKey);
      zKey = sqlite3HexToBlob(zTemp);
      sqliteFree(zTemp);
    }
    sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
    if( keyType ){
      sqliteFree(zKey);
    }
  }
#endif
  sqliteFree(zFile);
  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr==0 && rc==SQLITE_OK ){
    rc = sqlite3ReadSchema(pParse);
  }
  if( rc ){
    int i = db->nDb - 1;
    assert( i>=2 );
    if( db->aDb[i].pBt ){
      sqlite3BtreeClose(db->aDb[i].pBt);
      db->aDb[i].pBt = 0;
    }
    sqlite3ResetInternalSchema(db, 0);
    if( 0==pParse->nErr ){
      pParse->nErr++;
      pParse->rc = SQLITE_ERROR;
    }
  }
}

/*
** This routine is called by the parser to process a DETACH statement:
**
**    DETACH DATABASE dbname
**
** The pDbname argument is the name of the database in the DETACH statement.
*/
void sqlite3Detach(Parse *pParse, Token *pDbname){
  int i;
  sqlite3 *db;
  Vdbe *v;
  Db *pDb = 0;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
  if( pParse->explain ) return;
  db = pParse->db;
  for(i=0; i<db->nDb; i++){
    pDb = &db->aDb[i];
    if( pDb->pBt==0 || pDb->zName==0 ) continue;
    if( strlen(pDb->zName)!=pDbname->n ) continue;
    if( sqlite3StrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break;
  }
  if( i>=db->nDb ){
    sqlite3ErrorMsg(pParse, "no such database: %T", pDbname);
    return;
  }
  if( i<2 ){
    sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname);
    return;
  }
  if( !db->autoCommit ){
    sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction");
    pParse->rc = SQLITE_ERROR;
    return;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
    return;
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */
  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;
  sqlite3ResetInternalSchema(db, 0);
}

/*
** Initialize a DbFixer structure.  This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
**
** The return value indicates whether or not fixation is required.  TRUE
** means we do need to fix the database references, FALSE means we do not.
*/
int sqlite3FixInit(
  DbFixer *pFix,      /* The fixer to be initialized */
  Parse *pParse,      /* Error messages will be written here */
  int iDb,            /* This is the database that must be used */
  const char *zType,  /* "view", "trigger", or "index" */
  const Token *pName  /* Name of the view, trigger, or index */
){
  sqlite3 *db;

  if( iDb<0 || iDb==1 ) return 0;
  db = pParse->db;
  assert( db->nDb>iDb );
  pFix->pParse = pParse;
  pFix->zDb = db->aDb[iDb].zName;
  pFix->zType = zType;
  pFix->pName = pName;
  return 1;
}

/*
** The following set of routines walk through the parse tree and assign
** a specific database to all table references where the database name
** was left unspecified in the original SQL statement.  The pFix structure
** must have been initialized by a prior call to sqlite3FixInit().
**
** These routines are used to make sure that an index, trigger, or
** view in one database does not refer to objects in a different database.
** (Exception: indices, triggers, and views in the TEMP database are
** allowed to refer to anything.)  If a reference is explicitly made
** to an object in a different database, an error message is added to
** pParse->zErrMsg and these routines return non-zero.  If everything
** checks out, these routines return 0.
*/
int sqlite3FixSrcList(
  DbFixer *pFix,       /* Context of the fixation */
  SrcList *pList       /* The Source list to check and modify */
){
  int i;
  const char *zDb;
  struct SrcList_item *pItem;

  if( pList==0 ) return 0;
  zDb = pFix->zDb;
  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pItem->zDatabase==0 ){
      pItem->zDatabase = sqliteStrDup(zDb);
    }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
      sqlite3ErrorMsg(pFix->pParse,
         "%s %T cannot reference objects in database %s",
         pFix->zType, pFix->pName, pItem->zDatabase);
      return 1;
    }
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
    if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
    if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
#endif
  }
  return 0;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
int sqlite3FixSelect(
  DbFixer *pFix,       /* Context of the fixation */
  Select *pSelect      /* The SELECT statement to be fixed to one database */
){
  while( pSelect ){
    if( sqlite3FixExprList(pFix, pSelect->pEList) ){
      return 1;
    }
    if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
      return 1;
    }
    pSelect = pSelect->pPrior;
  }
  return 0;
}
int sqlite3FixExpr(
  DbFixer *pFix,     /* Context of the fixation */
  Expr *pExpr        /* The expression to be fixed to one database */
){
  while( pExpr ){
    if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
      return 1;
    }
    if( sqlite3FixExprList(pFix, pExpr->pList) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pExpr->pRight) ){
      return 1;
    }
    pExpr = pExpr->pLeft;
  }
  return 0;
}
int sqlite3FixExprList(
  DbFixer *pFix,     /* Context of the fixation */
  ExprList *pList    /* The expression to be fixed to one database */
){
  int i;
  struct ExprList_item *pItem;
  if( pList==0 ) return 0;
  for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
    if( sqlite3FixExpr(pFix, pItem->pExpr) ){
      return 1;
    }
  }
  return 0;
}
#endif

#ifndef SQLITE_OMIT_TRIGGER
int sqlite3FixTriggerStep(
  DbFixer *pFix,     /* Context of the fixation */
  TriggerStep *pStep /* The trigger step be fixed to one database */
){
  while( pStep ){
    if( sqlite3FixSelect(pFix, pStep->pSelect) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pStep->pWhere) ){
      return 1;
    }
    if( sqlite3FixExprList(pFix, pStep->pExprList) ){
      return 1;
    }
    pStep = pStep->pNext;
  }
  return 0;
}
#endif
Added SQLite.Interop/src/auth.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
/*
** 2003 January 11
**
** 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 file contains code used to implement the sqlite3_set_authorizer()
** API.  This facility is an optional feature of the library.  Embedded
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
**
** $Id: auth.c,v 1.1 2005/03/01 16:04:26 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** All of the code in this file may be omitted by defining a single
** macro.
*/
#ifndef SQLITE_OMIT_AUTHORIZATION

/*
** Set or clear the access authorization function.
**
** The access authorization function is be called during the compilation
** phase to verify that the user has read and/or write access permission on
** various fields of the database.  The first argument to the auth function
** is a copy of the 3rd argument to this routine.  The second argument
** to the auth function is one of these constants:
**
**       SQLITE_CREATE_INDEX
**       SQLITE_CREATE_TABLE
**       SQLITE_CREATE_TEMP_INDEX
**       SQLITE_CREATE_TEMP_TABLE
**       SQLITE_CREATE_TEMP_TRIGGER
**       SQLITE_CREATE_TEMP_VIEW
**       SQLITE_CREATE_TRIGGER
**       SQLITE_CREATE_VIEW
**       SQLITE_DELETE
**       SQLITE_DROP_INDEX
**       SQLITE_DROP_TABLE
**       SQLITE_DROP_TEMP_INDEX
**       SQLITE_DROP_TEMP_TABLE
**       SQLITE_DROP_TEMP_TRIGGER
**       SQLITE_DROP_TEMP_VIEW
**       SQLITE_DROP_TRIGGER
**       SQLITE_DROP_VIEW
**       SQLITE_INSERT
**       SQLITE_PRAGMA
**       SQLITE_READ
**       SQLITE_SELECT
**       SQLITE_TRANSACTION
**       SQLITE_UPDATE
**
** The third and fourth arguments to the auth function are the name of
** the table and the column that are being accessed.  The auth function
** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE.  If
** SQLITE_OK is returned, it means that access is allowed.  SQLITE_DENY
** means that the SQL statement will never-run - the sqlite3_exec() call
** will return with an error.  SQLITE_IGNORE means that the SQL statement
** should run but attempts to read the specified column will return NULL
** and attempts to write the column will be ignored.
**
** Setting the auth function to NULL disables this hook.  The default
** setting of the auth function is NULL.
*/
int sqlite3_set_authorizer(
  sqlite3 *db,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pArg
){
  db->xAuth = xAuth;
  db->pAuthArg = pArg;
  sqlite3ExpirePreparedStatements(db);
  return SQLITE_OK;
}

/*
** Write an error message into pParse->zErrMsg that explains that the
** user-supplied authorization function returned an illegal value.
*/
static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
  sqlite3ErrorMsg(pParse, "illegal return value (%d) from the "
    "authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
    "or SQLITE_DENY", rc);
  pParse->rc = SQLITE_ERROR;
}

/*
** The pExpr should be a TK_COLUMN expression.  The table referred to
** is in pTabList or else it is the NEW or OLD table of a trigger.  
** Check to see if it is OK to read this particular column.
**
** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN 
** instruction into a TK_NULL.  If the auth function returns SQLITE_DENY,
** then generate an error.
*/
void sqlite3AuthRead(
  Parse *pParse,        /* The parser context */
  Expr *pExpr,          /* The expression to check authorization on */
  SrcList *pTabList     /* All table that pExpr might refer to */
){
  sqlite3 *db = pParse->db;
  int rc;
  Table *pTab;          /* The table being read */
  const char *zCol;     /* Name of the column of the table */
  int iSrc;             /* Index in pTabList->a[] of table being read */
  const char *zDBase;   /* Name of database being accessed */
  TriggerStack *pStack; /* The stack of current triggers */

  if( db->xAuth==0 ) return;
  assert( pExpr->op==TK_COLUMN );
  for(iSrc=0; pTabList && iSrc<pTabList->nSrc; iSrc++){
    if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
  }
  if( iSrc>=0 && pTabList && iSrc<pTabList->nSrc ){
    pTab = pTabList->a[iSrc].pTab;
  }else if( (pStack = pParse->trigStack)!=0 ){
    /* This must be an attempt to read the NEW or OLD pseudo-tables
    ** of a trigger.
    */
    assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
    pTab = pStack->pTab;
  }else{
    return;
  }
  if( pTab==0 ) return;
  if( pExpr->iColumn>=0 ){
    assert( pExpr->iColumn<pTab->nCol );
    zCol = pTab->aCol[pExpr->iColumn].zName;
  }else if( pTab->iPKey>=0 ){
    assert( pTab->iPKey<pTab->nCol );
    zCol = pTab->aCol[pTab->iPKey].zName;
  }else{
    zCol = "ROWID";
  }
  assert( pExpr->iDb<db->nDb );
  zDBase = db->aDb[pExpr->iDb].zName;
  rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, 
                 pParse->zAuthContext);
  if( rc==SQLITE_IGNORE ){
    pExpr->op = TK_NULL;
  }else if( rc==SQLITE_DENY ){
    if( db->nDb>2 || pExpr->iDb!=0 ){
      sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited", 
         zDBase, pTab->zName, zCol);
    }else{
      sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol);
    }
    pParse->rc = SQLITE_AUTH;
  }else if( rc!=SQLITE_OK ){
    sqliteAuthBadReturnCode(pParse, rc);
  }
}

/*
** Do an authorization check using the code and arguments given.  Return
** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY.  If SQLITE_DENY
** is returned, then the error count and error message in pParse are
** modified appropriately.
*/
int sqlite3AuthCheck(
  Parse *pParse,
  int code,
  const char *zArg1,
  const char *zArg2,
  const char *zArg3
){
  sqlite3 *db = pParse->db;
  int rc;

  /* Don't do any authorization checks if the database is initialising. */
  if( db->init.busy ){
    return SQLITE_OK;
  }

  if( db->xAuth==0 ){
    return SQLITE_OK;
  }
  rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
  if( rc==SQLITE_DENY ){
    sqlite3ErrorMsg(pParse, "not authorized");
    pParse->rc = SQLITE_AUTH;
  }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
    rc = SQLITE_DENY;
    sqliteAuthBadReturnCode(pParse, rc);
  }
  return rc;
}

/*
** Push an authorization context.  After this routine is called, the
** zArg3 argument to authorization callbacks will be zContext until
** popped.  Or if pParse==0, this routine is a no-op.
*/
void sqlite3AuthContextPush(
  Parse *pParse,
  AuthContext *pContext, 
  const char *zContext
){
  pContext->pParse = pParse;
  if( pParse ){
    pContext->zAuthContext = pParse->zAuthContext;
    pParse->zAuthContext = zContext;
  }
}

/*
** Pop an authorization context that was previously pushed
** by sqlite3AuthContextPush
*/
void sqlite3AuthContextPop(AuthContext *pContext){
  if( pContext->pParse ){
    pContext->pParse->zAuthContext = pContext->zAuthContext;
    pContext->pParse = 0;
  }
}

#endif /* SQLITE_OMIT_AUTHORIZATION */
Added SQLite.Interop/src/btree.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
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
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
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
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
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
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
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
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
/*
** 2004 April 6
**
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.1 2005/03/01 16:04:27 rmsimpson Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
**
** The basic idea is that each page of the file contains N database
** entries and N+1 pointers to subpages.
**
**   ----------------------------------------------------------------
**   |  Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N) | Ptr(N+1) |
**   ----------------------------------------------------------------
**
** All of the keys on the page that Ptr(0) points to have values less
** than Key(0).  All of the keys on page Ptr(1) and its subpages have
** values greater than Key(0) and less than Key(1).  All of the keys
** on Ptr(N+1) and its subpages have values greater than Key(N).  And
** so forth.
**
** Finding a particular key requires reading O(log(M)) pages from the 
** disk where M is the number of entries in the tree.
**
** In this implementation, a single file can hold one or more separate 
** BTrees.  Each BTree is identified by the index of its root page.  The
** key and data for any entry are combined to form the "payload".  A
** fixed amount of payload can be carried directly on the database
** page.  If the payload is larger than the preset amount then surplus
** bytes are stored on overflow pages.  The payload for an entry
** and the preceding pointer are combined to form a "Cell".  Each 
** page has a small header which contains the Ptr(N+1) pointer and other
** information such as the size of key and data.
**
** FORMAT DETAILS
**
** The file is divided into pages.  The first page is called page 1,
** the second is page 2, and so forth.  A page number of zero indicates
** "no such page".  The page size can be anything between 512 and 65536.
** Each page can be either a btree page, a freelist page or an overflow
** page.
**
** The first page is always a btree page.  The first 100 bytes of the first
** page contain a special header (the "file header") that describes the file.
** The format of the file header is as follows:
**
**   OFFSET   SIZE    DESCRIPTION
**      0      16     Header string: "SQLite format 3\000"
**     16       2     Page size in bytes.  
**     18       1     File format write version
**     19       1     File format read version
**     20       1     Bytes of unused space at the end of each page
**     21       1     Max embedded payload fraction
**     22       1     Min embedded payload fraction
**     23       1     Min leaf payload fraction
**     24       4     File change counter
**     28       4     Reserved for future use
**     32       4     First freelist page
**     36       4     Number of freelist pages in the file
**     40      60     15 4-byte meta values passed to higher layers
**
** All of the integer values are big-endian (most significant byte first).
**
** The file change counter is incremented when the database is changed more
** than once within the same second.  This counter, together with the
** modification time of the file, allows other processes to know
** when the file has changed and thus when they need to flush their
** cache.
**
** The max embedded payload fraction is the amount of the total usable
** space in a page that can be consumed by a single cell for standard
** B-tree (non-LEAFDATA) tables.  A value of 255 means 100%.  The default
** is to limit the maximum cell size so that at least 4 cells will fit
** on one page.  Thus the default max embedded payload fraction is 64.
**
** If the payload for a cell is larger than the max payload, then extra
** payload is spilled to overflow pages.  Once an overflow page is allocated,
** as many bytes as possible are moved into the overflow pages without letting
** the cell size drop below the min embedded payload fraction.
**
** The min leaf payload fraction is like the min embedded payload fraction
** except that it applies to leaf nodes in a LEAFDATA tree.  The maximum
** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
** not specified in the header.
**
** Each btree pages is divided into three sections:  The header, the
** cell pointer array, and the cell area area.  Page 1 also has a 100-byte
** file header that occurs before the page header.
**
**      |----------------|
**      | file header    |   100 bytes.  Page 1 only.
**      |----------------|
**      | page header    |   8 bytes for leaves.  12 bytes for interior nodes
**      |----------------|
**      | cell pointer   |   |  2 bytes per cell.  Sorted order.
**      | array          |   |  Grows downward
**      |                |   v
**      |----------------|
**      | unallocated    |
**      | space          |
**      |----------------|   ^  Grows upwards
**      | cell content   |   |  Arbitrary order interspersed with freeblocks.
**      | area           |   |  and free space fragments.
**      |----------------|
**
** The page headers looks like this:
**
**   OFFSET   SIZE     DESCRIPTION
**      0       1      Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
**      1       2      byte offset to the first freeblock
**      3       2      number of cells on this page
**      5       2      first byte of the cell content area
**      7       1      number of fragmented free bytes
**      8       4      Right child (the Ptr(N+1) value).  Omitted on leaves.
**
** The flags define the format of this btree page.  The leaf flag means that
** this page has no children.  The zerodata flag means that this page carries
** only keys and no data.  The intkey flag means that the key is a integer
** which is stored in the key size entry of the cell header rather than in
** the payload area.
**
** The cell pointer array begins on the first byte after the page header.
** The cell pointer array contains zero or more 2-byte numbers which are
** offsets from the beginning of the page to the cell content in the cell
** content area.  The cell pointers occur in sorted order.  The system strives
** to keep free space after the last cell pointer so that new cells can
** be easily added without having to defragment the page.
**
** Cell content is stored at the very end of the page and grows toward the
** beginning of the page.
**
** Unused space within the cell content area is collected into a linked list of
** freeblocks.  Each freeblock is at least 4 bytes in size.  The byte offset
** to the first freeblock is given in the header.  Freeblocks occur in
** increasing order.  Because a freeblock must be at least 4 bytes in size,
** any group of 3 or fewer unused bytes in the cell content area cannot
** exist on the freeblock chain.  A group of 3 or fewer free bytes is called
** a fragment.  The total number of bytes in all fragments is recorded.
** in the page header at offset 7.
**
**    SIZE    DESCRIPTION
**      2     Byte offset of the next freeblock
**      2     Bytes in this freeblock
**
** Cells are of variable length.  Cells are stored in the cell content area at
** the end of the page.  Pointers to the cells are in the cell pointer array
** that immediately follows the page header.  Cells is not necessarily
** contiguous or in order, but cell pointers are contiguous and in order.
**
** Cell content makes use of variable length integers.  A variable
** length integer is 1 to 9 bytes where the lower 7 bits of each 
** byte are used.  The integer consists of all bytes that have bit 8 set and
** the first byte with bit 8 clear.  The most significant byte of the integer
** appears first.  A variable-length integer may not be more than 9 bytes long.
** As a special case, all 8 bytes of the 9th byte are used as data.  This
** allows a 64-bit integer to be encoded in 9 bytes.
**
**    0x00                      becomes  0x00000000
**    0x7f                      becomes  0x0000007f
**    0x81 0x00                 becomes  0x00000080
**    0x82 0x00                 becomes  0x00000100
**    0x80 0x7f                 becomes  0x0000007f
**    0x8a 0x91 0xd1 0xac 0x78  becomes  0x12345678
**    0x81 0x81 0x81 0x81 0x01  becomes  0x10204081
**
** Variable length integers are used for rowids and to hold the number of
** bytes of key and data in a btree cell.
**
** The content of a cell looks like this:
**
**    SIZE    DESCRIPTION
**      4     Page number of the left child. Omitted if leaf flag is set.
**     var    Number of bytes of data. Omitted if the zerodata flag is set.
**     var    Number of bytes of key. Or the key itself if intkey flag is set.
**      *     Payload
**      4     First page of the overflow chain.  Omitted if no overflow
**
** Overflow pages form a linked list.  Each page except the last is completely
** filled with data (pagesize - 4 bytes).  The last page can have as little
** as 1 byte of data.
**
**    SIZE    DESCRIPTION
**      4     Page number of next overflow page
**      *     Data
**
** Freelist pages come in two subtypes: trunk pages and leaf pages.  The
** file header points to first in a linked list of trunk page.  Each trunk
** page points to multiple leaf pages.  The content of a leaf page is
** unspecified.  A trunk page looks like this:
**
**    SIZE    DESCRIPTION
**      4     Page number of next trunk page
**      4     Number of leaf pointers on this page
**      *     zero or more pages numbers of leaves
*/
#include "sqliteInt.h"
#include "pager.h"
#include "btree.h"
#include "os.h"
#include <assert.h>

/*
** This macro rounds values up so that if the value is an address it
** is guaranteed to be an address that is aligned to an 8-byte boundary.
*/
#define FORCE_ALIGNMENT(X)   (((X)+7)&~7)

/* The following value is the maximum cell size assuming a maximum page
** size give above.
*/
#define MX_CELL_SIZE(pBt)  (pBt->pageSize-8)

/* The maximum number of cells on a single page of the database.  This
** assumes a minimum cell size of 3 bytes.  Such small cells will be
** exceedingly rare, but they are possible.
*/
#define MX_CELL(pBt) ((pBt->pageSize-8)/3)

/* Forward declarations */
typedef struct MemPage MemPage;

/*
** This is a magic string that appears at the beginning of every
** SQLite database in order to identify the file as a real database.
**                                  123456789 123456 */
static const char zMagicHeader[] = "SQLite format 3";

/*
** Page type flags.  An ORed combination of these flags appear as the
** first byte of every BTree page.
*/
#define PTF_INTKEY    0x01
#define PTF_ZERODATA  0x02
#define PTF_LEAFDATA  0x04
#define PTF_LEAF      0x08

/*
** As each page of the file is loaded into memory, an instance of the following
** structure is appended and initialized to zero.  This structure stores
** information about the page that is decoded from the raw file page.
**
** The pParent field points back to the parent page.  This allows us to
** walk up the BTree from any leaf to the root.  Care must be taken to
** unref() the parent page pointer when this page is no longer referenced.
** The pageDestructor() routine handles that chore.
*/
struct MemPage {
  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
  u8 idxShift;         /* True if Cell indices have changed */
  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
  u8 intKey;           /* True if intkey flag is set */
  u8 leaf;             /* True if leaf flag is set */
  u8 zeroData;         /* True if table stores keys only */
  u8 leafData;         /* True if tables stores data on leaves only */
  u8 hasData;          /* True if this page stores data */
  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
  u16 maxLocal;        /* Copy of Btree.maxLocal or Btree.maxLeaf */
  u16 minLocal;        /* Copy of Btree.minLocal or Btree.minLeaf */
  u16 cellOffset;      /* Index in aData of first cell pointer */
  u16 idxParent;       /* Index in parent of this node */
  u16 nFree;           /* Number of free bytes on the page */
  u16 nCell;           /* Number of cells on this page, local and ovfl */
  struct _OvflCell {   /* Cells that will not fit on aData[] */
    u8 *pCell;           /* Pointers to the body of the overflow cell */
    u16 idx;             /* Insert this cell before idx-th non-overflow cell */
  } aOvfl[5];
  struct Btree *pBt;   /* Pointer back to BTree structure */
  u8 *aData;           /* Pointer back to the start of the page */
  Pgno pgno;           /* Page number for this page */
  MemPage *pParent;    /* The parent of this page.  NULL for root */
};

/*
** The in-memory image of a disk page has the auxiliary information appended
** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
** that extra information.
*/
#define EXTRA_SIZE sizeof(MemPage)

/*
** Everything we need to know about an open database
*/
struct Btree {
  Pager *pPager;        /* The page cache */
  BtCursor *pCursor;    /* A list of all open cursors */
  MemPage *pPage1;      /* First page of the database */
  u8 inTrans;           /* True if a transaction is in progress */
  u8 inStmt;            /* True if we are in a statement subtransaction */
  u8 readOnly;          /* True if the underlying file is readonly */
  u8 maxEmbedFrac;      /* Maximum payload as % of total page size */
  u8 minEmbedFrac;      /* Minimum payload as % of total page size */
  u8 minLeafFrac;       /* Minimum leaf payload as % of total page size */
  u8 pageSizeFixed;     /* True if the page size can no longer be changed */
#ifndef SQLITE_OMIT_AUTOVACUUM
  u8 autoVacuum;        /* True if database supports auto-vacuum */
#endif
  u16 pageSize;         /* Total number of bytes on a page */
  u16 psAligned;        /* pageSize rounded up to a multiple of 8 */
  u16 usableSize;       /* Number of usable bytes on each page */
  int maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
  int minLocal;         /* Minimum local payload in non-LEAFDATA tables */
  int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
  int minLeaf;          /* Minimum local payload in a LEAFDATA table */
};
typedef Btree Bt;

/*
** Btree.inTrans may take one of the following values.
*/
#define TRANS_NONE  0
#define TRANS_READ  1
#define TRANS_WRITE 2

/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page.
*/
typedef struct CellInfo CellInfo;
struct CellInfo {
  u8 *pCell;     /* Pointer to the start of cell content */
  i64 nKey;      /* The key for INTKEY tables, or number of bytes in key */
  u32 nData;     /* Number of bytes of data */
  u16 nHeader;   /* Size of the cell content header in bytes */
  u16 nLocal;    /* Amount of payload held locally */
  u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
  u16 nSize;     /* Size of the cell content on the main b-tree page */
};

/*
** A cursor is a pointer to a particular entry in the BTree.
** The entry is identified by its MemPage and the index in
** MemPage.aCell[] of the entry.
*/
struct BtCursor {
  Btree *pBt;               /* The Btree to which this cursor belongs */
  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
  int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */
  void *pArg;               /* First arg to xCompare() */
  Pgno pgnoRoot;            /* The root page of this tree */
  MemPage *pPage;           /* Page that contains the entry */
  int idx;                  /* Index of the entry in pPage->aCell[] */
  CellInfo info;            /* A parse of the cell we are pointing at */
  u8 wrFlag;                /* True if writable */
  u8 isValid;               /* TRUE if points to a valid entry */
};

/*
** The TRACE macro will print high-level status information about the
** btree operation when the global variable sqlite3_btree_trace is
** enabled.
*/
#if SQLITE_TEST
# define TRACE(X)   if( sqlite3_btree_trace )\
                        { sqlite3DebugPrintf X; fflush(stdout); }
#else
# define TRACE(X)
#endif
int sqlite3_btree_trace=0;  /* True to enable tracing */

/*
** Forward declaration
*/
static int checkReadLocks(Btree*,Pgno,BtCursor*);

/*
** Read or write a two- and four-byte big-endian integer values.
*/
static u32 get2byte(unsigned char *p){
  return (p[0]<<8) | p[1];
}
static u32 get4byte(unsigned char *p){
  return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
static void put2byte(unsigned char *p, u32 v){
  p[0] = v>>8;
  p[1] = v;
}
static void put4byte(unsigned char *p, u32 v){
  p[0] = v>>24;
  p[1] = v>>16;
  p[2] = v>>8;
  p[3] = v;
}

/*
** Routines to read and write variable-length integers.  These used to
** be defined locally, but now we use the varint routines in the util.c
** file.
*/
#define getVarint    sqlite3GetVarint
#define getVarint32  sqlite3GetVarint32
#define putVarint    sqlite3PutVarint

/* The database page the PENDING_BYTE occupies. This page is never used.
** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
** should possibly be consolidated (presumably in pager.h).
*/
#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** These macros define the location of the pointer-map entry for a 
** database page. The first argument to each is the number of usable
** bytes on each page of the database (often 1024). The second is the
** page number to look up in the pointer map.
**
** PTRMAP_PAGENO returns the database page number of the pointer-map
** page that stores the required pointer. PTRMAP_PTROFFSET returns
** the offset of the requested map entry.
**
** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
** this test.
*/
#define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2)
#define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5)
#define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno)

/*
** The pointer map is a lookup table that identifies the parent page for
** each child page in the database file.  The parent page is the page that
** contains a pointer to the child.  Every page in the database contains
** 0 or 1 parent pages.  (In this context 'database page' refers
** to any page that is not part of the pointer map itself.)  Each pointer map
** entry consists of a single byte 'type' and a 4 byte parent page number.
** The PTRMAP_XXX identifiers below are the valid types.
**
** The purpose of the pointer map is to facility moving pages from one
** position in the file to another as part of autovacuum.  When a page
** is moved, the pointer in its parent must be updated to point to the
** new location.  The pointer map is used to locate the parent page quickly.
**
** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
**                  used in this case.
**
** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number 
**                  is not used in this case.
**
** PTRMAP_OVERFLOW1: The database page is the first page in a list of 
**                   overflow pages. The page number identifies the page that
**                   contains the cell with a pointer to this overflow page.
**
** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
**                   overflow pages. The page-number identifies the previous
**                   page in the overflow page list.
**
** PTRMAP_BTREE: The database page is a non-root btree page. The page number
**               identifies the parent page in the btree.
*/
#define PTRMAP_ROOTPAGE 1
#define PTRMAP_FREEPAGE 2
#define PTRMAP_OVERFLOW1 3
#define PTRMAP_OVERFLOW2 4
#define PTRMAP_BTREE 5

/*
** Write an entry into the pointer map.
**
** This routine updates the pointer map entry for page number 'key'
** so that it maps to type 'eType' and parent page number 'pgno'.
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
*/
static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno parent){
  u8 *pPtrmap;    /* The pointer map page */
  Pgno iPtrmap;   /* The pointer map page number */
  int offset;     /* Offset in pointer map page */
  int rc;

  assert( pBt->autoVacuum );
  if( key==0 ){
    return SQLITE_CORRUPT;
  }
  iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
  rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  offset = PTRMAP_PTROFFSET(pBt->usableSize, key);

  if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
    TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
    rc = sqlite3pager_write(pPtrmap);
    if( rc==SQLITE_OK ){
      pPtrmap[offset] = eType;
      put4byte(&pPtrmap[offset+1], parent);
    }
  }

  sqlite3pager_unref(pPtrmap);
  return rc;
}

/*
** Read an entry from the pointer map.
**
** This routine retrieves the pointer map entry for page 'key', writing
** the type and parent page number to *pEType and *pPgno respectively.
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
*/
static int ptrmapGet(Btree *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
  int iPtrmap;       /* Pointer map page index */
  u8 *pPtrmap;       /* Pointer map page data */
  int offset;        /* Offset of entry in pointer map */
  int rc;

  iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
  rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
  if( rc!=0 ){
    return rc;
  }

  offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
  if( pEType ) *pEType = pPtrmap[offset];
  if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);

  sqlite3pager_unref(pPtrmap);
  if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT;
  return SQLITE_OK;
}

#endif /* SQLITE_OMIT_AUTOVACUUM */

/*
** Given a btree page and a cell index (0 means the first cell on
** the page, 1 means the second cell, and so forth) return a pointer
** to the cell content.
**
** This routine works only for pages that do not contain overflow cells.
*/
static u8 *findCell(MemPage *pPage, int iCell){
  u8 *data = pPage->aData;
  assert( iCell>=0 );
  assert( iCell<get2byte(&data[pPage->hdrOffset+3]) );
  return data + get2byte(&data[pPage->cellOffset+2*iCell]);
}

/*
** This a more complex version of findCell() that works for
** pages that do contain overflow cells.  See insert
*/
static u8 *findOverflowCell(MemPage *pPage, int iCell){
  int i;
  for(i=pPage->nOverflow-1; i>=0; i--){
    int k;
    struct _OvflCell *pOvfl;
    pOvfl = &pPage->aOvfl[i];
    k = pOvfl->idx;
    if( k<=iCell ){
      if( k==iCell ){
        return pOvfl->pCell;
      }
      iCell--;
    }
  }
  return findCell(pPage, iCell);
}

/*
** Parse a cell content block and fill in the CellInfo structure.  There
** are two versions of this function.  parseCell() takes a cell index
** as the second argument and parseCellPtr() takes a pointer to the
** body of the cell as its second argument.
*/
static void parseCellPtr(
  MemPage *pPage,         /* Page containing the cell */
  u8 *pCell,              /* Pointer to the cell text. */
  CellInfo *pInfo         /* Fill in this structure */
){
  int n;                  /* Number bytes in cell content header */
  u32 nPayload;           /* Number of bytes of cell payload */

  pInfo->pCell = pCell;
  assert( pPage->leaf==0 || pPage->leaf==1 );
  n = pPage->childPtrSize;
  assert( n==4-4*pPage->leaf );
  if( pPage->hasData ){
    n += getVarint32(&pCell[n], &nPayload);
  }else{
    nPayload = 0;
  }
  n += getVarint(&pCell[n], (u64 *)&pInfo->nKey);
  pInfo->nHeader = n;
  pInfo->nData = nPayload;
  if( !pPage->intKey ){
    nPayload += pInfo->nKey;
  }
  if( nPayload<=pPage->maxLocal ){
    /* This is the (easy) common case where the entire payload fits
    ** on the local page.  No overflow is required.
    */
    int nSize;          /* Total size of cell content in bytes */
    pInfo->nLocal = nPayload;
    pInfo->iOverflow = 0;
    nSize = nPayload + n;
    if( nSize<4 ){
      nSize = 4;        /* Minimum cell size is 4 */
    }
    pInfo->nSize = nSize;
  }else{
    /* If the payload will not fit completely on the local page, we have
    ** to decide how much to store locally and how much to spill onto
    ** overflow pages.  The strategy is to minimize the amount of unused
    ** space on overflow pages while keeping the amount of local storage
    ** in between minLocal and maxLocal.
    **
    ** Warning:  changing the way overflow payload is distributed in any
    ** way will result in an incompatible file format.
    */
    int minLocal;  /* Minimum amount of payload held locally */
    int maxLocal;  /* Maximum amount of payload held locally */
    int surplus;   /* Overflow payload available for local storage */

    minLocal = pPage->minLocal;
    maxLocal = pPage->maxLocal;
    surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
    if( surplus <= maxLocal ){
      pInfo->nLocal = surplus;
    }else{
      pInfo->nLocal = minLocal;
    }
    pInfo->iOverflow = pInfo->nLocal + n;
    pInfo->nSize = pInfo->iOverflow + 4;
  }
}
static void parseCell(
  MemPage *pPage,         /* Page containing the cell */
  int iCell,              /* The cell index.  First cell is 0 */
  CellInfo *pInfo         /* Fill in this structure */
){
  parseCellPtr(pPage, findCell(pPage, iCell), pInfo);
}

/*
** Compute the total number of bytes that a Cell needs in the cell
** data area of the btree-page.  The return number includes the cell
** data header and the local payload, but not any overflow page or
** the space used by the cell pointer.
*/
#ifndef NDEBUG
static int cellSize(MemPage *pPage, int iCell){
  CellInfo info;
  parseCell(pPage, iCell, &info);
  return info.nSize;
}
#endif
static int cellSizePtr(MemPage *pPage, u8 *pCell){
  CellInfo info;
  parseCellPtr(pPage, pCell, &info);
  return info.nSize;
}

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** If the cell pCell, part of page pPage contains a pointer
** to an overflow page, insert an entry into the pointer-map
** for the overflow page.
*/
static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
  if( pCell ){
    CellInfo info;
    parseCellPtr(pPage, pCell, &info);
    if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
      Pgno ovfl = get4byte(&pCell[info.iOverflow]);
      return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
    }
  }
  return SQLITE_OK;
}
/*
** If the cell with index iCell on page pPage contains a pointer
** to an overflow page, insert an entry into the pointer-map
** for the overflow page.
*/
static int ptrmapPutOvfl(MemPage *pPage, int iCell){
  u8 *pCell;
  pCell = findOverflowCell(pPage, iCell);
  return ptrmapPutOvflPtr(pPage, pCell);
}
#endif


/*
** Do sanity checking on a page.  Throw an exception if anything is
** not right.
**
** This routine is used for internal error checking only.  It is omitted
** from most builds.
*/
#if defined(BTREE_DEBUG) && !defined(NDEBUG) && 0
static void _pageIntegrity(MemPage *pPage){
  int usableSize;
  u8 *data;
  int i, j, idx, c, pc, hdr, nFree;
  int cellOffset;
  int nCell, cellLimit;
  u8 *used;

  used = sqliteMallocRaw( pPage->pBt->pageSize );
  if( used==0 ) return;
  usableSize = pPage->pBt->usableSize;
  assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->psAligned] );
  hdr = pPage->hdrOffset;
  assert( hdr==(pPage->pgno==1 ? 100 : 0) );
  assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
  c = pPage->aData[hdr];
  if( pPage->isInit ){
    assert( pPage->leaf == ((c & PTF_LEAF)!=0) );
    assert( pPage->zeroData == ((c & PTF_ZERODATA)!=0) );
    assert( pPage->leafData == ((c & PTF_LEAFDATA)!=0) );
    assert( pPage->intKey == ((c & (PTF_INTKEY|PTF_LEAFDATA))!=0) );
    assert( pPage->hasData ==
             !(pPage->zeroData || (!pPage->leaf && pPage->leafData)) );
    assert( pPage->cellOffset==pPage->hdrOffset+12-4*pPage->leaf );
    assert( pPage->nCell = get2byte(&pPage->aData[hdr+3]) );
  }
  data = pPage->aData;
  memset(used, 0, usableSize);
  for(i=0; i<hdr+10-pPage->leaf*4; i++) used[i] = 1;
  nFree = 0;
  pc = get2byte(&data[hdr+1]);
  while( pc ){
    int size;
    assert( pc>0 && pc<usableSize-4 );
    size = get2byte(&data[pc+2]);
    assert( pc+size<=usableSize );
    nFree += size;
    for(i=pc; i<pc+size; i++){
      assert( used[i]==0 );
      used[i] = 1;
    }
    pc = get2byte(&data[pc]);
  }
  idx = 0;
  nCell = get2byte(&data[hdr+3]);
  cellLimit = get2byte(&data[hdr+5]);
  assert( pPage->isInit==0 
         || pPage->nFree==nFree+data[hdr+7]+cellLimit-(cellOffset+2*nCell) );
  cellOffset = pPage->cellOffset;
  for(i=0; i<nCell; i++){
    int size;
    pc = get2byte(&data[cellOffset+2*i]);
    assert( pc>0 && pc<usableSize-4 );
    size = cellSize(pPage, &data[pc]);
    assert( pc+size<=usableSize );
    for(j=pc; j<pc+size; j++){
      assert( used[j]==0 );
      used[j] = 1;
    }
  }
  for(i=cellOffset+2*nCell; i<cellimit; i++){
    assert( used[i]==0 );
    used[i] = 1;
  }
  nFree = 0;
  for(i=0; i<usableSize; i++){
    assert( used[i]<=1 );
    if( used[i]==0 ) nFree++;
  }
  assert( nFree==data[hdr+7] );
  sqliteFree(used);
}
#define pageIntegrity(X) _pageIntegrity(X)
#else
# define pageIntegrity(X)
#endif

/*
** Defragment the page given.  All Cells are moved to the
** beginning of the page and all free space is collected 
** into one big FreeBlk at the end of the page.
*/
static int defragmentPage(MemPage *pPage){
  int i;                     /* Loop counter */
  int pc;                    /* Address of a i-th cell */
  int addr;                  /* Offset of first byte after cell pointer array */
  int hdr;                   /* Offset to the page header */
  int size;                  /* Size of a cell */
  int usableSize;            /* Number of usable bytes on a page */
  int cellOffset;            /* Offset to the cell pointer array */
  int brk;                   /* Offset to the cell content area */
  int nCell;                 /* Number of cells on the page */
  unsigned char *data;       /* The page data */
  unsigned char *temp;       /* Temp area for cell content */

  assert( sqlite3pager_iswriteable(pPage->aData) );
  assert( pPage->pBt!=0 );
  assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
  assert( pPage->nOverflow==0 );
  temp = sqliteMalloc( pPage->pBt->pageSize );
  if( temp==0 ) return SQLITE_NOMEM;
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  cellOffset = pPage->cellOffset;
  nCell = pPage->nCell;
  assert( nCell==get2byte(&data[hdr+3]) );
  usableSize = pPage->pBt->usableSize;
  brk = get2byte(&data[hdr+5]);
  memcpy(&temp[brk], &data[brk], usableSize - brk);
  brk = usableSize;
  for(i=0; i<nCell; i++){
    u8 *pAddr;     /* The i-th cell pointer */
    pAddr = &data[cellOffset + i*2];
    pc = get2byte(pAddr);
    assert( pc<pPage->pBt->usableSize );
    size = cellSizePtr(pPage, &temp[pc]);
    brk -= size;
    memcpy(&data[brk], &temp[pc], size);
    put2byte(pAddr, brk);
  }
  assert( brk>=cellOffset+2*nCell );
  put2byte(&data[hdr+5], brk);
  data[hdr+1] = 0;
  data[hdr+2] = 0;
  data[hdr+7] = 0;
  addr = cellOffset+2*nCell;
  memset(&data[addr], 0, brk-addr);
  sqliteFree(temp);
  return SQLITE_OK;
}

/*
** Allocate nByte bytes of space on a page.
**
** Return the index into pPage->aData[] of the first byte of
** the new allocation. Or return 0 if there is not enough free
** space on the page to satisfy the allocation request.
**
** If the page contains nBytes of free space but does not contain
** nBytes of contiguous free space, then this routine automatically
** calls defragementPage() to consolidate all free space before 
** allocating the new chunk.
*/
static int allocateSpace(MemPage *pPage, int nByte){
  int addr, pc, hdr;
  int size;
  int nFrag;
  int top;
  int nCell;
  int cellOffset;
  unsigned char *data;
  
  data = pPage->aData;
  assert( sqlite3pager_iswriteable(data) );
  assert( pPage->pBt );
  if( nByte<4 ) nByte = 4;
  if( pPage->nFree<nByte || pPage->nOverflow>0 ) return 0;
  pPage->nFree -= nByte;
  hdr = pPage->hdrOffset;

  nFrag = data[hdr+7];
  if( nFrag<60 ){
    /* Search the freelist looking for a slot big enough to satisfy the
    ** space request. */
    addr = hdr+1;
    while( (pc = get2byte(&data[addr]))>0 ){
      size = get2byte(&data[pc+2]);
      if( size>=nByte ){
        if( size<nByte+4 ){
          memcpy(&data[addr], &data[pc], 2);
          data[hdr+7] = nFrag + size - nByte;
          return pc;
        }else{
          put2byte(&data[pc+2], size-nByte);
          return pc + size - nByte;
        }
      }
      addr = pc;
    }
  }

  /* Allocate memory from the gap in between the cell pointer array
  ** and the cell content area.
  */
  top = get2byte(&data[hdr+5]);
  nCell = get2byte(&data[hdr+3]);
  cellOffset = pPage->cellOffset;
  if( nFrag>=60 || cellOffset + 2*nCell > top - nByte ){
    if( defragmentPage(pPage) ) return 0;
    top = get2byte(&data[hdr+5]);
  }
  top -= nByte;
  assert( cellOffset + 2*nCell <= top );
  put2byte(&data[hdr+5], top);
  return top;
}

/*
** Return a section of the pPage->aData to the freelist.
** The first byte of the new free block is pPage->aDisk[start]
** and the size of the block is "size" bytes.
**
** Most of the effort here is involved in coalesing adjacent
** free blocks into a single big free block.
*/
static void freeSpace(MemPage *pPage, int start, int size){
  int addr, pbegin, hdr;
  unsigned char *data = pPage->aData;

  assert( pPage->pBt!=0 );
  assert( sqlite3pager_iswriteable(data) );
  assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
  assert( (start + size)<=pPage->pBt->usableSize );
  if( size<4 ) size = 4;

  /* Add the space back into the linked list of freeblocks */
  hdr = pPage->hdrOffset;
  addr = hdr + 1;
  while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
    assert( pbegin<=pPage->pBt->usableSize-4 );
    assert( pbegin>addr );
    addr = pbegin;
  }
  assert( pbegin<=pPage->pBt->usableSize-4 );
  assert( pbegin>addr || pbegin==0 );
  put2byte(&data[addr], start);
  put2byte(&data[start], pbegin);
  put2byte(&data[start+2], size);
  pPage->nFree += size;

  /* Coalesce adjacent free blocks */
  addr = pPage->hdrOffset + 1;
  while( (pbegin = get2byte(&data[addr]))>0 ){
    int pnext, psize;
    assert( pbegin>addr );
    assert( pbegin<=pPage->pBt->usableSize-4 );
    pnext = get2byte(&data[pbegin]);
    psize = get2byte(&data[pbegin+2]);
    if( pbegin + psize + 3 >= pnext && pnext>0 ){
      int frag = pnext - (pbegin+psize);
      assert( frag<=data[pPage->hdrOffset+7] );
      data[pPage->hdrOffset+7] -= frag;
      put2byte(&data[pbegin], get2byte(&data[pnext]));
      put2byte(&data[pbegin+2], pnext+get2byte(&data[pnext+2])-pbegin);
    }else{
      addr = pbegin;
    }
  }

  /* If the cell content area begins with a freeblock, remove it. */
  if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
    int top;
    pbegin = get2byte(&data[hdr+1]);
    memcpy(&data[hdr+1], &data[pbegin], 2);
    top = get2byte(&data[hdr+5]);
    put2byte(&data[hdr+5], top + get2byte(&data[pbegin+2]));
  }
}

/*
** Decode the flags byte (the first byte of the header) for a page
** and initialize fields of the MemPage structure accordingly.
*/
static void decodeFlags(MemPage *pPage, int flagByte){
  Btree *pBt;     /* A copy of pPage->pBt */

  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
  pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0;
  pPage->zeroData = (flagByte & PTF_ZERODATA)!=0;
  pPage->leaf = (flagByte & PTF_LEAF)!=0;
  pPage->childPtrSize = 4*(pPage->leaf==0);
  pBt = pPage->pBt;
  if( flagByte & PTF_LEAFDATA ){
    pPage->leafData = 1;
    pPage->maxLocal = pBt->maxLeaf;
    pPage->minLocal = pBt->minLeaf;
  }else{
    pPage->leafData = 0;
    pPage->maxLocal = pBt->maxLocal;
    pPage->minLocal = pBt->minLocal;
  }
  pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
}

/*
** Initialize the auxiliary information for a disk block.
**
** The pParent parameter must be a pointer to the MemPage which
** is the parent of the page being initialized.  The root of a
** BTree has no parent and so for that page, pParent==NULL.
**
** Return SQLITE_OK on success.  If we see that the page does
** not contain a well-formed database page, then return 
** SQLITE_CORRUPT.  Note that a return of SQLITE_OK does not
** guarantee that the page is well-formed.  It only shows that
** we failed to detect any corruption.
*/
static int initPage(
  MemPage *pPage,        /* The page to be initialized */
  MemPage *pParent       /* The parent.  Might be NULL */
){
  int pc;            /* Address of a freeblock within pPage->aData[] */
  int hdr;           /* Offset to beginning of page header */
  u8 *data;          /* Equal to pPage->aData */
  Btree *pBt;        /* The main btree structure */
  int usableSize;    /* Amount of usable space on each page */
  int cellOffset;    /* Offset from start of page to first cell pointer */
  int nFree;         /* Number of unused bytes on the page */
  int top;           /* First byte of the cell content area */

  pBt = pPage->pBt;
  assert( pBt!=0 );
  assert( pParent==0 || pParent->pBt==pBt );
  assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
  assert( pPage->aData == &((unsigned char*)pPage)[-pBt->psAligned] );
  if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
    /* The parent page should never change unless the file is corrupt */
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }
  if( pPage->isInit ) return SQLITE_OK;
  if( pPage->pParent==0 && pParent!=0 ){
    pPage->pParent = pParent;
    sqlite3pager_ref(pParent->aData);
  }
  hdr = pPage->hdrOffset;
  data = pPage->aData;
  decodeFlags(pPage, data[hdr]);
  pPage->nOverflow = 0;
  pPage->idxShift = 0;
  usableSize = pBt->usableSize;
  pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
  top = get2byte(&data[hdr+5]);
  pPage->nCell = get2byte(&data[hdr+3]);
  if( pPage->nCell>MX_CELL(pBt) ){
    /* To many cells for a single page.  The page must be corrupt */
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }
  if( pPage->nCell==0 && pParent!=0 && pParent->pgno!=1 ){
    /* All pages must have at least one cell, except for root pages */
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }

  /* Compute the total free space on the page */
  pc = get2byte(&data[hdr+1]);
  nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
  while( pc>0 ){
    int next, size;
    if( pc>usableSize-4 ){
      /* Free block is off the page */
      return SQLITE_CORRUPT;  /* bkpt-CORRUPT */
    }
    next = get2byte(&data[pc]);
    size = get2byte(&data[pc+2]);
    if( next>0 && next<=pc+size+3 ){
      /* Free blocks must be in accending order */
      return SQLITE_CORRUPT;  /* bkpt-CORRUPT */
    }
    nFree += size;
    pc = next;
  }
  pPage->nFree = nFree;
  if( nFree>=usableSize ){
    /* Free space cannot exceed total page size */
    return SQLITE_CORRUPT;  /* bkpt-CORRUPT */
  }

  pPage->isInit = 1;
  pageIntegrity(pPage);
  return SQLITE_OK;
}

/*
** Set up a raw page so that it looks like a database page holding
** no entries.
*/
static void zeroPage(MemPage *pPage, int flags){
  unsigned char *data = pPage->aData;
  Btree *pBt = pPage->pBt;
  int hdr = pPage->hdrOffset;
  int first;

  assert( sqlite3pager_pagenumber(data)==pPage->pgno );
  assert( &data[pBt->psAligned] == (unsigned char*)pPage );
  assert( sqlite3pager_iswriteable(data) );
  memset(&data[hdr], 0, pBt->usableSize - hdr);
  data[hdr] = flags;
  first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
  memset(&data[hdr+1], 0, 4);
  data[hdr+7] = 0;
  put2byte(&data[hdr+5], pBt->usableSize);
  pPage->nFree = pBt->usableSize - first;
  decodeFlags(pPage, flags);
  pPage->hdrOffset = hdr;
  pPage->cellOffset = first;
  pPage->nOverflow = 0;
  pPage->idxShift = 0;
  pPage->nCell = 0;
  pPage->isInit = 1;
  pageIntegrity(pPage);
}

/*
** Get a page from the pager.  Initialize the MemPage.pBt and
** MemPage.aData elements if needed.
*/
static int getPage(Btree *pBt, Pgno pgno, MemPage **ppPage){
  int rc;
  unsigned char *aData;
  MemPage *pPage;
  rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData);
  if( rc ) return rc;
  pPage = (MemPage*)&aData[pBt->psAligned];
  pPage->aData = aData;
  pPage->pBt = pBt;
  pPage->pgno = pgno;
  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
  *ppPage = pPage;
  return SQLITE_OK;
}

/*
** Get a page from the pager and initialize it.  This routine
** is just a convenience wrapper around separate calls to
** getPage() and initPage().
*/
static int getAndInitPage(
  Btree *pBt,          /* The database file */
  Pgno pgno,           /* Number of the page to get */
  MemPage **ppPage,    /* Write the page pointer here */
  MemPage *pParent     /* Parent of the page */
){
  int rc;
  if( pgno==0 ){
    return SQLITE_CORRUPT;  /* bkpt-CORRUPT */
  }
  rc = getPage(pBt, pgno, ppPage);
  if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
    rc = initPage(*ppPage, pParent);
  }
  return rc;
}

/*
** Release a MemPage.  This should be called once for each prior
** call to getPage.
*/
static void releasePage(MemPage *pPage){
  if( pPage ){
    assert( pPage->aData );
    assert( pPage->pBt );
    assert( &pPage->aData[pPage->pBt->psAligned]==(unsigned char*)pPage );
    sqlite3pager_unref(pPage->aData);
  }
}

/*
** This routine is called when the reference count for a page
** reaches zero.  We need to unref the pParent pointer when that
** happens.
*/
static void pageDestructor(void *pData, int pageSize){
  MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)];
  if( pPage->pParent ){
    MemPage *pParent = pPage->pParent;
    pPage->pParent = 0;
    releasePage(pParent);
  }
  pPage->isInit = 0;
}

/*
** During a rollback, when the pager reloads information into the cache
** so that the cache is restored to its original state at the start of
** the transaction, for each page restored this routine is called.
**
** This routine needs to reset the extra data section at the end of the
** page to agree with the restored data.
*/
static void pageReinit(void *pData, int pageSize){
  MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)];
  if( pPage->isInit ){
    pPage->isInit = 0;
    initPage(pPage, pPage->pParent);
  }
}

/*
** Open a database file.
** 
** zFilename is the name of the database file.  If zFilename is NULL
** a new database with a random name is created.  This randomly named
** database file will be deleted when sqlite3BtreeClose() is called.
*/
int sqlite3BtreeOpen(
  const char *zFilename,  /* Name of the file containing the BTree database */
  Btree **ppBtree,        /* Pointer to new Btree object written here */
  int flags               /* Options */
){
  Btree *pBt;
  int rc;
  int nReserve;
  unsigned char zDbHeader[100];

  /*
  ** The following asserts make sure that structures used by the btree are
  ** the right size.  This is to guard against size changes that result
  ** when compiling on a different architecture.
  */
  assert( sizeof(i64)==8 );
  assert( sizeof(u64)==8 );
  assert( sizeof(u32)==4 );
  assert( sizeof(u16)==2 );
  assert( sizeof(Pgno)==4 );
  assert( sizeof(ptr)==sizeof(char*) );
  assert( sizeof(uptr)==sizeof(ptr) );

  pBt = sqliteMalloc( sizeof(*pBt) );
  if( pBt==0 ){
    *ppBtree = 0;
    return SQLITE_NOMEM;
  }
  rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
  if( rc!=SQLITE_OK ){
    if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
    sqliteFree(pBt);
    *ppBtree = 0;
    return rc;
  }
  sqlite3pager_set_destructor(pBt->pPager, pageDestructor);
  sqlite3pager_set_reiniter(pBt->pPager, pageReinit);
  pBt->pCursor = 0;
  pBt->pPage1 = 0;
  pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
  sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader);
  pBt->pageSize = get2byte(&zDbHeader[16]);
  if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE ){
    pBt->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
    pBt->maxEmbedFrac = 64;   /* 25% */
    pBt->minEmbedFrac = 32;   /* 12.5% */
    pBt->minLeafFrac = 32;    /* 12.5% */
#ifndef SQLITE_OMIT_AUTOVACUUM
    /* If the magic name ":memory:" will create an in-memory database, then
    ** do not set the auto-vacuum flag, even if SQLITE_DEFAULT_AUTOVACUUM
    ** is true. On the other hand, if SQLITE_OMIT_MEMORYDB has been defined,
    ** then ":memory:" is just a regular file-name. Respect the auto-vacuum
    ** default in this case.
    */
#ifndef SQLITE_OMIT_MEMORYDB
    if( zFilename && strcmp(zFilename,":memory:") ){
#else
    if( zFilename ){
#endif
      pBt->autoVacuum = SQLITE_DEFAULT_AUTOVACUUM;
    }
#endif
    nReserve = 0;
  }else{
    nReserve = zDbHeader[20];
    pBt->maxEmbedFrac = zDbHeader[21];
    pBt->minEmbedFrac = zDbHeader[22];
    pBt->minLeafFrac = zDbHeader[23];
    pBt->pageSizeFixed = 1;
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
#endif
  }
  pBt->usableSize = pBt->pageSize - nReserve;
  pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize);
  sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);
  *ppBtree = pBt;
  return SQLITE_OK;
}

/*
** Close an open database and invalidate all cursors.
*/
int sqlite3BtreeClose(Btree *pBt){
  while( pBt->pCursor ){
    sqlite3BtreeCloseCursor(pBt->pCursor);
  }
  sqlite3pager_close(pBt->pPager);
  sqliteFree(pBt);
  return SQLITE_OK;
}

/*
** Change the busy handler callback function.
*/
int sqlite3BtreeSetBusyHandler(Btree *pBt, BusyHandler *pHandler){
  sqlite3pager_set_busyhandler(pBt->pPager, pHandler);
  return SQLITE_OK;
}

/*
** Change the limit on the number of pages allowed in the cache.
**
** The maximum number of cache pages is set to the absolute
** value of mxPage.  If mxPage is negative, the pager will
** operate asynchronously - it will not stop to do fsync()s
** to insure data is written to the disk surface before
** continuing.  Transactions still work if synchronous is off,
** and the database cannot be corrupted if this program
** crashes.  But if the operating system crashes or there is
** an abrupt power failure when synchronous is off, the database
** could be left in an inconsistent and unrecoverable state.
** Synchronous is on by default so database corruption is not
** normally a worry.
*/
int sqlite3BtreeSetCacheSize(Btree *pBt, int mxPage){
  sqlite3pager_set_cachesize(pBt->pPager, mxPage);
  return SQLITE_OK;
}

/*
** Change the way data is synced to disk in order to increase or decrease
** how well the database resists damage due to OS crashes and power
** failures.  Level 1 is the same as asynchronous (no syncs() occur and
** there is a high probability of damage)  Level 2 is the default.  There
** is a very low but non-zero probability of damage.  Level 3 reduces the
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){
  sqlite3pager_set_safety_level(pBt->pPager, level);
  return SQLITE_OK;
}
#endif

#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/*
** Change the default pages size and the number of reserved bytes per page.
**
** The page size must be a power of 2 between 512 and 65536.  If the page
** size supplied does not meet this constraint then the page size is not
** changed.
**
** Page sizes are constrained to be a power of two so that the region
** of the database file used for locking (beginning at PENDING_BYTE,
** the first byte past the 1GB boundary, 0x40000000) needs to occur
** at the beginning of a page.
**
** If parameter nReserve is less than zero, then the number of reserved
** bytes per page is left unchanged.
*/
int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){
  if( pBt->pageSizeFixed ){
    return SQLITE_READONLY;
  }
  if( nReserve<0 ){
    nReserve = pBt->pageSize - pBt->usableSize;
  }
  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
        ((pageSize-1)&pageSize)==0 ){
    pBt->pageSize = pageSize;
    pBt->psAligned = FORCE_ALIGNMENT(pageSize);
    sqlite3pager_set_pagesize(pBt->pPager, pageSize);
  }
  pBt->usableSize = pBt->pageSize - nReserve;
  return SQLITE_OK;
}

/*
** Return the currently defined page size
*/
int sqlite3BtreeGetPageSize(Btree *pBt){
  return pBt->pageSize;
}
int sqlite3BtreeGetReserve(Btree *pBt){
  return pBt->pageSize - pBt->usableSize;
}
#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */

/*
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
** is disabled. The default value for the auto-vacuum property is 
** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
*/
int sqlite3BtreeSetAutoVacuum(Btree *pBt, int autoVacuum){
#ifdef SQLITE_OMIT_AUTOVACUUM
  return SQLITE_READONLY;
#else
  if( pBt->pageSizeFixed ){
    return SQLITE_READONLY;
  }
  pBt->autoVacuum = (autoVacuum?1:0);
  return SQLITE_OK;
#endif
}

/*
** Return the value of the 'auto-vacuum' property. If auto-vacuum is 
** enabled 1 is returned. Otherwise 0.
*/
int sqlite3BtreeGetAutoVacuum(Btree *pBt){
#ifdef SQLITE_OMIT_AUTOVACUUM
  return 0;
#else
  return pBt->autoVacuum;
#endif
}


/*
** Get a reference to pPage1 of the database file.  This will
** also acquire a readlock on that file.
**
** SQLITE_OK is returned on success.  If the file is not a
** well-formed database file, then SQLITE_CORRUPT is returned.
** SQLITE_BUSY is returned if the database is locked.  SQLITE_NOMEM
** is returned if we run out of memory.  SQLITE_PROTOCOL is returned
** if there is a locking protocol violation.
*/
static int lockBtree(Btree *pBt){
  int rc;
  MemPage *pPage1;
  if( pBt->pPage1 ) return SQLITE_OK;
  rc = getPage(pBt, 1, &pPage1);
  if( rc!=SQLITE_OK ) return rc;
  

  /* Do some checking to help insure the file we opened really is
  ** a valid database file. 
  */
  rc = SQLITE_NOTADB;
  if( sqlite3pager_pagecount(pBt->pPager)>0 ){
    u8 *page1 = pPage1->aData;
    if( memcmp(page1, zMagicHeader, 16)!=0 ){
      goto page1_init_failed;
    }
    if( page1[18]>1 || page1[19]>1 ){
      goto page1_init_failed;
    }
    pBt->pageSize = get2byte(&page1[16]);
    pBt->usableSize = pBt->pageSize - page1[20];
    if( pBt->usableSize<500 ){
      goto page1_init_failed;
    }
    pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize);
    pBt->maxEmbedFrac = page1[21];
    pBt->minEmbedFrac = page1[22];
    pBt->minLeafFrac = page1[23];
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
#endif
  }

  /* maxLocal is the maximum amount of payload to store locally for
  ** a cell.  Make sure it is small enough so that at least minFanout
  ** cells can will fit on one page.  We assume a 10-byte page header.
  ** Besides the payload, the cell must store:
  **     2-byte pointer to the cell
  **     4-byte child pointer
  **     9-byte nKey value
  **     4-byte nData value
  **     4-byte overflow page pointer
  ** So a cell consists of a 2-byte poiner, a header which is as much as
  ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
  ** page pointer.
  */
  pBt->maxLocal = (pBt->usableSize-12)*pBt->maxEmbedFrac/255 - 23;
  pBt->minLocal = (pBt->usableSize-12)*pBt->minEmbedFrac/255 - 23;
  pBt->maxLeaf = pBt->usableSize - 35;
  pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23;
  if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){
    goto page1_init_failed;
  }
  assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
  pBt->pPage1 = pPage1;
  return SQLITE_OK;

page1_init_failed:
  releasePage(pPage1);
  pBt->pPage1 = 0;
  return rc;
}

/*
** If there are no outstanding cursors and we are not in the middle
** of a transaction but there is a read lock on the database, then
** this routine unrefs the first page of the database file which 
** has the effect of releasing the read lock.
**
** If there are any outstanding cursors, this routine is a no-op.
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(Btree *pBt){
  if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
    if( pBt->pPage1->aData==0 ){
      MemPage *pPage = pBt->pPage1;
      pPage->aData = &((char*)pPage)[-pBt->psAligned];
      pPage->pBt = pBt;
      pPage->pgno = 1;
    }
    releasePage(pBt->pPage1);
    pBt->pPage1 = 0;
    pBt->inStmt = 0;
  }
}

/*
** Create a new database by initializing the first page of the
** file.
*/
static int newDatabase(Btree *pBt){
  MemPage *pP1;
  unsigned char *data;
  int rc;
  if( sqlite3pager_pagecount(pBt->pPager)>0 ) return SQLITE_OK;
  pP1 = pBt->pPage1;
  assert( pP1!=0 );
  data = pP1->aData;
  rc = sqlite3pager_write(data);
  if( rc ) return rc;
  memcpy(data, zMagicHeader, sizeof(zMagicHeader));
  assert( sizeof(zMagicHeader)==16 );
  put2byte(&data[16], pBt->pageSize);
  data[18] = 1;
  data[19] = 1;
  data[20] = pBt->pageSize - pBt->usableSize;
  data[21] = pBt->maxEmbedFrac;
  data[22] = pBt->minEmbedFrac;
  data[23] = pBt->minLeafFrac;
  memset(&data[24], 0, 100-24);
  zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
  pBt->pageSizeFixed = 1;
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( pBt->autoVacuum ){
    put4byte(&data[36 + 4*4], 1);
  }
#endif
  return SQLITE_OK;
}

/*
** Attempt to start a new transaction. A write-transaction
** is started if the second argument is nonzero, otherwise a read-
** transaction.  If the second argument is 2 or more and exclusive
** transaction is started, meaning that no other process is allowed
** to access the database.  A preexisting transaction may not be
** upgrade to exclusive by calling this routine a second time - the
** exclusivity flag only works for a new transaction.
**
** A write-transaction must be started before attempting any 
** changes to the database.  None of the following routines 
** will work unless a transaction is started first:
**
**      sqlite3BtreeCreateTable()
**      sqlite3BtreeCreateIndex()
**      sqlite3BtreeClearTable()
**      sqlite3BtreeDropTable()
**      sqlite3BtreeInsert()
**      sqlite3BtreeDelete()
**      sqlite3BtreeUpdateMeta()
**
** If wrflag is true, then nMaster specifies the maximum length of
** a master journal file name supplied later via sqlite3BtreeSync().
** This is so that appropriate space can be allocated in the journal file
** when it is created..
*/
int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){
  int rc = SQLITE_OK;

  /* If the btree is already in a write-transaction, or it
  ** is already in a read-transaction and a read-transaction
  ** is requested, this is a no-op.
  */
  if( pBt->inTrans==TRANS_WRITE || 
      (pBt->inTrans==TRANS_READ && !wrflag) ){
    return SQLITE_OK;
  }
  if( pBt->readOnly && wrflag ){
    return SQLITE_READONLY;
  }

  if( pBt->pPage1==0 ){
    rc = lockBtree(pBt);
  }

  if( rc==SQLITE_OK && wrflag ){
    rc = sqlite3pager_begin(pBt->pPage1->aData, wrflag>1);
    if( rc==SQLITE_OK ){
      rc = newDatabase(pBt);
    }
  }

  if( rc==SQLITE_OK ){
    pBt->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
    if( wrflag ) pBt->inStmt = 0;
  }else{
    unlockBtreeIfUnused(pBt);
  }
  return rc;
}

#ifndef SQLITE_OMIT_AUTOVACUUM

/*
** Set the pointer-map entries for all children of page pPage. Also, if
** pPage contains cells that point to overflow pages, set the pointer
** map entries for the overflow pages as well.
*/
static int setChildPtrmaps(MemPage *pPage){
  int i;                             /* Counter variable */
  int nCell;                         /* Number of cells in page pPage */
  int rc = SQLITE_OK;                /* Return code */
  Btree *pBt = pPage->pBt;
  int isInitOrig = pPage->isInit;
  Pgno pgno = pPage->pgno;

  initPage(pPage, 0);
  nCell = pPage->nCell;

  for(i=0; i<nCell; i++){
    u8 *pCell = findCell(pPage, i);

    rc = ptrmapPutOvflPtr(pPage, pCell);
    if( rc!=SQLITE_OK ){
      goto set_child_ptrmaps_out;
    }

    if( !pPage->leaf ){
      Pgno childPgno = get4byte(pCell);
      rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
      if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
    }
  }

  if( !pPage->leaf ){
    Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
  }

set_child_ptrmaps_out:
  pPage->isInit = isInitOrig;
  return rc;
}

/*
** Somewhere on pPage, which is guarenteed to be a btree page, not an overflow
** page, is a pointer to page iFrom. Modify this pointer so that it points to
** iTo. Parameter eType describes the type of pointer to be modified, as 
** follows:
**
** PTRMAP_BTREE:     pPage is a btree-page. The pointer points at a child 
**                   page of pPage.
**
** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
**                   page pointed to by one of the cells on pPage.
**
** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
**                   overflow page in the list.
*/
static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
  if( eType==PTRMAP_OVERFLOW2 ){
    /* The pointer is always the first 4 bytes of the page in this case.  */
    if( get4byte(pPage->aData)!=iFrom ){
      return SQLITE_CORRUPT;
    }
    put4byte(pPage->aData, iTo);
  }else{
    int isInitOrig = pPage->isInit;
    int i;
    int nCell;

    initPage(pPage, 0);
    nCell = pPage->nCell;

    for(i=0; i<nCell; i++){
      u8 *pCell = findCell(pPage, i);
      if( eType==PTRMAP_OVERFLOW1 ){
        CellInfo info;
        parseCellPtr(pPage, pCell, &info);
        if( info.iOverflow ){
          if( iFrom==get4byte(&pCell[info.iOverflow]) ){
            put4byte(&pCell[info.iOverflow], iTo);
            break;
          }
        }
      }else{
        if( get4byte(pCell)==iFrom ){
          put4byte(pCell, iTo);
          break;
        }
      }
    }
  
    if( i==nCell ){
      if( eType!=PTRMAP_BTREE || 
          get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
        return SQLITE_CORRUPT;
      }
      put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
    }

    pPage->isInit = isInitOrig;
  }
  return SQLITE_OK;
}


/*
** Move the open database page pDbPage to location iFreePage in the 
** database. The pDbPage reference remains valid.
*/
static int relocatePage(
  Btree *pBt,              /* Btree */
  MemPage *pDbPage,        /* Open page to move */
  u8 eType,                /* Pointer map 'type' entry for pDbPage */
  Pgno iPtrPage,           /* Pointer map 'page-no' entry for pDbPage */
  Pgno iFreePage           /* The location to move pDbPage to */
){
  MemPage *pPtrPage;   /* The page that contains a pointer to pDbPage */
  Pgno iDbPage = pDbPage->pgno;
  Pager *pPager = pBt->pPager;
  int rc;

  assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || 
      eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );

  /* Move page iDbPage from it's current location to page number iFreePage */
  TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", 
      iDbPage, iFreePage, iPtrPage, eType));
  rc = sqlite3pager_movepage(pPager, pDbPage->aData, iFreePage);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  pDbPage->pgno = iFreePage;

  /* If pDbPage was a btree-page, then it may have child pages and/or cells
  ** that point to overflow pages. The pointer map entries for all these
  ** pages need to be changed.
  **
  ** If pDbPage is an overflow page, then the first 4 bytes may store a
  ** pointer to a subsequent overflow page. If this is the case, then
  ** the pointer map needs to be updated for the subsequent overflow page.
  */
  if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){
    rc = setChildPtrmaps(pDbPage);
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }else{
    Pgno nextOvfl = get4byte(pDbPage->aData);
    if( nextOvfl!=0 ){
      rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }
  }

  /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
  ** that it points at iFreePage. Also fix the pointer map entry for
  ** iPtrPage.
  */
  if( eType!=PTRMAP_ROOTPAGE ){
    rc = getPage(pBt, iPtrPage, &pPtrPage);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    rc = sqlite3pager_write(pPtrPage->aData);
    if( rc!=SQLITE_OK ){
      releasePage(pPtrPage);
      return rc;
    }
    rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
    releasePage(pPtrPage);
    if( rc==SQLITE_OK ){
      rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage);
    }
  }
  return rc;
}

/* Forward declaration required by autoVacuumCommit(). */
static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8);

/*
** This routine is called prior to sqlite3pager_commit when a transaction
** is commited for an auto-vacuum database.
*/
static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){
  Pager *pPager = pBt->pPager;
  Pgno nFreeList;   /* Number of pages remaining on the free-list. */
  int nPtrMap;      /* Number of pointer-map pages deallocated */
  Pgno origSize;  /* Pages in the database file */
  Pgno finSize;   /* Pages in the database file after truncation */
  int rc;           /* Return code */
  u8 eType;
  int pgsz = pBt->pageSize;  /* Page size for this database */
  Pgno iDbPage;              /* The database page to move */
  MemPage *pDbMemPage = 0;   /* "" */
  Pgno iPtrPage;             /* The page that contains a pointer to iDbPage */
  Pgno iFreePage;            /* The free-list page to move iDbPage to */
  MemPage *pFreeMemPage = 0; /* "" */

#ifndef NDEBUG
  int nRef = *sqlite3pager_stats(pPager);
#endif

  assert( pBt->autoVacuum );
  if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){
    return SQLITE_CORRUPT;
  }

  /* Figure out how many free-pages are in the database. If there are no
  ** free pages, then auto-vacuum is a no-op.
  */
  nFreeList = get4byte(&pBt->pPage1->aData[36]);
  if( nFreeList==0 ){
    *nTrunc = 0;
    return SQLITE_OK;
  }

  origSize = sqlite3pager_pagecount(pPager);
  nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5);
  finSize = origSize - nFreeList - nPtrMap;
  if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
    finSize--;
    if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){
      finSize--;
    }
  }
  TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize));

  /* Variable 'finSize' will be the size of the file in pages after
  ** the auto-vacuum has completed (the current file size minus the number
  ** of pages on the free list). Loop through the pages that lie beyond
  ** this mark, and if they are not already on the free list, move them
  ** to a free page earlier in the file (somewhere before finSize).
  */
  for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){
    /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
    if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
      continue;
    }

    rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
    assert( eType!=PTRMAP_ROOTPAGE );

    /* If iDbPage is free, do not swap it.  */
    if( eType==PTRMAP_FREEPAGE ){
      continue;
    }
    rc = getPage(pBt, iDbPage, &pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;

    /* Find the next page in the free-list that is not already at the end 
    ** of the file. A page can be pulled off the free list using the 
    ** allocatePage() routine.
    */
    do{
      if( pFreeMemPage ){
        releasePage(pFreeMemPage);
        pFreeMemPage = 0;
      }
      rc = allocatePage(pBt, &pFreeMemPage, &iFreePage, 0, 0);
      if( rc!=SQLITE_OK ){
        releasePage(pDbMemPage);
        goto autovacuum_out;
      }
      assert( iFreePage<=origSize );
    }while( iFreePage>finSize );
    releasePage(pFreeMemPage);
    pFreeMemPage = 0;

    rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage);
    releasePage(pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
  }

  /* The entire free-list has been swapped to the end of the file. So
  ** truncate the database file to finSize pages and consider the
  ** free-list empty.
  */
  rc = sqlite3pager_write(pBt->pPage1->aData);
  if( rc!=SQLITE_OK ) goto autovacuum_out;
  put4byte(&pBt->pPage1->aData[32], 0);
  put4byte(&pBt->pPage1->aData[36], 0);
  if( rc!=SQLITE_OK ) goto autovacuum_out;
  *nTrunc = finSize;

autovacuum_out:
  assert( nRef==*sqlite3pager_stats(pPager) );
  if( rc!=SQLITE_OK ){
    sqlite3pager_rollback(pPager);
  }
  return rc;
}
#endif

/*
** Commit the transaction currently in progress.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
*/
int sqlite3BtreeCommit(Btree *pBt){
  int rc = SQLITE_OK;
  if( pBt->inTrans==TRANS_WRITE ){
    rc = sqlite3pager_commit(pBt->pPager);
  }
  pBt->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);
  return rc;
}

#ifndef NDEBUG
/*
** Return the number of write-cursors open on this handle. This is for use
** in assert() expressions, so it is only compiled if NDEBUG is not
** defined.
*/
static int countWriteCursors(Btree *pBt){
  BtCursor *pCur;
  int r = 0;
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    if( pCur->wrFlag ) r++;
  }
  return r;
}
#endif

#ifdef SQLITE_TEST
/*
** Print debugging information about all cursors to standard output.
*/
void sqlite3BtreeCursorList(Btree *pBt){
  BtCursor *pCur;
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    MemPage *pPage = pCur->pPage;
    char *zMode = pCur->wrFlag ? "rw" : "ro";
    sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
       pCur, pCur->pgnoRoot, zMode,
       pPage ? pPage->pgno : 0, pCur->idx,
       pCur->isValid ? "" : " eof"
    );
  }
}
#endif

/*
** Rollback the transaction in progress.  All cursors will be
** invalided by this operation.  Any attempt to use a cursor
** that was open at the beginning of this operation will result
** in an error.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
*/
int sqlite3BtreeRollback(Btree *pBt){
  int rc = SQLITE_OK;
  MemPage *pPage1;
  if( pBt->inTrans==TRANS_WRITE ){
    rc = sqlite3pager_rollback(pBt->pPager);
    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call getPage() on page 1 again to make sure pPage1->aData is
    ** set correctly. */
    if( getPage(pBt, 1, &pPage1)==SQLITE_OK ){
      releasePage(pPage1);
    }
    assert( countWriteCursors(pBt)==0 );
  }
  pBt->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);
  return rc;
}

/*
** Start a statement subtransaction.  The subtransaction can
** can be rolled back independently of the main transaction.
** You must start a transaction before starting a subtransaction.
** The subtransaction is ended automatically if the main transaction
** commits or rolls back.
**
** Only one subtransaction may be active at a time.  It is an error to try
** to start a new subtransaction if another subtransaction is already active.
**
** Statement subtransactions are used around individual SQL statements
** that are contained within a BEGIN...COMMIT block.  If a constraint
** error occurs within the statement, the effect of that one statement
** can be rolled back without having to rollback the entire transaction.
*/
int sqlite3BtreeBeginStmt(Btree *pBt){
  int rc;
  if( (pBt->inTrans!=TRANS_WRITE) || pBt->inStmt ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  rc = pBt->readOnly ? SQLITE_OK : sqlite3pager_stmt_begin(pBt->pPager);
  pBt->inStmt = 1;
  return rc;
}


/*
** Commit the statment subtransaction currently in progress.  If no
** subtransaction is active, this is a no-op.
*/
int sqlite3BtreeCommitStmt(Btree *pBt){
  int rc;
  if( pBt->inStmt && !pBt->readOnly ){
    rc = sqlite3pager_stmt_commit(pBt->pPager);
  }else{
    rc = SQLITE_OK;
  }
  pBt->inStmt = 0;
  return rc;
}

/*
** Rollback the active statement subtransaction.  If no subtransaction
** is active this routine is a no-op.
**
** All cursors will be invalidated by this operation.  Any attempt
** to use a cursor that was open at the beginning of this operation
** will result in an error.
*/
int sqlite3BtreeRollbackStmt(Btree *pBt){
  int rc;
  if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
  rc = sqlite3pager_stmt_rollback(pBt->pPager);
  assert( countWriteCursors(pBt)==0 );
  pBt->inStmt = 0;
  return rc;
}

/*
** Default key comparison function to be used if no comparison function
** is specified on the sqlite3BtreeCursor() call.
*/
static int dfltCompare(
  void *NotUsed,             /* User data is not used */
  int n1, const void *p1,    /* First key to compare */
  int n2, const void *p2     /* Second key to compare */
){
  int c;
  c = memcmp(p1, p2, n1<n2 ? n1 : n2);
  if( c==0 ){
    c = n1 - n2;
  }
  return c;
}

/*
** Create a new cursor for the BTree whose root is on the page
** iTable.  The act of acquiring a cursor gets a read lock on 
** the database file.
**
** If wrFlag==0, then the cursor can only be used for reading.
** If wrFlag==1, then the cursor can be used for reading or for
** writing if other conditions for writing are also met.  These
** are the conditions that must be met in order for writing to
** be allowed:
**
** 1:  The cursor must have been opened with wrFlag==1
**
** 2:  No other cursors may be open with wrFlag==0 on the same table
**
** 3:  The database must be writable (not on read-only media)
**
** 4:  There must be an active transaction.
**
** Condition 2 warrants further discussion.  If any cursor is opened
** on a table with wrFlag==0, that prevents all other cursors from
** writing to that table.  This is a kind of "read-lock".  When a cursor
** is opened with wrFlag==0 it is guaranteed that the table will not
** change as long as the cursor is open.  This allows the cursor to
** do a sequential scan of the table without having to worry about
** entries being inserted or deleted during the scan.  Cursors should
** be opened with wrFlag==0 only if this read-lock property is needed.
** That is to say, cursors should be opened with wrFlag==0 only if they
** intend to use the sqlite3BtreeNext() system call.  All other cursors
** should be opened with wrFlag==1 even if they never really intend
** to write.
** 
** No checking is done to make sure that page iTable really is the
** root page of a b-tree.  If it is not, then the cursor acquired
** will not work correctly.
**
** The comparison function must be logically the same for every cursor
** on a particular table.  Changing the comparison function will result
** in incorrect operations.  If the comparison function is NULL, a
** default comparison function is used.  The comparison function is
** always ignored for INTKEY tables.
*/
int sqlite3BtreeCursor(
  Btree *pBt,                                 /* The btree */
  int iTable,                                 /* Root page of table to open */
  int wrFlag,                                 /* 1 to write. 0 read-only */
  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
  void *pArg,                                 /* First arg to xCompare() */
  BtCursor **ppCur                            /* Write new cursor here */
){
  int rc;
  BtCursor *pCur;

  *ppCur = 0;
  if( wrFlag ){
    if( pBt->readOnly ){
      return SQLITE_READONLY;
    }
    if( checkReadLocks(pBt, iTable, 0) ){
      return SQLITE_LOCKED;
    }
  }
  if( pBt->pPage1==0 ){
    rc = lockBtree(pBt);
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }
  pCur = sqliteMallocRaw( sizeof(*pCur) );
  if( pCur==0 ){
    rc = SQLITE_NOMEM;
    goto create_cursor_exception;
  }
  pCur->pgnoRoot = (Pgno)iTable;
  if( iTable==1 && sqlite3pager_pagecount(pBt->pPager)==0 ){
    rc = SQLITE_EMPTY;
    pCur->pPage = 0;
    goto create_cursor_exception;
  }
  pCur->pPage = 0;  /* For exit-handler, in case getAndInitPage() fails. */
  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0);
  if( rc!=SQLITE_OK ){
    goto create_cursor_exception;
  }
  pCur->xCompare = xCmp ? xCmp : dfltCompare;
  pCur->pArg = pArg;
  pCur->pBt = pBt;
  pCur->wrFlag = wrFlag;
  pCur->idx = 0;
  memset(&pCur->info, 0, sizeof(pCur->info));
  pCur->pNext = pBt->pCursor;
  if( pCur->pNext ){
    pCur->pNext->pPrev = pCur;
  }
  pCur->pPrev = 0;
  pBt->pCursor = pCur;
  pCur->isValid = 0;
  *ppCur = pCur;
  return SQLITE_OK;

create_cursor_exception:
  if( pCur ){
    releasePage(pCur->pPage);
    sqliteFree(pCur);
  }
  unlockBtreeIfUnused(pBt);
  return rc;
}

#if 0  /* Not Used */
/*
** Change the value of the comparison function used by a cursor.
*/
void sqlite3BtreeSetCompare(
  BtCursor *pCur,     /* The cursor to whose comparison function is changed */
  int(*xCmp)(void*,int,const void*,int,const void*), /* New comparison func */
  void *pArg          /* First argument to xCmp() */
){
  pCur->xCompare = xCmp ? xCmp : dfltCompare;
  pCur->pArg = pArg;
}
#endif

/*
** Close a cursor.  The read lock on the database file is released
** when the last cursor is closed.
*/
int sqlite3BtreeCloseCursor(BtCursor *pCur){
  Btree *pBt = pCur->pBt;
  if( pCur->pPrev ){
    pCur->pPrev->pNext = pCur->pNext;
  }else{
    pBt->pCursor = pCur->pNext;
  }
  if( pCur->pNext ){
    pCur->pNext->pPrev = pCur->pPrev;
  }
  releasePage(pCur->pPage);
  unlockBtreeIfUnused(pBt);
  sqliteFree(pCur);
  return SQLITE_OK;
}

/*
** Make a temporary cursor by filling in the fields of pTempCur.
** The temporary cursor is not on the cursor list for the Btree.
*/
static void getTempCursor(BtCursor *pCur, BtCursor *pTempCur){
  memcpy(pTempCur, pCur, sizeof(*pCur));
  pTempCur->pNext = 0;
  pTempCur->pPrev = 0;
  if( pTempCur->pPage ){
    sqlite3pager_ref(pTempCur->pPage->aData);
  }
}

/*
** Delete a temporary cursor such as was made by the CreateTemporaryCursor()
** function above.
*/
static void releaseTempCursor(BtCursor *pCur){
  if( pCur->pPage ){
    sqlite3pager_unref(pCur->pPage->aData);
  }
}

/*
** Make sure the BtCursor.info field of the given cursor is valid.
** If it is not already valid, call parseCell() to fill it in.
**
** BtCursor.info is a cache of the information in the current cell.
** Using this cache reduces the number of calls to parseCell().
*/
static void getCellInfo(BtCursor *pCur){
  if( pCur->info.nSize==0 ){
    parseCell(pCur->pPage, pCur->idx, &pCur->info);
  }else{
#ifndef NDEBUG
    CellInfo info;
    memset(&info, 0, sizeof(info));
    parseCell(pCur->pPage, pCur->idx, &info);
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
#endif
  }
}

/*
** Set *pSize to the size of the buffer needed to hold the value of
** the key for the current entry.  If the cursor is not pointing
** to a valid entry, *pSize is set to 0. 
**
** For a table with the INTKEY flag set, this routine returns the key
** itself, not the number of bytes in the key.
*/
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
  if( !pCur->isValid ){
    *pSize = 0;
  }else{
    getCellInfo(pCur);
    *pSize = pCur->info.nKey;
  }
  return SQLITE_OK;
}

/*
** Set *pSize to the number of bytes of data in the entry the
** cursor currently points to.  Always return SQLITE_OK.
** Failure is not possible.  If the cursor is not currently
** pointing to an entry (which can happen, for example, if
** the database is empty) then *pSize is set to 0.
*/
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  if( !pCur->isValid ){
    /* Not pointing at a valid entry - set *pSize to 0. */
    *pSize = 0;
  }else{
    getCellInfo(pCur);
    *pSize = pCur->info.nData;
  }
  return SQLITE_OK;
}

/*
** Read payload information from the entry that the pCur cursor is
** pointing to.  Begin reading the payload at "offset" and read
** a total of "amt" bytes.  Put the result in zBuf.
**
** This routine does not make a distinction between key and data.
** It just reads bytes from the payload area.  Data might appear
** on the main page or be scattered out on multiple overflow pages.
*/
static int getPayload(
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
  int offset,          /* Begin reading this far into payload */
  int amt,             /* Read this many bytes */
  unsigned char *pBuf, /* Write the bytes into this buffer */ 
  int skipKey          /* offset begins at data if this is true */
){
  unsigned char *aPayload;
  Pgno nextPage;
  int rc;
  MemPage *pPage;
  Btree *pBt;
  int ovflSize;
  u32 nKey;

  assert( pCur!=0 && pCur->pPage!=0 );
  assert( pCur->isValid );
  pBt = pCur->pBt;
  pPage = pCur->pPage;
  pageIntegrity(pPage);
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  getCellInfo(pCur);
  aPayload = pCur->info.pCell;
  aPayload += pCur->info.nHeader;
  if( pPage->intKey ){
    nKey = 0;
  }else{
    nKey = pCur->info.nKey;
  }
  assert( offset>=0 );
  if( skipKey ){
    offset += nKey;
  }
  if( offset+amt > nKey+pCur->info.nData ){
    return SQLITE_ERROR;
  }
  if( offset<pCur->info.nLocal ){
    int a = amt;
    if( a+offset>pCur->info.nLocal ){
      a = pCur->info.nLocal - offset;
    }
    memcpy(pBuf, &aPayload[offset], a);
    if( a==amt ){
      return SQLITE_OK;
    }
    offset = 0;
    pBuf += a;
    amt -= a;
  }else{
    offset -= pCur->info.nLocal;
  }
  ovflSize = pBt->usableSize - 4;
  if( amt>0 ){
    nextPage = get4byte(&aPayload[pCur->info.nLocal]);
    while( amt>0 && nextPage ){
      rc = sqlite3pager_get(pBt->pPager, nextPage, (void**)&aPayload);
      if( rc!=0 ){
        return rc;
      }
      nextPage = get4byte(aPayload);
      if( offset<ovflSize ){
        int a = amt;
        if( a + offset > ovflSize ){
          a = ovflSize - offset;
        }
        memcpy(pBuf, &aPayload[offset+4], a);
        offset = 0;
        amt -= a;
        pBuf += a;
      }else{
        offset -= ovflSize;
      }
      sqlite3pager_unref(aPayload);
    }
  }

  if( amt>0 ){
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }
  return SQLITE_OK;
}

/*
** Read part of the key associated with cursor pCur.  Exactly
** "amt" bytes will be transfered into pBuf[].  The transfer
** begins at "offset".
**
** Return SQLITE_OK on success or an error code if anything goes
** wrong.  An error is returned if "offset+amt" is larger than
** the available payload.
*/
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
  assert( pCur->isValid );
  assert( pCur->pPage!=0 );
  assert( pCur->pPage->intKey==0 );
  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  return getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
}

/*
** Read part of the data associated with cursor pCur.  Exactly
** "amt" bytes will be transfered into pBuf[].  The transfer
** begins at "offset".
**
** Return SQLITE_OK on success or an error code if anything goes
** wrong.  An error is returned if "offset+amt" is larger than
** the available payload.
*/
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
  assert( pCur->isValid );
  assert( pCur->pPage!=0 );
  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  return getPayload(pCur, offset, amt, pBuf, 1);
}

/*
** Return a pointer to payload information from the entry that the 
** pCur cursor is pointing to.  The pointer is to the beginning of
** the key if skipKey==0 and it points to the beginning of data if
** skipKey==1.  The number of bytes of available key/data is written
** into *pAmt.  If *pAmt==0, then the value returned will not be
** a valid pointer.
**
** This routine is an optimization.  It is common for the entire key
** and data to fit on the local page and for there to be no overflow
** pages.  When that is so, this routine can be used to access the
** key and data without making a copy.  If the key and/or data spills
** onto overflow pages, then getPayload() must be used to reassembly
** the key/data and copy it into a preallocated buffer.
**
** The pointer returned by this routine looks directly into the cached
** page of the database.  The data might change or move the next time
** any btree routine is called.
*/
static const unsigned char *fetchPayload(
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
  int *pAmt,           /* Write the number of available bytes here */
  int skipKey          /* read beginning at data if this is true */
){
  unsigned char *aPayload;
  MemPage *pPage;
  Btree *pBt;
  u32 nKey;
  int nLocal;

  assert( pCur!=0 && pCur->pPage!=0 );
  assert( pCur->isValid );
  pBt = pCur->pBt;
  pPage = pCur->pPage;
  pageIntegrity(pPage);
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  getCellInfo(pCur);
  aPayload = pCur->info.pCell;
  aPayload += pCur->info.nHeader;
  if( pPage->intKey ){
    nKey = 0;
  }else{
    nKey = pCur->info.nKey;
  }
  if( skipKey ){
    aPayload += nKey;
    nLocal = pCur->info.nLocal - nKey;
  }else{
    nLocal = pCur->info.nLocal;
    if( nLocal>nKey ){
      nLocal = nKey;
    }
  }
  *pAmt = nLocal;
  return aPayload;
}


/*
** For the entry that cursor pCur is point to, return as
** many bytes of the key or data as are available on the local
** b-tree page.  Write the number of available bytes into *pAmt.
**
** The pointer returned is ephemeral.  The key/data may move
** or be destroyed on the next call to any Btree routine.
**
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
*/
const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
  return (const void*)fetchPayload(pCur, pAmt, 0);
}
const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
  return (const void*)fetchPayload(pCur, pAmt, 1);
}


/*
** Move the cursor down to a new child page.  The newPgno argument is the
** page number of the child page to move to.
*/
static int moveToChild(BtCursor *pCur, u32 newPgno){
  int rc;
  MemPage *pNewPage;
  MemPage *pOldPage;
  Btree *pBt = pCur->pBt;

  assert( pCur->isValid );
  rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
  if( rc ) return rc;
  pageIntegrity(pNewPage);
  pNewPage->idxParent = pCur->idx;
  pOldPage = pCur->pPage;
  pOldPage->idxShift = 0;
  releasePage(pOldPage);
  pCur->pPage = pNewPage;
  pCur->idx = 0;
  pCur->info.nSize = 0;
  if( pNewPage->nCell<1 ){
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }
  return SQLITE_OK;
}

/*
** Return true if the page is the virtual root of its table.
**
** The virtual root page is the root page for most tables.  But
** for the table rooted on page 1, sometime the real root page
** is empty except for the right-pointer.  In such cases the
** virtual root page is the page that the right-pointer of page
** 1 is pointing to.
*/
static int isRootPage(MemPage *pPage){
  MemPage *pParent = pPage->pParent;
  if( pParent==0 ) return 1;
  if( pParent->pgno>1 ) return 0;
  if( get2byte(&pParent->aData[pParent->hdrOffset+3])==0 ) return 1;
  return 0;
}

/*
** Move the cursor up to the parent page.
**
** pCur->idx is set to the cell index that contains the pointer
** to the page we are coming from.  If we are coming from the
** right-most child page then pCur->idx is set to one more than
** the largest cell index.
*/
static void moveToParent(BtCursor *pCur){
  Pgno oldPgno;
  MemPage *pParent;
  MemPage *pPage;
  int idxParent;

  assert( pCur->isValid );
  pPage = pCur->pPage;
  assert( pPage!=0 );
  assert( !isRootPage(pPage) );
  pageIntegrity(pPage);
  pParent = pPage->pParent;
  assert( pParent!=0 );
  pageIntegrity(pParent);
  idxParent = pPage->idxParent;
  sqlite3pager_ref(pParent->aData);
  oldPgno = pPage->pgno;
  releasePage(pPage);
  pCur->pPage = pParent;
  pCur->info.nSize = 0;
  assert( pParent->idxShift==0 );
  pCur->idx = idxParent;
}

/*
** Move the cursor to the root page
*/
static int moveToRoot(BtCursor *pCur){
  MemPage *pRoot;
  int rc;
  Btree *pBt = pCur->pBt;

  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0);
  if( rc ){
    pCur->isValid = 0;
    return rc;
  }
  releasePage(pCur->pPage);
  pageIntegrity(pRoot);
  pCur->pPage = pRoot;
  pCur->idx = 0;
  pCur->info.nSize = 0;
  if( pRoot->nCell==0 && !pRoot->leaf ){
    Pgno subpage;
    assert( pRoot->pgno==1 );
    subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
    assert( subpage>0 );
    pCur->isValid = 1;
    rc = moveToChild(pCur, subpage);
  }
  pCur->isValid = pCur->pPage->nCell>0;
  return rc;
}

/*
** Move the cursor down to the left-most leaf entry beneath the
** entry to which it is currently pointing.
*/
static int moveToLeftmost(BtCursor *pCur){
  Pgno pgno;
  int rc;
  MemPage *pPage;

  assert( pCur->isValid );
  while( !(pPage = pCur->pPage)->leaf ){
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
    pgno = get4byte(findCell(pPage, pCur->idx));
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
  }
  return SQLITE_OK;
}

/*
** Move the cursor down to the right-most leaf entry beneath the
** page to which it is currently pointing.  Notice the difference
** between moveToLeftmost() and moveToRightmost().  moveToLeftmost()
** finds the left-most entry beneath the *entry* whereas moveToRightmost()
** finds the right-most entry beneath the *page*.
*/
static int moveToRightmost(BtCursor *pCur){
  Pgno pgno;
  int rc;
  MemPage *pPage;

  assert( pCur->isValid );
  while( !(pPage = pCur->pPage)->leaf ){
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    pCur->idx = pPage->nCell;
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
  }
  pCur->idx = pPage->nCell - 1;
  pCur->info.nSize = 0;
  return SQLITE_OK;
}

/* Move the cursor to the first entry in the table.  Return SQLITE_OK
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
  int rc;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  if( pCur->isValid==0 ){
    assert( pCur->pPage->nCell==0 );
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pCur->pPage->nCell>0 );
  *pRes = 0;
  rc = moveToLeftmost(pCur);
  return rc;
}

/* Move the cursor to the last entry in the table.  Return SQLITE_OK
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  int rc;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  if( pCur->isValid==0 ){
    assert( pCur->pPage->nCell==0 );
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pCur->isValid );
  *pRes = 0;
  rc = moveToRightmost(pCur);
  return rc;
}

/* Move the cursor so that it points to an entry near pKey/nKey.
** Return a success code.
**
** For INTKEY tables, only the nKey parameter is used.  pKey is
** ignored.  For other tables, nKey is the number of bytes of data
** in nKey.  The comparison function specified when the cursor was
** created is used to compare keys.
**
** If an exact match is not found, then the cursor is always
** left pointing at a leaf page which would hold the entry if it
** were present.  The cursor might point to an entry that comes
** before or after the key.
**
** The result of comparing the key with the entry to which the
** cursor is written to *pRes if pRes!=NULL.  The meaning of
** this value is as follows:
**
**     *pRes<0      The cursor is left pointing at an entry that
**                  is smaller than pKey or if the table is empty
**                  and the cursor is therefore left point to nothing.
**
**     *pRes==0     The cursor is left pointing at an entry that
**                  exactly matches pKey.
**
**     *pRes>0      The cursor is left pointing at an entry that
**                  is larger than pKey.
*/
int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
  int rc;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  assert( pCur->pPage );
  assert( pCur->pPage->isInit );
  if( pCur->isValid==0 ){
    *pRes = -1;
    assert( pCur->pPage->nCell==0 );
    return SQLITE_OK;
  }
   for(;;){
    int lwr, upr;
    Pgno chldPg;
    MemPage *pPage = pCur->pPage;
    int c = -1;  /* pRes return if table is empty must be -1 */
    lwr = 0;
    upr = pPage->nCell-1;
    if( !pPage->intKey && pKey==0 ){
      return SQLITE_CORRUPT;
    }
    pageIntegrity(pPage);
    while( lwr<=upr ){
      void *pCellKey;
      i64 nCellKey;
      pCur->idx = (lwr+upr)/2;
      pCur->info.nSize = 0;
      sqlite3BtreeKeySize(pCur, &nCellKey);
      if( pPage->intKey ){
        if( nCellKey<nKey ){
          c = -1;
        }else if( nCellKey>nKey ){
          c = +1;
        }else{
          c = 0;
        }
      }else{
        int available;
        pCellKey = (void *)fetchPayload(pCur, &available, 0);
        if( available>=nCellKey ){
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
        }else{
          pCellKey = sqliteMallocRaw( nCellKey );
          if( pCellKey==0 ) return SQLITE_NOMEM;
          rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
          sqliteFree(pCellKey);
          if( rc ) return rc;
        }
      }
      if( c==0 ){
        if( pPage->leafData && !pPage->leaf ){
          lwr = pCur->idx;
          upr = lwr - 1;
          break;
        }else{
          if( pRes ) *pRes = 0;
          return SQLITE_OK;
        }
      }
      if( c<0 ){
        lwr = pCur->idx+1;
      }else{
        upr = pCur->idx-1;
      }
    }
    assert( lwr==upr+1 );
    assert( pPage->isInit );
    if( pPage->leaf ){
      chldPg = 0;
    }else if( lwr>=pPage->nCell ){
      chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    }else{
      chldPg = get4byte(findCell(pPage, lwr));
    }
    if( chldPg==0 ){
      assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
      if( pRes ) *pRes = c;
      return SQLITE_OK;
    }
    pCur->idx = lwr;
    pCur->info.nSize = 0;
    rc = moveToChild(pCur, chldPg);
    if( rc ){
      return rc;
    }
  }
  /* NOT REACHED */
}

/*
** Return TRUE if the cursor is not pointing at an entry of the table.
**
** TRUE will be returned after a call to sqlite3BtreeNext() moves
** past the last entry in the table or sqlite3BtreePrev() moves past
** the first entry.  TRUE is also returned if the table is empty.
*/
int sqlite3BtreeEof(BtCursor *pCur){
  return pCur->isValid==0;
}

/*
** Advance the cursor to the next entry in the database.  If
** successful then set *pRes=0.  If the cursor
** was already pointing to the last entry in the database before
** this routine was called, then set *pRes=1.
*/
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
  int rc;
  MemPage *pPage = pCur->pPage;

  assert( pRes!=0 );
  if( pCur->isValid==0 ){
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pPage->isInit );
  assert( pCur->idx<pPage->nCell );

  pCur->idx++;
  pCur->info.nSize = 0;
  if( pCur->idx>=pPage->nCell ){
    if( !pPage->leaf ){
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
      if( rc ) return rc;
      rc = moveToLeftmost(pCur);
      *pRes = 0;
      return rc;
    }
    do{
      if( isRootPage(pPage) ){
        *pRes = 1;
        pCur->isValid = 0;
        return SQLITE_OK;
      }
      moveToParent(pCur);
      pPage = pCur->pPage;
    }while( pCur->idx>=pPage->nCell );
    *pRes = 0;
    if( pPage->leafData ){
      rc = sqlite3BtreeNext(pCur, pRes);
    }else{
      rc = SQLITE_OK;
    }
    return rc;
  }
  *pRes = 0;
  if( pPage->leaf ){
    return SQLITE_OK;
  }
  rc = moveToLeftmost(pCur);
  return rc;
}

/*
** Step the cursor to the back to the previous entry in the database.  If
** successful then set *pRes=0.  If the cursor
** was already pointing to the first entry in the database before
** this routine was called, then set *pRes=1.
*/
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
  int rc;
  Pgno pgno;
  MemPage *pPage;
  if( pCur->isValid==0 ){
    *pRes = 1;
    return SQLITE_OK;
  }

  pPage = pCur->pPage;
  assert( pPage->isInit );
  assert( pCur->idx>=0 );
  if( !pPage->leaf ){
    pgno = get4byte( findCell(pPage, pCur->idx) );
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
    rc = moveToRightmost(pCur);
  }else{
    while( pCur->idx==0 ){
      if( isRootPage(pPage) ){
        pCur->isValid = 0;
        *pRes = 1;
        return SQLITE_OK;
      }
      moveToParent(pCur);
      pPage = pCur->pPage;
    }
    pCur->idx--;
    pCur->info.nSize = 0;
    if( pPage->leafData && !pPage->leaf ){
      rc = sqlite3BtreePrevious(pCur, pRes);
    }else{
      rc = SQLITE_OK;
    }
  }
  *pRes = 0;
  return rc;
}

/*
** Allocate a new page from the database file.
**
** The new page is marked as dirty.  (In other words, sqlite3pager_write()
** has already been called on the new page.)  The new page has also
** been referenced and the calling routine is responsible for calling
** sqlite3pager_unref() on the new page when it is done.
**
** SQLITE_OK is returned on success.  Any other return value indicates
** an error.  *ppPage and *pPgno are undefined in the event of an error.
** Do not invoke sqlite3pager_unref() on *ppPage if an error is returned.
**
** If the "nearby" parameter is not 0, then a (feeble) effort is made to 
** locate a page close to the page number "nearby".  This can be used in an
** attempt to keep related pages close to each other in the database file,
** which in turn can make database access faster.
**
** If the "exact" parameter is not 0, and the page-number nearby exists 
** anywhere on the free-list, then it is guarenteed to be returned. This
** is only used by auto-vacuum databases when allocating a new table.
*/
static int allocatePage(
  Btree *pBt, 
  MemPage **ppPage, 
  Pgno *pPgno, 
  Pgno nearby,
  u8 exact
){
  MemPage *pPage1;
  int rc;
  int n;     /* Number of pages on the freelist */
  int k;     /* Number of leaves on the trunk of the freelist */

  pPage1 = pBt->pPage1;
  n = get4byte(&pPage1->aData[36]);
  if( n>0 ){
    /* There are pages on the freelist.  Reuse one of those pages. */
    MemPage *pTrunk = 0;
    Pgno iTrunk;
    MemPage *pPrevTrunk = 0;
    u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
    
    /* If the 'exact' parameter was true and a query of the pointer-map
    ** shows that the page 'nearby' is somewhere on the free-list, then
    ** the entire-list will be searched for that page.
    */
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( exact ){
      u8 eType;
      assert( nearby>0 );
      assert( pBt->autoVacuum );
      rc = ptrmapGet(pBt, nearby, &eType, 0);
      if( rc ) return rc;
      if( eType==PTRMAP_FREEPAGE ){
        searchList = 1;
      }
      *pPgno = nearby;
    }
#endif

    /* Decrement the free-list count by 1. Set iTrunk to the index of the
    ** first free-list trunk page. iPrevTrunk is initially 1.
    */
    rc = sqlite3pager_write(pPage1->aData);
    if( rc ) return rc;
    put4byte(&pPage1->aData[36], n-1);

    /* The code within this loop is run only once if the 'searchList' variable
    ** is not true. Otherwise, it runs once for each trunk-page on the
    ** free-list until the page 'nearby' is located.
    */
    do {
      pPrevTrunk = pTrunk;
      if( pPrevTrunk ){
        iTrunk = get4byte(&pPrevTrunk->aData[0]);
      }else{
        iTrunk = get4byte(&pPage1->aData[32]);
      }
      rc = getPage(pBt, iTrunk, &pTrunk);
      if( rc ){
        releasePage(pPrevTrunk);
        return rc;
      }

      /* TODO: This should move to after the loop? */
      rc = sqlite3pager_write(pTrunk->aData);
      if( rc ){
        releasePage(pTrunk);
        releasePage(pPrevTrunk);
        return rc;
      }

      k = get4byte(&pTrunk->aData[4]);
      if( k==0 && !searchList ){
        /* The trunk has no leaves and the list is not being searched. 
        ** So extract the trunk page itself and use it as the newly 
        ** allocated page */
        assert( pPrevTrunk==0 );
        *pPgno = iTrunk;
        memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
        *ppPage = pTrunk;
        pTrunk = 0;
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
      }else if( k>pBt->usableSize/4 - 8 ){
        /* Value of k is out of range.  Database corruption */
        return SQLITE_CORRUPT; /* bkpt-CORRUPT */
#ifndef SQLITE_OMIT_AUTOVACUUM
      }else if( searchList && nearby==iTrunk ){
        /* The list is being searched and this trunk page is the page
        ** to allocate, regardless of whether it has leaves.
        */
        assert( *pPgno==iTrunk );
        *ppPage = pTrunk;
        searchList = 0;
        if( k==0 ){
          if( !pPrevTrunk ){
            memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
          }else{
            memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4);
          }
        }else{
          /* The trunk page is required by the caller but it contains 
          ** pointers to free-list leaves. The first leaf becomes a trunk
          ** page in this case.
          */
          MemPage *pNewTrunk;
          Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
          rc = getPage(pBt, iNewTrunk, &pNewTrunk);
          if( rc!=SQLITE_OK ){
            releasePage(pTrunk);
            releasePage(pPrevTrunk);
            return rc;
          }
          rc = sqlite3pager_write(pNewTrunk->aData);
          if( rc!=SQLITE_OK ){
            releasePage(pNewTrunk);
            releasePage(pTrunk);
            releasePage(pPrevTrunk);
            return rc;
          }
          memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
          put4byte(&pNewTrunk->aData[4], k-1);
          memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
          if( !pPrevTrunk ){
            put4byte(&pPage1->aData[32], iNewTrunk);
          }else{
            put4byte(&pPrevTrunk->aData[0], iNewTrunk);
          }
          releasePage(pNewTrunk);
        }
        pTrunk = 0;
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
#endif
      }else{
        /* Extract a leaf from the trunk */
        int closest;
        Pgno iPage;
        unsigned char *aData = pTrunk->aData;
        if( nearby>0 ){
          int i, dist;
          closest = 0;
          dist = get4byte(&aData[8]) - nearby;
          if( dist<0 ) dist = -dist;
          for(i=1; i<k; i++){
            int d2 = get4byte(&aData[8+i*4]) - nearby;
            if( d2<0 ) d2 = -d2;
            if( d2<dist ){
              closest = i;
              dist = d2;
            }
          }
        }else{
          closest = 0;
        }

        iPage = get4byte(&aData[8+closest*4]);
        if( !searchList || iPage==nearby ){
          *pPgno = iPage;
          if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){
            /* Free page off the end of the file */
            return SQLITE_CORRUPT; /* bkpt-CORRUPT */
          }
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
                 ": %d more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          rc = getPage(pBt, *pPgno, ppPage);
          if( rc==SQLITE_OK ){
            sqlite3pager_dont_rollback((*ppPage)->aData);
            rc = sqlite3pager_write((*ppPage)->aData);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
            }
          }
          searchList = 0;
        }
      }
      releasePage(pPrevTrunk);
    }while( searchList );
    releasePage(pTrunk);
  }else{
    /* There are no pages on the freelist, so create a new page at the
    ** end of the file */
    *pPgno = sqlite3pager_pagecount(pBt->pPager) + 1;

#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt->usableSize, *pPgno) ){
      /* If *pPgno refers to a pointer-map page, allocate two new pages
      ** at the end of the file instead of one. The first allocated page
      ** becomes a new pointer-map page, the second is used by the caller.
      */
      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
      assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
      (*pPgno)++;
    }
#endif

    assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
    rc = getPage(pBt, *pPgno, ppPage);
    if( rc ) return rc;
    rc = sqlite3pager_write((*ppPage)->aData);
    if( rc!=SQLITE_OK ){
      releasePage(*ppPage);
    }
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
  }

  assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
  return rc;
}

/*
** Add a page of the database file to the freelist.
**
** sqlite3pager_unref() is NOT called for pPage.
*/
static int freePage(MemPage *pPage){
  Btree *pBt = pPage->pBt;
  MemPage *pPage1 = pBt->pPage1;
  int rc, n, k;

  /* Prepare the page for freeing */
  assert( pPage->pgno>1 );
  pPage->isInit = 0;
  releasePage(pPage->pParent);
  pPage->pParent = 0;

  /* Increment the free page count on pPage1 */
  rc = sqlite3pager_write(pPage1->aData);
  if( rc ) return rc;
  n = get4byte(&pPage1->aData[36]);
  put4byte(&pPage1->aData[36], n+1);

#ifndef SQLITE_OMIT_AUTOVACUUM
  /* If the database supports auto-vacuum, write an entry in the pointer-map
  ** to indicate that the page is free.
  */
  if( pBt->autoVacuum ){
    rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0);
    if( rc ) return rc;
  }
#endif

  if( n==0 ){
    /* This is the first free page */
    rc = sqlite3pager_write(pPage->aData);
    if( rc ) return rc;
    memset(pPage->aData, 0, 8);
    put4byte(&pPage1->aData[32], pPage->pgno);
    TRACE(("FREE-PAGE: %d first\n", pPage->pgno));
  }else{
    /* Other free pages already exist.  Retrive the first trunk page
    ** of the freelist and find out how many leaves it has. */
    MemPage *pTrunk;
    rc = getPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk);
    if( rc ) return rc;
    k = get4byte(&pTrunk->aData[4]);
    if( k>=pBt->usableSize/4 - 8 ){
      /* The trunk is full.  Turn the page being freed into a new
      ** trunk page with no leaves. */
      rc = sqlite3pager_write(pPage->aData);
      if( rc ) return rc;
      put4byte(pPage->aData, pTrunk->pgno);
      put4byte(&pPage->aData[4], 0);
      put4byte(&pPage1->aData[32], pPage->pgno);
      TRACE(("FREE-PAGE: %d new trunk page replacing %d\n",
              pPage->pgno, pTrunk->pgno));
    }else{
      /* Add the newly freed page as a leaf on the current trunk */
      rc = sqlite3pager_write(pTrunk->aData);
      if( rc ) return rc;
      put4byte(&pTrunk->aData[4], k+1);
      put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
      sqlite3pager_dont_write(pBt->pPager, pPage->pgno);
      TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
    }
    releasePage(pTrunk);
  }
  return rc;
}

/*
** Free any overflow pages associated with the given Cell.
*/
static int clearCell(MemPage *pPage, unsigned char *pCell){
  Btree *pBt = pPage->pBt;
  CellInfo info;
  Pgno ovflPgno;
  int rc;

  parseCellPtr(pPage, pCell, &info);
  if( info.iOverflow==0 ){
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  while( ovflPgno!=0 ){
    MemPage *pOvfl;
    if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){
      return SQLITE_CORRUPT;
    }
    rc = getPage(pBt, ovflPgno, &pOvfl);
    if( rc ) return rc;
    ovflPgno = get4byte(pOvfl->aData);
    rc = freePage(pOvfl);
    if( rc ) return rc;
    sqlite3pager_unref(pOvfl->aData);
  }
  return SQLITE_OK;
}

/*
** Create the byte sequence used to represent a cell on page pPage
** and write that byte sequence into pCell[].  Overflow pages are
** allocated and filled in as necessary.  The calling procedure
** is responsible for making sure sufficient space has been allocated
** for pCell[].
**
** Note that pCell does not necessary need to point to the pPage->aData
** area.  pCell might point to some temporary storage.  The cell will
** be constructed in this temporary area then copied into pPage->aData
** later.
*/
static int fillInCell(
  MemPage *pPage,                /* The page that contains the cell */
  unsigned char *pCell,          /* Complete text of the cell */
  const void *pKey, i64 nKey,    /* The key */
  const void *pData,int nData,   /* The data */
  int *pnSize                    /* Write cell size here */
){
  int nPayload;
  const u8 *pSrc;
  int nSrc, n, rc;
  int spaceLeft;
  MemPage *pOvfl = 0;
  MemPage *pToRelease = 0;
  unsigned char *pPrior;
  unsigned char *pPayload;
  Btree *pBt = pPage->pBt;
  Pgno pgnoOvfl = 0;
  int nHeader;
  CellInfo info;

  /* Fill in the header. */
  nHeader = 0;
  if( !pPage->leaf ){
    nHeader += 4;
  }
  if( pPage->hasData ){
    nHeader += putVarint(&pCell[nHeader], nData);
  }else{
    nData = 0;
  }
  nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
  parseCellPtr(pPage, pCell, &info);
  assert( info.nHeader==nHeader );
  assert( info.nKey==nKey );
  assert( info.nData==nData );
  
  /* Fill in the payload */
  nPayload = nData;
  if( pPage->intKey ){
    pSrc = pData;
    nSrc = nData;
    nData = 0;
  }else{
    nPayload += nKey;
    pSrc = pKey;
    nSrc = nKey;
  }
  *pnSize = info.nSize;
  spaceLeft = info.nLocal;
  pPayload = &pCell[nHeader];
  pPrior = &pCell[info.iOverflow];

  while( nPayload>0 ){
    if( spaceLeft==0 ){
#ifndef SQLITE_OMIT_AUTOVACUUM
      Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
#endif
      rc = allocatePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0);
#ifndef SQLITE_OMIT_AUTOVACUUM
      /* If the database supports auto-vacuum, and the second or subsequent
      ** overflow page is being allocated, add an entry to the pointer-map
      ** for that page now. The entry for the first overflow page will be
      ** added later, by the insertCell() routine.
      */
      if( pBt->autoVacuum && pgnoPtrmap!=0 && rc==SQLITE_OK ){
        rc = ptrmapPut(pBt, pgnoOvfl, PTRMAP_OVERFLOW2, pgnoPtrmap);
      }
#endif
      if( rc ){
        releasePage(pToRelease);
        /* clearCell(pPage, pCell); */
        return rc;
      }
      put4byte(pPrior, pgnoOvfl);
      releasePage(pToRelease);
      pToRelease = pOvfl;
      pPrior = pOvfl->aData;
      put4byte(pPrior, 0);
      pPayload = &pOvfl->aData[4];
      spaceLeft = pBt->usableSize - 4;
    }
    n = nPayload;
    if( n>spaceLeft ) n = spaceLeft;
    if( n>nSrc ) n = nSrc;
    memcpy(pPayload, pSrc, n);
    nPayload -= n;
    pPayload += n;
    pSrc += n;
    nSrc -= n;
    spaceLeft -= n;
    if( nSrc==0 ){
      nSrc = nData;
      pSrc = pData;
    }
  }
  releasePage(pToRelease);
  return SQLITE_OK;
}

/*
** Change the MemPage.pParent pointer on the page whose number is
** given in the second argument so that MemPage.pParent holds the
** pointer in the third argument.
*/
static int reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){
  MemPage *pThis;
  unsigned char *aData;

  if( pgno==0 ) return SQLITE_OK;
  assert( pBt->pPager!=0 );
  aData = sqlite3pager_lookup(pBt->pPager, pgno);
  if( aData ){
    pThis = (MemPage*)&aData[pBt->psAligned];
    assert( pThis->aData==aData );
    if( pThis->isInit ){
      if( pThis->pParent!=pNewParent ){
        if( pThis->pParent ) sqlite3pager_unref(pThis->pParent->aData);
        pThis->pParent = pNewParent;
        if( pNewParent ) sqlite3pager_ref(pNewParent->aData);
      }
      pThis->idxParent = idx;
    }
    sqlite3pager_unref(aData);
  }

#ifndef SQLITE_OMIT_AUTOVACUUM
  if( pBt->autoVacuum ){
    return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno);
  }
#endif
  return SQLITE_OK;
}



/*
** Change the pParent pointer of all children of pPage to point back
** to pPage.
**
** In other words, for every child of pPage, invoke reparentPage()
** to make sure that each child knows that pPage is its parent.
**
** This routine gets called after you memcpy() one page into
** another.
*/
static int reparentChildPages(MemPage *pPage){
  int i;
  Btree *pBt = pPage->pBt;
  int rc = SQLITE_OK;

  if( pPage->leaf ) return SQLITE_OK;

  for(i=0; i<pPage->nCell; i++){
    u8 *pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = reparentPage(pBt, get4byte(pCell), pPage, i);
      if( rc!=SQLITE_OK ) return rc;
    }
  }
  if( !pPage->leaf ){
    rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), 
       pPage, i);
    pPage->idxShift = 0;
  }
  return rc;
}

/*
** Remove the i-th cell from pPage.  This routine effects pPage only.
** The cell content is not freed or deallocated.  It is assumed that
** the cell content has been copied someplace else.  This routine just
** removes the reference to the cell from pPage.
**
** "sz" must be the number of bytes in the cell.
*/
static void dropCell(MemPage *pPage, int idx, int sz){
  int i;          /* Loop counter */
  int pc;         /* Offset to cell content of cell being deleted */
  u8 *data;       /* pPage->aData */
  u8 *ptr;        /* Used to move bytes around within data[] */

  assert( idx>=0 && idx<pPage->nCell );
  assert( sz==cellSize(pPage, idx) );
  assert( sqlite3pager_iswriteable(pPage->aData) );
  data = pPage->aData;
  ptr = &data[pPage->cellOffset + 2*idx];
  pc = get2byte(ptr);
  assert( pc>10 && pc+sz<=pPage->pBt->usableSize );
  freeSpace(pPage, pc, sz);
  for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
    ptr[0] = ptr[2];
    ptr[1] = ptr[3];
  }
  pPage->nCell--;
  put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
  pPage->nFree += 2;
  pPage->idxShift = 1;
}

/*
** Insert a new cell on pPage at cell index "i".  pCell points to the
** content of the cell.
**
** If the cell content will fit on the page, then put it there.  If it
** will not fit, then make a copy of the cell content into pTemp if
** pTemp is not null.  Regardless of pTemp, allocate a new entry
** in pPage->aOvfl[] and make it point to the cell content (either
** in pTemp or the original pCell) and also record its index. 
** Allocating a new entry in pPage->aCell[] implies that 
** pPage->nOverflow is incremented.
**
** If nSkip is non-zero, then do not copy the first nSkip bytes of the
** cell. The caller will overwrite them after this function returns. If
** nSkip is non-zero, then pCell may not point to an invalid memory location 
** (but pCell+nSkip is always valid).
*/
static int insertCell(
  MemPage *pPage,   /* Page into which we are copying */
  int i,            /* New cell becomes the i-th cell of the page */
  u8 *pCell,        /* Content of the new cell */
  int sz,           /* Bytes of content in pCell */
  u8 *pTemp,        /* Temp storage space for pCell, if needed */
  u8 nSkip          /* Do not write the first nSkip bytes of the cell */
){
  int idx;          /* Where to write new cell content in data[] */
  int j;            /* Loop counter */
  int top;          /* First byte of content for any cell in data[] */
  int end;          /* First byte past the last cell pointer in data[] */
  int ins;          /* Index in data[] where new cell pointer is inserted */
  int hdr;          /* Offset into data[] of the page header */
  int cellOffset;   /* Address of first cell pointer in data[] */
  u8 *data;         /* The content of the whole page */
  u8 *ptr;          /* Used for moving information around in data[] */

  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
  assert( sz==cellSizePtr(pPage, pCell) );
  assert( sqlite3pager_iswriteable(pPage->aData) );
  if( pPage->nOverflow || sz+2>pPage->nFree ){
    if( pTemp ){
      memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
      pCell = pTemp;
    }
    j = pPage->nOverflow++;
    assert( j<sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0]) );
    pPage->aOvfl[j].pCell = pCell;
    pPage->aOvfl[j].idx = i;
    pPage->nFree = 0;
  }else{
    data = pPage->aData;
    hdr = pPage->hdrOffset;
    top = get2byte(&data[hdr+5]);
    cellOffset = pPage->cellOffset;
    end = cellOffset + 2*pPage->nCell + 2;
    ins = cellOffset + 2*i;
    if( end > top - sz ){
      defragmentPage(pPage);
      top = get2byte(&data[hdr+5]);
      assert( end + sz <= top );
    }
    idx = allocateSpace(pPage, sz);
    assert( idx>0 );
    assert( end <= get2byte(&data[hdr+5]) );
    pPage->nCell++;
    pPage->nFree -= 2;
    memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
    for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){
      ptr[0] = ptr[-2];
      ptr[1] = ptr[-1];
    }
    put2byte(&data[ins], idx);
    put2byte(&data[hdr+3], pPage->nCell);
    pPage->idxShift = 1;
    pageIntegrity(pPage);
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pPage->pBt->autoVacuum ){
      /* The cell may contain a pointer to an overflow page. If so, write
      ** the entry for the overflow page into the pointer map.
      */
      CellInfo info;
      parseCellPtr(pPage, pCell, &info);
      if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
        Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
        int rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno);
        if( rc!=SQLITE_OK ) return rc;
      }
    }
#endif
  }

  return SQLITE_OK;
}

/*
** Add a list of cells to a page.  The page should be initially empty.
** The cells are guaranteed to fit on the page.
*/
static void assemblePage(
  MemPage *pPage,   /* The page to be assemblied */
  int nCell,        /* The number of cells to add to this page */
  u8 **apCell,      /* Pointers to cell bodies */
  int *aSize        /* Sizes of the cells */
){
  int i;            /* Loop counter */
  int totalSize;    /* Total size of all cells */
  int hdr;          /* Index of page header */
  int cellptr;      /* Address of next cell pointer */
  int cellbody;     /* Address of next cell body */
  u8 *data;         /* Data for the page */

  assert( pPage->nOverflow==0 );
  totalSize = 0;
  for(i=0; i<nCell; i++){
    totalSize += aSize[i];
  }
  assert( totalSize+2*nCell<=pPage->nFree );
  assert( pPage->nCell==0 );
  cellptr = pPage->cellOffset;
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  put2byte(&data[hdr+3], nCell);
  cellbody = allocateSpace(pPage, totalSize);
  assert( cellbody>0 );
  assert( pPage->nFree >= 2*nCell );
  pPage->nFree -= 2*nCell;
  for(i=0; i<nCell; i++){
    put2byte(&data[cellptr], cellbody);
    memcpy(&data[cellbody], apCell[i], aSize[i]);
    cellptr += 2;
    cellbody += aSize[i];
  }
  assert( cellbody==pPage->pBt->usableSize );
  pPage->nCell = nCell;
}

/*
** The following parameters determine how many adjacent pages get involved
** in a balancing operation.  NN is the number of neighbors on either side
** of the page that participate in the balancing operation.  NB is the
** total number of pages that participate, including the target page and
** NN neighbors on either side.
**
** The minimum value of NN is 1 (of course).  Increasing NN above 1
** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
** in exchange for a larger degradation in INSERT and UPDATE performance.
** The value of NN appears to give the best results overall.
*/
#define NN 1             /* Number of neighbors on either side of pPage */
#define NB (NN*2+1)      /* Total pages involved in the balance */

/* Forward reference */
static int balance(MemPage*, int);

#ifndef SQLITE_OMIT_QUICKBALANCE
/*
** This version of balance() handles the common special case where
** a new entry is being inserted on the extreme right-end of the
** tree, in other words, when the new entry will become the largest
** entry in the tree.
**
** Instead of trying balance the 3 right-most leaf pages, just add
** a new page to the right-hand side and put the one new entry in
** that page.  This leaves the right side of the tree somewhat
** unbalanced.  But odds are that we will be inserting new entries
** at the end soon afterwards so the nearly empty page will quickly
** fill up.  On average.
**
** pPage is the leaf page which is the right-most page in the tree.
** pParent is its parent.  pPage must have a single overflow entry
** which is also the right-most entry on the page.
*/
static int balance_quick(MemPage *pPage, MemPage *pParent){
  int rc;
  MemPage *pNew;
  Pgno pgnoNew;
  u8 *pCell;
  int szCell;
  CellInfo info;
  Btree *pBt = pPage->pBt;
  int parentIdx = pParent->nCell;   /* pParent new divider cell index */
  int parentSize;                   /* Size of new divider cell */
  u8 parentCell[64];                /* Space for the new divider cell */

  /* Allocate a new page. Insert the overflow cell from pPage
  ** into it. Then remove the overflow cell from pPage.
  */
  rc = allocatePage(pBt, &pNew, &pgnoNew, 0, 0);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  pCell = pPage->aOvfl[0].pCell;
  szCell = cellSizePtr(pPage, pCell);
  zeroPage(pNew, pPage->aData[0]);
  assemblePage(pNew, 1, &pCell, &szCell);
  pPage->nOverflow = 0;

  /* Set the parent of the newly allocated page to pParent. */
  pNew->pParent = pParent;
  sqlite3pager_ref(pParent->aData);

  /* pPage is currently the right-child of pParent. Change this
  ** so that the right-child is the new page allocated above and
  ** pPage is the next-to-right child. 
  */
  assert( pPage->nCell>0 );
  parseCellPtr(pPage, findCell(pPage, pPage->nCell-1), &info);
  rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, &parentSize);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  assert( parentSize<64 );
  rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
  put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);

#ifndef SQLITE_OMIT_AUTOVACUUM
  /* If this is an auto-vacuum database, update the pointer map
  ** with entries for the new page, and any pointer from the 
  ** cell on the page to an overflow page.
  */
  if( pBt->autoVacuum ){
    rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    rc = ptrmapPutOvfl(pNew, 0);
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }
#endif

  /* Release the reference to the new page and balance the parent page,
  ** in case the divider cell inserted caused it to become overfull.
  */
  releasePage(pNew);
  return balance(pParent, 0);
}
#endif /* SQLITE_OMIT_QUICKBALANCE */

/*
** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
** if the database supports auto-vacuum or not. Because it is used
** within an expression that is an argument to another macro 
** (sqliteMallocRaw), it is not possible to use conditional compilation.
** So, this macro is defined instead.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
#define ISAUTOVACUUM (pBt->autoVacuum)
#else
#define ISAUTOVACUUM 0
#endif

/*
** This routine redistributes Cells on pPage and up to NN*2 siblings
** of pPage so that all pages have about the same amount of free space.
** Usually NN siblings on either side of pPage is used in the balancing,
** though more siblings might come from one side if pPage is the first
** or last child of its parent.  If pPage has fewer than 2*NN siblings
** (something which can only happen if pPage is the root page or a 
** child of root) then all available siblings participate in the balancing.
**
** The number of siblings of pPage might be increased or decreased by one or
** two in an effort to keep pages nearly full but not over full. The root page
** is special and is allowed to be nearly empty. If pPage is 
** the root page, then the depth of the tree might be increased
** or decreased by one, as necessary, to keep the root page from being
** overfull or completely empty.
**
** Note that when this routine is called, some of the Cells on pPage
** might not actually be stored in pPage->aData[].  This can happen
** if the page is overfull.  Part of the job of this routine is to
** make sure all Cells for pPage once again fit in pPage->aData[].
**
** In the course of balancing the siblings of pPage, the parent of pPage
** might become overfull or underfull.  If that happens, then this routine
** is called recursively on the parent.
**
** If this routine fails for any reason, it might leave the database
** in a corrupted state.  So if this routine fails, the database should
** be rolled back.
*/
static int balance_nonroot(MemPage *pPage){
  MemPage *pParent;            /* The parent of pPage */
  Btree *pBt;                  /* The whole database */
  int nCell = 0;               /* Number of cells in aCell[] */
  int nOld;                    /* Number of pages in apOld[] */
  int nNew;                    /* Number of pages in apNew[] */
  int nDiv;                    /* Number of cells in apDiv[] */
  int i, j, k;                 /* Loop counters */
  int idx;                     /* Index of pPage in pParent->aCell[] */
  int nxDiv;                   /* Next divider slot in pParent->aCell[] */
  int rc;                      /* The return code */
  int leafCorrection;          /* 4 if pPage is a leaf.  0 if not */
  int leafData;                /* True if pPage is a leaf of a LEAFDATA tree */
  int usableSpace;             /* Bytes in pPage beyond the header */
  int pageFlags;               /* Value of pPage->aData[0] */
  int subtotal;                /* Subtotal of bytes in cells on one page */
  int iSpace = 0;              /* First unused byte of aSpace[] */
  int mxCellPerPage;           /* Maximum number of cells in one page */
  MemPage *apOld[NB];          /* pPage and up to two siblings */
  Pgno pgnoOld[NB];            /* Page numbers for each page in apOld[] */
  MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
  MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
  Pgno pgnoNew[NB+2];          /* Page numbers for each page in apNew[] */
  int idxDiv[NB];              /* Indices of divider cells in pParent */
  u8 *apDiv[NB];               /* Divider cells in pParent */
  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
  int szNew[NB+2];             /* Combined size of cells place on i-th page */
  u8 **apCell;                 /* All cells begin balanced */
  int *szCell;                 /* Local size of all cells in apCell[] */
  u8 *aCopy[NB];               /* Space for holding data of apCopy[] */
  u8 *aSpace;                  /* Space to hold copies of dividers cells */
#ifndef SQLITE_OMIT_AUTOVACUUM
  u8 *aFrom = 0;
#endif

  /* 
  ** Find the parent page.
  */
  assert( pPage->isInit );
  assert( sqlite3pager_iswriteable(pPage->aData) );
  pBt = pPage->pBt;
  pParent = pPage->pParent;
  sqlite3pager_write(pParent->aData);
  assert( pParent );
  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));

#ifndef SQLITE_OMIT_QUICKBALANCE
  /*
  ** A special case:  If a new entry has just been inserted into a
  ** table (that is, a btree with integer keys and all data at the leaves)
  ** an the new entry is the right-most entry in the tree (it has the
  ** largest key) then use the special balance_quick() routine for
  ** balancing.  balance_quick() is much faster and results in a tighter
  ** packing of data in the common case.
  */
  if( pPage->leaf &&
      pPage->intKey &&
      pPage->leafData &&
      pPage->nOverflow==1 &&
      pPage->aOvfl[0].idx==pPage->nCell &&
      pPage->pParent->pgno!=1 &&
      get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
  ){
    /*
    ** TODO: Check the siblings to the left of pPage. It may be that
    ** they are not full and no new page is required.
    */
    return balance_quick(pPage, pParent);
  }
#endif

  /*
  ** Allocate space for memory structures
  */
  mxCellPerPage = MX_CELL(pBt);
  apCell = sqliteMallocRaw( 
       (mxCellPerPage+2)*NB*(sizeof(u8*)+sizeof(int))
     + sizeof(MemPage)*NB
     + pBt->psAligned*(5+NB)
     + (ISAUTOVACUUM ? (mxCellPerPage+2)*NN*2 : 0)
  );
  if( apCell==0 ){
    return SQLITE_NOMEM;
  }
  szCell = (int*)&apCell[(mxCellPerPage+2)*NB];
  aCopy[0] = (u8*)&szCell[(mxCellPerPage+2)*NB];
  for(i=1; i<NB; i++){
    aCopy[i] = &aCopy[i-1][pBt->psAligned+sizeof(MemPage)];
  }
  aSpace = &aCopy[NB-1][pBt->psAligned+sizeof(MemPage)];
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( pBt->autoVacuum ){
    aFrom = &aSpace[5*pBt->psAligned];
  }
#endif
  
  /*
  ** Find the cell in the parent page whose left child points back
  ** to pPage.  The "idx" variable is the index of that cell.  If pPage
  ** is the rightmost child of pParent then set idx to pParent->nCell 
  */
  if( pParent->idxShift ){
    Pgno pgno;
    pgno = pPage->pgno;
    assert( pgno==sqlite3pager_pagenumber(pPage->aData) );
    for(idx=0; idx<pParent->nCell; idx++){
      if( get4byte(findCell(pParent, idx))==pgno ){
        break;
      }
    }
    assert( idx<pParent->nCell
             || get4byte(&pParent->aData[pParent->hdrOffset+8])==pgno );
  }else{
    idx = pPage->idxParent;
  }

  /*
  ** Initialize variables so that it will be safe to jump
  ** directly to balance_cleanup at any moment.
  */
  nOld = nNew = 0;
  sqlite3pager_ref(pParent->aData);

  /*
  ** Find sibling pages to pPage and the cells in pParent that divide
  ** the siblings.  An attempt is made to find NN siblings on either
  ** side of pPage.  More siblings are taken from one side, however, if
  ** pPage there are fewer than NN siblings on the other side.  If pParent
  ** has NB or fewer children then all children of pParent are taken.
  */
  nxDiv = idx - NN;
  if( nxDiv + NB > pParent->nCell ){
    nxDiv = pParent->nCell - NB + 1;
  }
  if( nxDiv<0 ){
    nxDiv = 0;
  }
  nDiv = 0;
  for(i=0, k=nxDiv; i<NB; i++, k++){
    if( k<pParent->nCell ){
      idxDiv[i] = k;
      apDiv[i] = findCell(pParent, k);
      nDiv++;
      assert( !pParent->leaf );
      pgnoOld[i] = get4byte(apDiv[i]);
    }else if( k==pParent->nCell ){
      pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]);
    }else{
      break;
    }
    rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i], pParent);
    if( rc ) goto balance_cleanup;
    apOld[i]->idxParent = k;
    apCopy[i] = 0;
    assert( i==nOld );
    nOld++;
  }

  /*
  ** Make copies of the content of pPage and its siblings into aOld[].
  ** The rest of this function will use data from the copies rather
  ** that the original pages since the original pages will be in the
  ** process of being overwritten.
  */
  for(i=0; i<nOld; i++){
    MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->psAligned];
    p->aData = &((u8*)p)[-pBt->psAligned];
    memcpy(p->aData, apOld[i]->aData, pBt->psAligned + sizeof(MemPage));
    p->aData = &((u8*)p)[-pBt->psAligned];
  }

  /*
  ** Load pointers to all cells on sibling pages and the divider cells
  ** into the local apCell[] array.  Make copies of the divider cells
  ** into space obtained form aSpace[] and remove the the divider Cells
  ** from pParent.
  **
  ** If the siblings are on leaf pages, then the child pointers of the
  ** divider cells are stripped from the cells before they are copied
  ** into aSpace[].  In this way, all cells in apCell[] are without
  ** child pointers.  If siblings are not leaves, then all cell in
  ** apCell[] include child pointers.  Either way, all cells in apCell[]
  ** are alike.
  **
  ** leafCorrection:  4 if pPage is a leaf.  0 if pPage is not a leaf.
  **       leafData:  1 if pPage holds key+data and pParent holds only keys.
  */
  nCell = 0;
  leafCorrection = pPage->leaf*4;
  leafData = pPage->leafData && pPage->leaf;
  for(i=0; i<nOld; i++){
    MemPage *pOld = apCopy[i];
    int limit = pOld->nCell+pOld->nOverflow;
    for(j=0; j<limit; j++){
      apCell[nCell] = findOverflowCell(pOld, j);
      szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        int a;
        aFrom[nCell] = i;
        for(a=0; a<pOld->nOverflow; a++){
          if( pOld->aOvfl[a].pCell==apCell[nCell] ){
            aFrom[nCell] = 0xFF;
            break;
          }
        }
      }
#endif
      nCell++;
    }
    if( i<nOld-1 ){
      int sz = cellSizePtr(pParent, apDiv[i]);
      if( leafData ){
        /* With the LEAFDATA flag, pParent cells hold only INTKEYs that
        ** are duplicates of keys on the child pages.  We need to remove
        ** the divider cells from pParent, but the dividers cells are not
        ** added to apCell[] because they are duplicates of child cells.
        */
        dropCell(pParent, nxDiv, sz);
      }else{
        u8 *pTemp;
        szCell[nCell] = sz;
        pTemp = &aSpace[iSpace];
        iSpace += sz;
        assert( iSpace<=pBt->psAligned*5 );
        memcpy(pTemp, apDiv[i], sz);
        apCell[nCell] = pTemp+leafCorrection;
#ifndef SQLITE_OMIT_AUTOVACUUM
        if( pBt->autoVacuum ){
          aFrom[nCell] = 0xFF;
        }
#endif
        dropCell(pParent, nxDiv, sz);
        szCell[nCell] -= leafCorrection;
        assert( get4byte(pTemp)==pgnoOld[i] );
        if( !pOld->leaf ){
          assert( leafCorrection==0 );
          /* The right pointer of the child page pOld becomes the left
          ** pointer of the divider cell */
          memcpy(apCell[nCell], &pOld->aData[pOld->hdrOffset+8], 4);
        }else{
          assert( leafCorrection==4 );
        }
        nCell++;
      }
    }
  }

  /*
  ** Figure out the number of pages needed to hold all nCell cells.
  ** Store this number in "k".  Also compute szNew[] which is the total
  ** size of all cells on the i-th page and cntNew[] which is the index
  ** in apCell[] of the cell that divides page i from page i+1.  
  ** cntNew[k] should equal nCell.
  **
  ** Values computed by this block:
  **
  **           k: The total number of sibling pages
  **    szNew[i]: Spaced used on the i-th sibling page.
  **   cntNew[i]: Index in apCell[] and szCell[] for the first cell to
  **              the right of the i-th sibling page.
  ** usableSpace: Number of bytes of space available on each sibling.
  ** 
  */
  usableSpace = pBt->usableSize - 12 + leafCorrection;
  for(subtotal=k=i=0; i<nCell; i++){
    subtotal += szCell[i] + 2;
    if( subtotal > usableSpace ){
      szNew[k] = subtotal - szCell[i];
      cntNew[k] = i;
      if( leafData ){ i--; }
      subtotal = 0;
      k++;
    }
  }
  szNew[k] = subtotal;
  cntNew[k] = nCell;
  k++;

  /*
  ** The packing computed by the previous block is biased toward the siblings
  ** on the left side.  The left siblings are always nearly full, while the
  ** right-most sibling might be nearly empty.  This block of code attempts
  ** to adjust the packing of siblings to get a better balance.
  **
  ** This adjustment is more than an optimization.  The packing above might
  ** be so out of balance as to be illegal.  For example, the right-most
  ** sibling might be completely empty.  This adjustment is not optional.
  */
  for(i=k-1; i>0; i--){
    int szRight = szNew[i];  /* Size of sibling on the right */
    int szLeft = szNew[i-1]; /* Size of sibling on the left */
    int r;              /* Index of right-most cell in left sibling */
    int d;              /* Index of first cell to the left of right sibling */

    r = cntNew[i-1] - 1;
    d = r + 1 - leafData;
    while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
      szRight += szCell[d] + 2;
      szLeft -= szCell[r] + 2;
      cntNew[i-1]--;
      r = cntNew[i-1] - 1;
      d = r + 1 - leafData;
    }
    szNew[i] = szRight;
    szNew[i-1] = szLeft;
  }
  assert( cntNew[0]>0 );

  /*
  ** Allocate k new pages.  Reuse old pages where possible.
  */
  assert( pPage->pgno>1 );
  pageFlags = pPage->aData[0];
  for(i=0; i<k; i++){
    MemPage *pNew;
    if( i<nOld ){
      pNew = apNew[i] = apOld[i];
      pgnoNew[i] = pgnoOld[i];
      apOld[i] = 0;
      rc = sqlite3pager_write(pNew->aData);
      if( rc ) goto balance_cleanup;
    }else{
      rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
      if( rc ) goto balance_cleanup;
      apNew[i] = pNew;
    }
    nNew++;
    zeroPage(pNew, pageFlags);
  }

  /* Free any old pages that were not reused as new pages.
  */
  while( i<nOld ){
    rc = freePage(apOld[i]);
    if( rc ) goto balance_cleanup;
    releasePage(apOld[i]);
    apOld[i] = 0;
    i++;
  }

  /*
  ** Put the new pages in accending order.  This helps to
  ** keep entries in the disk file in order so that a scan
  ** of the table is a linear scan through the file.  That
  ** in turn helps the operating system to deliver pages
  ** from the disk more rapidly.
  **
  ** An O(n^2) insertion sort algorithm is used, but since
  ** n is never more than NB (a small constant), that should
  ** not be a problem.
  **
  ** When NB==3, this one optimization makes the database
  ** about 25% faster for large insertions and deletions.
  */
  for(i=0; i<k-1; i++){
    int minV = pgnoNew[i];
    int minI = i;
    for(j=i+1; j<k; j++){
      if( pgnoNew[j]<(unsigned)minV ){
        minI = j;
        minV = pgnoNew[j];
      }
    }
    if( minI>i ){
      int t;
      MemPage *pT;
      t = pgnoNew[i];
      pT = apNew[i];
      pgnoNew[i] = pgnoNew[minI];
      apNew[i] = apNew[minI];
      pgnoNew[minI] = t;
      apNew[minI] = pT;
    }
  }
  TRACE(("BALANCE: old: %d %d %d  new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
    pgnoOld[0], 
    nOld>=2 ? pgnoOld[1] : 0,
    nOld>=3 ? pgnoOld[2] : 0,
    pgnoNew[0], szNew[0],
    nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0,
    nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0,
    nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0,
    nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0));

  /*
  ** Evenly distribute the data in apCell[] across the new pages.
  ** Insert divider cells into pParent as necessary.
  */
  j = 0;
  for(i=0; i<nNew; i++){
    /* Assemble the new sibling page. */
    MemPage *pNew = apNew[i];
    assert( pNew->pgno==pgnoNew[i] );
    assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
    assert( pNew->nCell>0 );
    assert( pNew->nOverflow==0 );

#ifndef SQLITE_OMIT_AUTOVACUUM
    /* If this is an auto-vacuum database, update the pointer map entries
    ** that point to the siblings that were rearranged. These can be: left
    ** children of cells, the right-child of the page, or overflow pages
    ** pointed to by cells.
    */
    if( pBt->autoVacuum ){
      for(k=j; k<cntNew[i]; k++){
        if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
          rc = ptrmapPutOvfl(pNew, k-j);
          if( rc!=SQLITE_OK ){
            goto balance_cleanup;
          }
        }
      }
    }
#endif

    j = cntNew[i];

    /* If the sibling page assembled above was not the right-most sibling,
    ** insert a divider cell into the parent page.
    */
    if( i<nNew-1 && j<nCell ){
      u8 *pCell;
      u8 *pTemp;
      int sz;
      pCell = apCell[j];
      sz = szCell[j] + leafCorrection;
      if( !pNew->leaf ){
        memcpy(&pNew->aData[8], pCell, 4);
        pTemp = 0;
      }else if( leafData ){
	/* If the tree is a leaf-data tree, and the siblings are leaves, 
        ** then there is no divider cell in apCell[]. Instead, the divider 
        ** cell consists of the integer key for the right-most cell of 
        ** the sibling-page assembled above only.
        */
        CellInfo info;
        j--;
        parseCellPtr(pNew, apCell[j], &info);
        pCell = &aSpace[iSpace];
        fillInCell(pParent, pCell, 0, info.nKey, 0, 0, &sz);
        iSpace += sz;
        assert( iSpace<=pBt->psAligned*5 );
        pTemp = 0;
      }else{
        pCell -= 4;
        pTemp = &aSpace[iSpace];
        iSpace += sz;
        assert( iSpace<=pBt->psAligned*5 );
      }
      rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
      if( rc!=SQLITE_OK ) goto balance_cleanup;
      put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
#ifndef SQLITE_OMIT_AUTOVACUUM
      /* If this is an auto-vacuum database, and not a leaf-data tree,
      ** then update the pointer map with an entry for the overflow page
      ** that the cell just inserted points to (if any).
      */
      if( pBt->autoVacuum && !leafData ){
        rc = ptrmapPutOvfl(pParent, nxDiv);
        if( rc!=SQLITE_OK ){
          goto balance_cleanup;
        }
      }
#endif
      j++;
      nxDiv++;
    }
  }
  assert( j==nCell );
  if( (pageFlags & PTF_LEAF)==0 ){
    memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4);
  }
  if( nxDiv==pParent->nCell+pParent->nOverflow ){
    /* Right-most sibling is the right-most child of pParent */
    put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]);
  }else{
    /* Right-most sibling is the left child of the first entry in pParent
    ** past the right-most divider entry */
    put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]);
  }

  /*
  ** Reparent children of all cells.
  */
  for(i=0; i<nNew; i++){
    rc = reparentChildPages(apNew[i]);
    if( rc!=SQLITE_OK ) goto balance_cleanup;
  }
  rc = reparentChildPages(pParent);
  if( rc!=SQLITE_OK ) goto balance_cleanup;

  /*
  ** Balance the parent page.  Note that the current page (pPage) might
  ** have been added to the freelist so it might no longer be initialized.
  ** But the parent page will always be initialized.
  */
  assert( pParent->isInit );
  /* assert( pPage->isInit ); // No! pPage might have been added to freelist */
  /* pageIntegrity(pPage);    // No! pPage might have been added to freelist */ 
  rc = balance(pParent, 0);
  
  /*
  ** Cleanup before returning.
  */
balance_cleanup:
  sqliteFree(apCell);
  for(i=0; i<nOld; i++){
    releasePage(apOld[i]);
  }
  for(i=0; i<nNew; i++){
    releasePage(apNew[i]);
  }
  releasePage(pParent);
  TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
          pPage->pgno, nOld, nNew, nCell));
  return rc;
}

/*
** This routine is called for the root page of a btree when the root
** page contains no cells.  This is an opportunity to make the tree
** shallower by one level.
*/
static int balance_shallower(MemPage *pPage){
  MemPage *pChild;             /* The only child page of pPage */
  Pgno pgnoChild;              /* Page number for pChild */
  int rc = SQLITE_OK;          /* Return code from subprocedures */
  Btree *pBt;                  /* The main BTree structure */
  int mxCellPerPage;           /* Maximum number of cells per page */
  u8 **apCell;                 /* All cells from pages being balanced */
  int *szCell;                 /* Local size of all cells */

  assert( pPage->pParent==0 );
  assert( pPage->nCell==0 );
  pBt = pPage->pBt;
  mxCellPerPage = MX_CELL(pBt);
  apCell = sqliteMallocRaw( mxCellPerPage*(sizeof(u8*)+sizeof(int)) );
  if( apCell==0 ) return SQLITE_NOMEM;
  szCell = (int*)&apCell[mxCellPerPage];
  if( pPage->leaf ){
    /* The table is completely empty */
    TRACE(("BALANCE: empty table %d\n", pPage->pgno));
  }else{
    /* The root page is empty but has one child.  Transfer the
    ** information from that one child into the root page if it 
    ** will fit.  This reduces the depth of the tree by one.
    **
    ** If the root page is page 1, it has less space available than
    ** its child (due to the 100 byte header that occurs at the beginning
    ** of the database fle), so it might not be able to hold all of the 
    ** information currently contained in the child.  If this is the 
    ** case, then do not do the transfer.  Leave page 1 empty except
    ** for the right-pointer to the child page.  The child page becomes
    ** the virtual root of the tree.
    */
    pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    assert( pgnoChild>0 );
    assert( pgnoChild<=sqlite3pager_pagecount(pPage->pBt->pPager) );
    rc = getPage(pPage->pBt, pgnoChild, &pChild);
    if( rc ) goto end_shallow_balance;
    if( pPage->pgno==1 ){
      rc = initPage(pChild, pPage);
      if( rc ) goto end_shallow_balance;
      assert( pChild->nOverflow==0 );
      if( pChild->nFree>=100 ){
        /* The child information will fit on the root page, so do the
        ** copy */
        int i;
        zeroPage(pPage, pChild->aData[0]);
        for(i=0; i<pChild->nCell; i++){
          apCell[i] = findCell(pChild,i);
          szCell[i] = cellSizePtr(pChild, apCell[i]);
        }
        assemblePage(pPage, pChild->nCell, apCell, szCell);
        /* Copy the right-pointer of the child to the parent. */
        put4byte(&pPage->aData[pPage->hdrOffset+8], 
            get4byte(&pChild->aData[pChild->hdrOffset+8]));
        freePage(pChild);
        TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno));
      }else{
        /* The child has more information that will fit on the root.
        ** The tree is already balanced.  Do nothing. */
        TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno));
      }
    }else{
      memcpy(pPage->aData, pChild->aData, pPage->pBt->usableSize);
      pPage->isInit = 0;
      pPage->pParent = 0;
      rc = initPage(pPage, 0);
      assert( rc==SQLITE_OK );
      freePage(pChild);
      TRACE(("BALANCE: transfer child %d into root %d\n",
              pChild->pgno, pPage->pgno));
    }
    rc = reparentChildPages(pPage);
    assert( pPage->nOverflow==0 );
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum ){
      int i;
      for(i=0; i<pPage->nCell; i++){ 
        rc = ptrmapPutOvfl(pPage, i);
        if( rc!=SQLITE_OK ){
          goto end_shallow_balance;
        }
      }
    }
#endif
    if( rc!=SQLITE_OK ) goto end_shallow_balance;
    releasePage(pChild);
  }
end_shallow_balance:
  sqliteFree(apCell);
  return rc;
}


/*
** The root page is overfull
**
** When this happens, Create a new child page and copy the
** contents of the root into the child.  Then make the root
** page an empty page with rightChild pointing to the new
** child.   Finally, call balance_internal() on the new child
** to cause it to split.
*/
static int balance_deeper(MemPage *pPage){
  int rc;             /* Return value from subprocedures */
  MemPage *pChild;    /* Pointer to a new child page */
  Pgno pgnoChild;     /* Page number of the new child page */
  Btree *pBt;         /* The BTree */
  int usableSize;     /* Total usable size of a page */
  u8 *data;           /* Content of the parent page */
  u8 *cdata;          /* Content of the child page */
  int hdr;            /* Offset to page header in parent */
  int brk;            /* Offset to content of first cell in parent */

  assert( pPage->pParent==0 );
  assert( pPage->nOverflow>0 );
  pBt = pPage->pBt;
  rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0);
  if( rc ) return rc;
  assert( sqlite3pager_iswriteable(pChild->aData) );
  usableSize = pBt->usableSize;
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  brk = get2byte(&data[hdr+5]);
  cdata = pChild->aData;
  memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
  memcpy(&cdata[brk], &data[brk], usableSize-brk);
  assert( pChild->isInit==0 );
  rc = initPage(pChild, pPage);
  if( rc ) return rc;
  memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0]));
  pChild->nOverflow = pPage->nOverflow;
  if( pChild->nOverflow ){
    pChild->nFree = 0;
  }
  assert( pChild->nCell==pPage->nCell );
  zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
  put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
  TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( pBt->autoVacuum ){
    int i;
    rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
    if( rc ) return rc;
    for(i=0; i<pChild->nCell; i++){
      rc = ptrmapPutOvfl(pChild, i);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }
  }
#endif
  rc = balance_nonroot(pChild);
  releasePage(pChild);
  return rc;
}

/*
** Decide if the page pPage needs to be balanced.  If balancing is
** required, call the appropriate balancing routine.
*/
static int balance(MemPage *pPage, int insert){
  int rc = SQLITE_OK;
  if( pPage->pParent==0 ){
    if( pPage->nOverflow>0 ){
      rc = balance_deeper(pPage);
    }
    if( rc==SQLITE_OK && pPage->nCell==0 ){
      rc = balance_shallower(pPage);
    }
  }else{
    if( pPage->nOverflow>0 || 
        (!insert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
      rc = balance_nonroot(pPage);
    }
  }
  return rc;
}

/*
** This routine checks all cursors that point to table pgnoRoot.
** If any of those cursors other than pExclude were opened with 
** wrFlag==0 then this routine returns SQLITE_LOCKED.  If all
** cursors that point to pgnoRoot were opened with wrFlag==1
** then this routine returns SQLITE_OK.
**
** In addition to checking for read-locks (where a read-lock 
** means a cursor opened with wrFlag==0) this routine also moves
** all cursors other than pExclude so that they are pointing to the 
** first Cell on root page.  This is necessary because an insert 
** or delete might change the number of cells on a page or delete
** a page entirely and we do not want to leave any cursors 
** pointing to non-existant pages or cells.
*/
static int checkReadLocks(Btree *pBt, Pgno pgnoRoot, BtCursor *pExclude){
  BtCursor *p;
  for(p=pBt->pCursor; p; p=p->pNext){
    if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue;
    if( p->wrFlag==0 ) return SQLITE_LOCKED;
    if( p->pPage->pgno!=p->pgnoRoot ){
      moveToRoot(p);
    }
  }
  return SQLITE_OK;
}

/*
** Insert a new record into the BTree.  The key is given by (pKey,nKey)
** and the data is given by (pData,nData).  The cursor is used only to
** define what table the record should be inserted into.  The cursor
** is left pointing at a random location.
**
** For an INTKEY table, only the nKey value of the key is used.  pKey is
** ignored.  For a ZERODATA table, the pData and nData are both ignored.
*/
int sqlite3BtreeInsert(
  BtCursor *pCur,                /* Insert data into the table of this cursor */
  const void *pKey, i64 nKey,    /* The key of the new record */
  const void *pData, int nData   /* The data of the new record */
){
  int rc;
  int loc;
  int szNew;
  MemPage *pPage;
  Btree *pBt = pCur->pBt;
  unsigned char *oldCell;
  unsigned char *newCell = 0;

  if( pBt->inTrans!=TRANS_WRITE ){
    /* Must start a transaction before doing an insert */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );
  if( !pCur->wrFlag ){
    return SQLITE_PERM;   /* Cursor not open for writing */
  }
  if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
  }
  rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc);
  if( rc ) return rc;
  pPage = pCur->pPage;
  assert( pPage->intKey || nKey>=0 );
  assert( pPage->leaf || !pPage->leafData );
  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, nKey, nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit );
  rc = sqlite3pager_write(pPage->aData);
  if( rc ) return rc;
  newCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
  if( newCell==0 ) return SQLITE_NOMEM;
  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, &szNew);
  if( rc ) goto end_insert;
  assert( szNew==cellSizePtr(pPage, newCell) );
  assert( szNew<=MX_CELL_SIZE(pBt) );
  if( loc==0 && pCur->isValid ){
    int szOld;
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
    oldCell = findCell(pPage, pCur->idx);
    if( !pPage->leaf ){
      memcpy(newCell, oldCell, 4);
    }
    szOld = cellSizePtr(pPage, oldCell);
    rc = clearCell(pPage, oldCell);
    if( rc ) goto end_insert;
    dropCell(pPage, pCur->idx, szOld);
  }else if( loc<0 && pPage->nCell>0 ){
    assert( pPage->leaf );
    pCur->idx++;
    pCur->info.nSize = 0;
  }else{
    assert( pPage->leaf );
  }
  rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
  if( rc!=SQLITE_OK ) goto end_insert;
  rc = balance(pPage, 1);
  /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
  /* fflush(stdout); */
  if( rc==SQLITE_OK ){
    moveToRoot(pCur);
  }
end_insert:
  sqliteFree(newCell);
  return rc;
}

/*
** Delete the entry that the cursor is pointing to.  The cursor
** is left pointing at a random location.
*/
int sqlite3BtreeDelete(BtCursor *pCur){
  MemPage *pPage = pCur->pPage;
  unsigned char *pCell;
  int rc;
  Pgno pgnoChild = 0;
  Btree *pBt = pCur->pBt;

  assert( pPage->isInit );
  if( pBt->inTrans!=TRANS_WRITE ){
    /* Must start a transaction before doing a delete */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );
  if( pCur->idx >= pPage->nCell ){
    return SQLITE_ERROR;  /* The cursor is not pointing to anything */
  }
  if( !pCur->wrFlag ){
    return SQLITE_PERM;   /* Did not open this cursor for writing */
  }
  if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
  }
  rc = sqlite3pager_write(pPage->aData);
  if( rc ) return rc;

  /* Locate the cell within it's page and leave pCell pointing to the
  ** data. The clearCell() call frees any overflow pages associated with the
  ** cell. The cell itself is still intact.
  */
  pCell = findCell(pPage, pCur->idx);
  if( !pPage->leaf ){
    pgnoChild = get4byte(pCell);
  }
  rc = clearCell(pPage, pCell);
  if( rc ) return rc;

  if( !pPage->leaf ){
    /*
    ** The entry we are about to delete is not a leaf so if we do not
    ** do something we will leave a hole on an internal page.
    ** We have to fill the hole by moving in a cell from a leaf.  The
    ** next Cell after the one to be deleted is guaranteed to exist and
    ** to be a leaf so we can use it.
    */
    BtCursor leafCur;
    unsigned char *pNext;
    int szNext;
    int notUsed;
    unsigned char *tempCell;
    assert( !pPage->leafData );
    getTempCursor(pCur, &leafCur);
    rc = sqlite3BtreeNext(&leafCur, &notUsed);
    if( rc!=SQLITE_OK ){
      if( rc!=SQLITE_NOMEM ){
        rc = SQLITE_CORRUPT;  /* bkpt-CORRUPT */
      }
      return rc;
    }
    rc = sqlite3pager_write(leafCur.pPage->aData);
    if( rc ) return rc;
    TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
       pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno));
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
    pNext = findCell(leafCur.pPage, leafCur.idx);
    szNext = cellSizePtr(leafCur.pPage, pNext);
    assert( MX_CELL_SIZE(pBt)>=szNext+4 );
    tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
    if( tempCell==0 ) return SQLITE_NOMEM;
    rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0);
    if( rc!=SQLITE_OK ) return rc;
    put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild);
    rc = balance(pPage, 0);
    sqliteFree(tempCell);
    if( rc ) return rc;
    dropCell(leafCur.pPage, leafCur.idx, szNext);
    rc = balance(leafCur.pPage, 0);
    releaseTempCursor(&leafCur);
  }else{
    TRACE(("DELETE: table=%d delete from leaf %d\n",
       pCur->pgnoRoot, pPage->pgno));
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
    rc = balance(pPage, 0);
  }
  moveToRoot(pCur);
  return rc;
}

/*
** Create a new BTree table.  Write into *piTable the page
** number for the root page of the new table.
**
** The type of type is determined by the flags parameter.  Only the
** following values of flags are currently in use.  Other values for
** flags might not work:
**
**     BTREE_INTKEY|BTREE_LEAFDATA     Used for SQL tables with rowid keys
**     BTREE_ZERODATA                  Used for SQL indices
*/
int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){
  MemPage *pRoot;
  Pgno pgnoRoot;
  int rc;
  if( pBt->inTrans!=TRANS_WRITE ){
    /* Must start a transaction first */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );

  /* It is illegal to create a table if any cursors are open on the
  ** database. This is because in auto-vacuum mode the backend may
  ** need to move a database page to make room for the new root-page.
  ** If an open cursor was using the page a problem would occur.
  */
  if( pBt->pCursor ){
    return SQLITE_LOCKED;
  }

#ifdef SQLITE_OMIT_AUTOVACUUM
  rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);
  if( rc ) return rc;
#else
  if( pBt->autoVacuum ){
    Pgno pgnoMove;      /* Move a page here to make room for the root-page */
    MemPage *pPageMove; /* The page to move to. */

    /* Read the value of meta[3] from the database to determine where the
    ** root page of the new table should go. meta[3] is the largest root-page
    ** created so far, so the new root-page is (meta[3]+1).
    */
    rc = sqlite3BtreeGetMeta(pBt, 4, &pgnoRoot);
    if( rc!=SQLITE_OK ) return rc;
    pgnoRoot++;

    /* The new root-page may not be allocated on a pointer-map page, or the
    ** PENDING_BYTE page.
    */
    if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) ||
        pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
      pgnoRoot++;
    }
    assert( pgnoRoot>=3 );

    /* Allocate a page. The page that currently resides at pgnoRoot will
    ** be moved to the allocated page (unless the allocated page happens
    ** to reside at pgnoRoot).
    */
    rc = allocatePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
    if( rc!=SQLITE_OK ){
      return rc;
    }

    if( pgnoMove!=pgnoRoot ){
      u8 eType;
      Pgno iPtrPage;

      releasePage(pPageMove);
      rc = getPage(pBt, pgnoRoot, &pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
      assert( eType!=PTRMAP_ROOTPAGE );
      assert( eType!=PTRMAP_FREEPAGE );
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
      releasePage(pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = getPage(pBt, pgnoRoot, &pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = sqlite3pager_write(pRoot->aData);
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }
    }else{
      pRoot = pPageMove;
    } 

    /* Update the pointer-map and meta-data with the new root-page number. */
    rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
    if( rc ){
      releasePage(pRoot);
      return rc;
    }
    rc = sqlite3BtreeUpdateMeta(pBt, 4, pgnoRoot);
    if( rc ){
      releasePage(pRoot);
      return rc;
    }

  }else{
    rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);
    if( rc ) return rc;
  }
#endif
  assert( sqlite3pager_iswriteable(pRoot->aData) );
  zeroPage(pRoot, flags | PTF_LEAF);
  sqlite3pager_unref(pRoot->aData);
  *piTable = (int)pgnoRoot;
  return SQLITE_OK;
}

/*
** Erase the given database page and all its children.  Return
** the page to the freelist.
*/
static int clearDatabasePage(
  Btree *pBt,           /* The BTree that contains the table */
  Pgno pgno,            /* Page number to clear */
  MemPage *pParent,     /* Parent page.  NULL for the root */
  int freePageFlag      /* Deallocate page if true */
){
  MemPage *pPage;
  int rc;
  unsigned char *pCell;
  int i;

  if( pgno>sqlite3pager_pagecount(pBt->pPager) ){
    return SQLITE_CORRUPT;
  }

  rc = getAndInitPage(pBt, pgno, &pPage, pParent);
  if( rc ) return rc;
  rc = sqlite3pager_write(pPage->aData);
  if( rc ) return rc;
  for(i=0; i<pPage->nCell; i++){
    pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1);
      if( rc ) return rc;
    }
    rc = clearCell(pPage, pCell);
    if( rc ) return rc;
  }
  if( !pPage->leaf ){
    rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1);
    if( rc ) return rc;
  }
  if( freePageFlag ){
    rc = freePage(pPage);
  }else{
    zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
  }
  releasePage(pPage);
  return rc;
}

/*
** Delete all information from a single table in the database.  iTable is
** the page number of the root of the table.  After this routine returns,
** the root page is empty, but still exists.
**
** This routine will fail with SQLITE_LOCKED if there are any open
** read cursors on the table.  Open write cursors are moved to the
** root of the table.
*/
int sqlite3BtreeClearTable(Btree *pBt, int iTable){
  int rc;
  BtCursor *pCur;
  if( pBt->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    if( pCur->pgnoRoot==(Pgno)iTable ){
      if( pCur->wrFlag==0 ) return SQLITE_LOCKED;
      moveToRoot(pCur);
    }
  }
  rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0);
  if( rc ){
    sqlite3BtreeRollback(pBt);
  }
  return rc;
}

/*
** Erase all information in a table and add the root of the table to
** the freelist.  Except, the root of the principle table (the one on
** page 1) is never added to the freelist.
**
** This routine will fail with SQLITE_LOCKED if there are any open
** cursors on the table.
**
** If AUTOVACUUM is enabled and the page at iTable is not the last
** root page in the database file, then the last root page 
** in the database file is moved into the slot formerly occupied by
** iTable and that last slot formerly occupied by the last root page
** is added to the freelist instead of iTable.  In this say, all
** root pages are kept at the beginning of the database file, which
** is necessary for AUTOVACUUM to work right.  *piMoved is set to the 
** page number that used to be the last root page in the file before
** the move.  If no page gets moved, *piMoved is set to 0.
** The last root page is recorded in meta[3] and the value of
** meta[3] is updated by this procedure.
*/
int sqlite3BtreeDropTable(Btree *pBt, int iTable, int *piMoved){
  int rc;
  MemPage *pPage = 0;

  if( pBt->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }

  /* It is illegal to drop a table if any cursors are open on the
  ** database. This is because in auto-vacuum mode the backend may
  ** need to move another root-page to fill a gap left by the deleted
  ** root page. If an open cursor was using this page a problem would 
  ** occur.
  */
  if( pBt->pCursor ){
    return SQLITE_LOCKED;
  }

  rc = getPage(pBt, (Pgno)iTable, &pPage);
  if( rc ) return rc;
  rc = sqlite3BtreeClearTable(pBt, iTable);
  if( rc ) return rc;

  *piMoved = 0;

  if( iTable>1 ){
#ifdef SQLITE_OMIT_AUTOVACUUM
    rc = freePage(pPage);
    releasePage(pPage);
#else
    if( pBt->autoVacuum ){
      Pgno maxRootPgno;
      rc = sqlite3BtreeGetMeta(pBt, 4, &maxRootPgno);
      if( rc!=SQLITE_OK ){
        releasePage(pPage);
        return rc;
      }

      if( iTable==maxRootPgno ){
        /* If the table being dropped is the table with the largest root-page
        ** number in the database, put the root page on the free list. 
        */
        rc = freePage(pPage);
        releasePage(pPage);
        if( rc!=SQLITE_OK ){
          return rc;
        }
      }else{
        /* The table being dropped does not have the largest root-page
        ** number in the database. So move the page that does into the 
        ** gap left by the deleted root-page.
        */
        MemPage *pMove;
        releasePage(pPage);
        rc = getPage(pBt, maxRootPgno, &pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable);
        releasePage(pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        rc = getPage(pBt, maxRootPgno, &pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        rc = freePage(pMove);
        releasePage(pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        *piMoved = maxRootPgno;
      }

      /* Set the new 'max-root-page' value in the database header. This
      ** is the old value less one, less one more if that happens to
      ** be a root-page number, less one again if that is the
      ** PENDING_BYTE_PAGE.
      */
      maxRootPgno--;
      if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
        maxRootPgno--;
      }
      if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){
        maxRootPgno--;
      }
      assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );

      rc = sqlite3BtreeUpdateMeta(pBt, 4, maxRootPgno);
    }else{
      rc = freePage(pPage);
      releasePage(pPage);
    }
#endif
  }else{
    /* If sqlite3BtreeDropTable was called on page 1. */
    zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
    releasePage(pPage);
  }
  return rc;  
}


/*
** Read the meta-information out of a database file.  Meta[0]
** is the number of free pages currently in the database.  Meta[1]
** through meta[15] are available for use by higher layers.  Meta[0]
** is read-only, the others are read/write.
** 
** The schema layer numbers meta values differently.  At the schema
** layer (and the SetCookie and ReadCookie opcodes) the number of
** free pages is not visible.  So Cookie[0] is the same as Meta[1].
*/
int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){
  int rc;
  unsigned char *pP1;

  assert( idx>=0 && idx<=15 );
  rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1);
  if( rc ) return rc;
  *pMeta = get4byte(&pP1[36 + idx*4]);
  sqlite3pager_unref(pP1);

  /* If autovacuumed is disabled in this build but we are trying to 
  ** access an autovacuumed database, then make the database readonly. 
  */
#ifdef SQLITE_OMIT_AUTOVACUUM
  if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
#endif

  return SQLITE_OK;
}

/*
** Write meta-information back into the database.  Meta[0] is
** read-only and may not be written.
*/
int sqlite3BtreeUpdateMeta(Btree *pBt, int idx, u32 iMeta){
  unsigned char *pP1;
  int rc;
  assert( idx>=1 && idx<=15 );
  if( pBt->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( pBt->pPage1!=0 );
  pP1 = pBt->pPage1->aData;
  rc = sqlite3pager_write(pP1);
  if( rc ) return rc;
  put4byte(&pP1[36 + idx*4], iMeta);
  return SQLITE_OK;
}

/*
** Return the flag byte at the beginning of the page that the cursor
** is currently pointing to.
*/
int sqlite3BtreeFlags(BtCursor *pCur){
  MemPage *pPage = pCur->pPage;
  return pPage ? pPage->aData[pPage->hdrOffset] : 0;
}

#ifdef SQLITE_DEBUG
/*
** Print a disassembly of the given page on standard output.  This routine
** is used for debugging and testing only.
*/
static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){
  int rc;
  MemPage *pPage;
  int i, j, c;
  int nFree;
  u16 idx;
  int hdr;
  int nCell;
  int isInit;
  unsigned char *data;
  char range[20];
  unsigned char payload[20];

  rc = getPage(pBt, (Pgno)pgno, &pPage);
  isInit = pPage->isInit;
  if( pPage->isInit==0 ){
    initPage(pPage, pParent);
  }
  if( rc ){
    return rc;
  }
  hdr = pPage->hdrOffset;
  data = pPage->aData;
  c = data[hdr];
  pPage->intKey = (c & (PTF_INTKEY|PTF_LEAFDATA))!=0;
  pPage->zeroData = (c & PTF_ZERODATA)!=0;
  pPage->leafData = (c & PTF_LEAFDATA)!=0;
  pPage->leaf = (c & PTF_LEAF)!=0;
  pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
  nCell = get2byte(&data[hdr+3]);
  sqlite3DebugPrintf("PAGE %d:  flags=0x%02x  frag=%d   parent=%d\n", pgno,
    data[hdr], data[hdr+7], 
    (pPage->isInit && pPage->pParent) ? pPage->pParent->pgno : 0);
  assert( hdr == (pgno==1 ? 100 : 0) );
  idx = hdr + 12 - pPage->leaf*4;
  for(i=0; i<nCell; i++){
    CellInfo info;
    Pgno child;
    unsigned char *pCell;
    int sz;
    int addr;

    addr = get2byte(&data[idx + 2*i]);
    pCell = &data[addr];
    parseCellPtr(pPage, pCell, &info);
    sz = info.nSize;
    sprintf(range,"%d..%d", addr, addr+sz-1);
    if( pPage->leaf ){
      child = 0;
    }else{
      child = get4byte(pCell);
    }
    sz = info.nData;
    if( !pPage->intKey ) sz += info.nKey;
    if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
    memcpy(payload, &pCell[info.nHeader], sz);
    for(j=0; j<sz; j++){
      if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
    }
    payload[sz] = 0;
    sqlite3DebugPrintf(
      "cell %2d: i=%-10s chld=%-4d nk=%-4lld nd=%-4d payload=%s\n",
      i, range, child, info.nKey, info.nData, payload
    );
  }
  if( !pPage->leaf ){
    sqlite3DebugPrintf("right_child: %d\n", get4byte(&data[hdr+8]));
  }
  nFree = 0;
  i = 0;
  idx = get2byte(&data[hdr+1]);
  while( idx>0 && idx<pPage->pBt->usableSize ){
    int sz = get2byte(&data[idx+2]);
    sprintf(range,"%d..%d", idx, idx+sz-1);
    nFree += sz;
    sqlite3DebugPrintf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
       i, range, sz, nFree);
    idx = get2byte(&data[idx]);
    i++;
  }
  if( idx!=0 ){
    sqlite3DebugPrintf("ERROR: next freeblock index out of range: %d\n", idx);
  }
  if( recursive && !pPage->leaf ){
    for(i=0; i<nCell; i++){
      unsigned char *pCell = findCell(pPage, i);
      btreePageDump(pBt, get4byte(pCell), 1, pPage);
      idx = get2byte(pCell);
    }
    btreePageDump(pBt, get4byte(&data[hdr+8]), 1, pPage);
  }
  pPage->isInit = isInit;
  sqlite3pager_unref(data);
  fflush(stdout);
  return SQLITE_OK;
}
int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
  return btreePageDump(pBt, pgno, recursive, 0);
}
#endif

#ifdef SQLITE_TEST
/*
** Fill aResult[] with information about the entry and page that the
** cursor is pointing to.
** 
**   aResult[0] =  The page number
**   aResult[1] =  The entry number
**   aResult[2] =  Total number of entries on this page
**   aResult[3] =  Cell size (local payload + header)
**   aResult[4] =  Number of free bytes on this page
**   aResult[5] =  Number of free blocks on the page
**   aResult[6] =  Total payload size (local + overflow)
**   aResult[7] =  Header size in bytes
**   aResult[8] =  Local payload size
**   aResult[9] =  Parent page number
**
** This routine is used for testing and debugging only.
*/
int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
  int cnt, idx;
  MemPage *pPage = pCur->pPage;
  BtCursor tmpCur;

  pageIntegrity(pPage);
  assert( pPage->isInit );
  getTempCursor(pCur, &tmpCur);
  while( upCnt-- ){
    moveToParent(&tmpCur);
  }
  pPage = tmpCur.pPage;
  pageIntegrity(pPage);
  aResult[0] = sqlite3pager_pagenumber(pPage->aData);
  assert( aResult[0]==pPage->pgno );
  aResult[1] = tmpCur.idx;
  aResult[2] = pPage->nCell;
  if( tmpCur.idx>=0 && tmpCur.idx<pPage->nCell ){
    getCellInfo(&tmpCur);
    aResult[3] = tmpCur.info.nSize;
    aResult[6] = tmpCur.info.nData;
    aResult[7] = tmpCur.info.nHeader;
    aResult[8] = tmpCur.info.nLocal;
  }else{
    aResult[3] = 0;
    aResult[6] = 0;
    aResult[7] = 0;
    aResult[8] = 0;
  }
  aResult[4] = pPage->nFree;
  cnt = 0;
  idx = get2byte(&pPage->aData[pPage->hdrOffset+1]);
  while( idx>0 && idx<pPage->pBt->usableSize ){
    cnt++;
    idx = get2byte(&pPage->aData[idx]);
  }
  aResult[5] = cnt;
  if( pPage->pParent==0 || isRootPage(pPage) ){
    aResult[9] = 0;
  }else{
    aResult[9] = pPage->pParent->pgno;
  }
  releaseTempCursor(&tmpCur);
  return SQLITE_OK;
}
#endif

/*
** Return the pager associated with a BTree.  This routine is used for
** testing and debugging only.
*/
Pager *sqlite3BtreePager(Btree *pBt){
  return pBt->pPager;
}

/*
** This structure is passed around through all the sanity checking routines
** in order to keep track of some global state information.
*/
typedef struct IntegrityCk IntegrityCk;
struct IntegrityCk {
  Btree *pBt;    /* The tree being checked out */
  Pager *pPager; /* The associated pager.  Also accessible by pBt->pPager */
  int nPage;     /* Number of pages in the database */
  int *anRef;    /* Number of times each page is referenced */
  char *zErrMsg; /* An error message.  NULL of no errors seen. */
};

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Append a message to the error message string.
*/
static void checkAppendMsg(
  IntegrityCk *pCheck,
  char *zMsg1,
  const char *zFormat,
  ...
){
  va_list ap;
  char *zMsg2;
  va_start(ap, zFormat);
  zMsg2 = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
  if( zMsg1==0 ) zMsg1 = "";
  if( pCheck->zErrMsg ){
    char *zOld = pCheck->zErrMsg;
    pCheck->zErrMsg = 0;
    sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
    sqliteFree(zOld);
  }else{
    sqlite3SetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
  }
  sqliteFree(zMsg2);
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Add 1 to the reference count for page iPage.  If this is the second
** reference to the page, add an error message to pCheck->zErrMsg.
** Return 1 if there are 2 ore more references to the page and 0 if
** if this is the first reference to the page.
**
** Also check that the page number is in bounds.
*/
static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){
  if( iPage==0 ) return 1;
  if( iPage>pCheck->nPage || iPage<0 ){
    checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
    return 1;
  }
  if( pCheck->anRef[iPage]==1 ){
    checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
    return 1;
  }
  return  (pCheck->anRef[iPage]++)>1;
}

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Check that the entry in the pointer-map for page iChild maps to 
** page iParent, pointer type ptrType. If not, append an error message
** to pCheck.
*/
static void checkPtrmap(
  IntegrityCk *pCheck,   /* Integrity check context */
  Pgno iChild,           /* Child page number */
  u8 eType,              /* Expected pointer map type */
  Pgno iParent,          /* Expected pointer map parent page number */
  char *zContext         /* Context description (used for error msg) */
){
  int rc;
  u8 ePtrmapType;
  Pgno iPtrmapParent;

  rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
  if( rc!=SQLITE_OK ){
    checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
    return;
  }

  if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
    checkAppendMsg(pCheck, zContext, 
      "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", 
      iChild, eType, iParent, ePtrmapType, iPtrmapParent);
  }
}
#endif

/*
** Check the integrity of the freelist or of an overflow page list.
** Verify that the number of pages on the list is N.
*/
static void checkList(
  IntegrityCk *pCheck,  /* Integrity checking context */
  int isFreeList,       /* True for a freelist.  False for overflow page list */
  int iPage,            /* Page number for first page in the list */
  int N,                /* Expected number of pages in the list */
  char *zContext        /* Context for error messages */
){
  int i;
  int expected = N;
  int iFirst = iPage;
  while( N-- > 0 ){
    unsigned char *pOvfl;
    if( iPage<1 ){
      checkAppendMsg(pCheck, zContext,
         "%d of %d pages missing from overflow list starting at %d",
          N+1, expected, iFirst);
      break;
    }
    if( checkRef(pCheck, iPage, zContext) ) break;
    if( sqlite3pager_get(pCheck->pPager, (Pgno)iPage, (void**)&pOvfl) ){
      checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
      break;
    }
    if( isFreeList ){
      int n = get4byte(&pOvfl[4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pCheck->pBt->autoVacuum ){
        checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
      }
#endif
      if( n>pCheck->pBt->usableSize/4-8 ){
        checkAppendMsg(pCheck, zContext,
           "freelist leaf count too big on page %d", iPage);
        N--;
      }else{
        for(i=0; i<n; i++){
          Pgno iFreePage = get4byte(&pOvfl[8+i*4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
          if( pCheck->pBt->autoVacuum ){
            checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
          }
#endif
          checkRef(pCheck, iFreePage, zContext);
        }
        N -= n;
      }
    }
#ifndef SQLITE_OMIT_AUTOVACUUM
    else{
      /* If this database supports auto-vacuum and iPage is not the last
      ** page in this overflow list, check that the pointer-map entry for
      ** the following page matches iPage.
      */
      if( pCheck->pBt->autoVacuum && N>0 ){
        i = get4byte(pOvfl);
        checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
      }
    }
#endif
    iPage = get4byte(pOvfl);
    sqlite3pager_unref(pOvfl);
  }
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Do various sanity checks on a single page of a tree.  Return
** the tree depth.  Root pages return 0.  Parents of root pages
** return 1, and so forth.
** 
** These checks are done:
**
**      1.  Make sure that cells and freeblocks do not overlap
**          but combine to completely cover the page.
**  NO  2.  Make sure cell keys are in order.
**  NO  3.  Make sure no key is less than or equal to zLowerBound.
**  NO  4.  Make sure no key is greater than or equal to zUpperBound.
**      5.  Check the integrity of overflow pages.
**      6.  Recursively call checkTreePage on all children.
**      7.  Verify that the depth of all children is the same.
**      8.  Make sure this page is at least 33% full or else it is
**          the root of the tree.
*/
static int checkTreePage(
  IntegrityCk *pCheck,  /* Context for the sanity check */
  int iPage,            /* Page number of the page to check */
  MemPage *pParent,     /* Parent page */
  char *zParentContext, /* Parent context */
  char *zLowerBound,    /* All keys should be greater than this, if not NULL */
  int nLower,           /* Number of characters in zLowerBound */
  char *zUpperBound,    /* All keys should be less than this, if not NULL */
  int nUpper            /* Number of characters in zUpperBound */
){
  MemPage *pPage;
  int i, rc, depth, d2, pgno, cnt;
  int hdr, cellStart;
  int nCell;
  u8 *data;
  BtCursor cur;
  Btree *pBt;
  int maxLocal, usableSize;
  char zContext[100];
  char *hit;

  sprintf(zContext, "Page %d: ", iPage);

  /* Check that the page exists
  */
  cur.pBt = pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
  if( (rc = getPage(pBt, (Pgno)iPage, &pPage))!=0 ){
    checkAppendMsg(pCheck, zContext,
       "unable to get the page. error code=%d", rc);
    return 0;
  }
  maxLocal = pPage->leafData ? pBt->maxLeaf : pBt->maxLocal;
  if( (rc = initPage(pPage, pParent))!=0 ){
    checkAppendMsg(pCheck, zContext, "initPage() returns error code %d", rc);
    releasePage(pPage);
    return 0;
  }

  /* Check out all the cells.
  */
  depth = 0;
  cur.pPage = pPage;
  for(i=0; i<pPage->nCell; i++){
    u8 *pCell;
    int sz;
    CellInfo info;

    /* Check payload overflow pages
    */
    sprintf(zContext, "On tree page %d cell %d: ", iPage, i);
    pCell = findCell(pPage,i);
    parseCellPtr(pPage, pCell, &info);
    sz = info.nData;
    if( !pPage->intKey ) sz += info.nKey;
    if( sz>info.nLocal ){
      int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
      Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
      }
#endif
      checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
    }

    /* Check sanity of left child page.
    */
    if( !pPage->leaf ){
      pgno = get4byte(pCell);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
      }
#endif
      d2 = checkTreePage(pCheck,pgno,pPage,zContext,0,0,0,0);
      if( i>0 && d2!=depth ){
        checkAppendMsg(pCheck, zContext, "Child page depth differs");
      }
      depth = d2;
    }
  }
  if( !pPage->leaf ){
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    sprintf(zContext, "On page %d at right child: ", iPage);
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum ){
      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0);
    }
#endif
    checkTreePage(pCheck, pgno, pPage, zContext,0,0,0,0);
  }
 
  /* Check for complete coverage of the page
  */
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  hit = sqliteMalloc( usableSize );
  if( hit ){
    memset(hit, 1, get2byte(&data[hdr+5]));
    nCell = get2byte(&data[hdr+3]);
    cellStart = hdr + 12 - 4*pPage->leaf;
    for(i=0; i<nCell; i++){
      int pc = get2byte(&data[cellStart+i*2]);
      int size = cellSizePtr(pPage, &data[pc]);
      int j;
      if( (pc+size-1)>=usableSize || pc<0 ){
        checkAppendMsg(pCheck, 0, 
            "Corruption detected in cell %d on page %d",i,iPage,0);
      }else{
        for(j=pc+size-1; j>=pc; j--) hit[j]++;
      }
    }
    for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i<usableSize && cnt<10000; 
           cnt++){
      int size = get2byte(&data[i+2]);
      int j;
      if( (i+size-1)>=usableSize || i<0 ){
        checkAppendMsg(pCheck, 0,  
            "Corruption detected in cell %d on page %d",i,iPage,0);
      }else{
        for(j=i+size-1; j>=i; j--) hit[j]++;
      }
      i = get2byte(&data[i]);
    }
    for(i=cnt=0; i<usableSize; i++){
      if( hit[i]==0 ){
        cnt++;
      }else if( hit[i]>1 ){
        checkAppendMsg(pCheck, 0,
          "Multiple uses for byte %d of page %d", i, iPage);
        break;
      }
    }
    if( cnt!=data[hdr+7] ){
      checkAppendMsg(pCheck, 0, 
          "Fragmented space is %d byte reported as %d on page %d",
          cnt, data[hdr+7], iPage);
    }
  }
  sqliteFree(hit);

  releasePage(pPage);
  return depth+1;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** This routine does a complete check of the given BTree file.  aRoot[] is
** an array of pages numbers were each page number is the root page of
** a table.  nRoot is the number of entries in aRoot.
**
** If everything checks out, this routine returns NULL.  If something is
** amiss, an error message is written into memory obtained from malloc()
** and a pointer to that error message is returned.  The calling function
** is responsible for freeing the error message when it is done.
*/
char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){
  int i;
  int nRef;
  IntegrityCk sCheck;

  nRef = *sqlite3pager_stats(pBt->pPager);
  if( lockBtree(pBt)!=SQLITE_OK ){
    return sqliteStrDup("Unable to acquire a read lock on the database");
  }
  sCheck.pBt = pBt;
  sCheck.pPager = pBt->pPager;
  sCheck.nPage = sqlite3pager_pagecount(sCheck.pPager);
  if( sCheck.nPage==0 ){
    unlockBtreeIfUnused(pBt);
    return 0;
  }
  sCheck.anRef = sqliteMallocRaw( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
  if( !sCheck.anRef ){
    unlockBtreeIfUnused(pBt);
    return sqlite3MPrintf("Unable to malloc %d bytes", 
        (sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
  }
  for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
  i = PENDING_BYTE_PAGE(pBt);
  if( i<=sCheck.nPage ){
    sCheck.anRef[i] = 1;
  }
  sCheck.zErrMsg = 0;

  /* Check the integrity of the freelist
  */
  checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
            get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");

  /* Check all the tables.
  */
  for(i=0; i<nRoot; i++){
    if( aRoot[i]==0 ) continue;
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum && aRoot[i]>1 ){
      checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
    }
#endif
    checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0);
  }

  /* Make sure every page in the file is referenced
  */
  for(i=1; i<=sCheck.nPage; i++){
#ifdef SQLITE_OMIT_AUTOVACUUM
    if( sCheck.anRef[i]==0 ){
      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
    }
#else
    /* If the database supports auto-vacuum, make sure no tables contain
    ** references to pointer-map pages.
    */
    if( sCheck.anRef[i]==0 && 
       (PTRMAP_PAGENO(pBt->usableSize, i)!=i || !pBt->autoVacuum) ){
      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
    }
    if( sCheck.anRef[i]!=0 && 
       (PTRMAP_PAGENO(pBt->usableSize, i)==i && pBt->autoVacuum) ){
      checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
    }
#endif
  }

  /* Make sure this analysis did not leave any unref() pages
  */
  unlockBtreeIfUnused(pBt);
  if( nRef != *sqlite3pager_stats(pBt->pPager) ){
    checkAppendMsg(&sCheck, 0, 
      "Outstanding page count goes from %d to %d during this analysis",
      nRef, *sqlite3pager_stats(pBt->pPager)
    );
  }

  /* Clean  up and report errors.
  */
  sqliteFree(sCheck.anRef);
  return sCheck.zErrMsg;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/*
** Return the full pathname of the underlying database file.
*/
const char *sqlite3BtreeGetFilename(Btree *pBt){
  assert( pBt->pPager!=0 );
  return sqlite3pager_filename(pBt->pPager);
}

/*
** Return the pathname of the directory that contains the database file.
*/
const char *sqlite3BtreeGetDirname(Btree *pBt){
  assert( pBt->pPager!=0 );
  return sqlite3pager_dirname(pBt->pPager);
}

/*
** Return the pathname of the journal file for this database. The return
** value of this routine is the same regardless of whether the journal file
** has been created or not.
*/
const char *sqlite3BtreeGetJournalname(Btree *pBt){
  assert( pBt->pPager!=0 );
  return sqlite3pager_journalname(pBt->pPager);
}

#ifndef SQLITE_OMIT_VACUUM
/*
** Copy the complete content of pBtFrom into pBtTo.  A transaction
** must be active for both files.
**
** The size of file pBtFrom may be reduced by this operation.
** If anything goes wrong, the transaction on pBtFrom is rolled back.
*/
int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
  int rc = SQLITE_OK;
  Pgno i, nPage, nToPage;

  if( pBtTo->inTrans!=TRANS_WRITE || pBtFrom->inTrans!=TRANS_WRITE ){
    return SQLITE_ERROR;
  }
  if( pBtTo->pCursor ) return SQLITE_BUSY;
  nToPage = sqlite3pager_pagecount(pBtTo->pPager);
  nPage = sqlite3pager_pagecount(pBtFrom->pPager);
  for(i=1; rc==SQLITE_OK && i<=nPage; i++){
    void *pPage;
    rc = sqlite3pager_get(pBtFrom->pPager, i, &pPage);
    if( rc ) break;
    rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage);
    if( rc ) break;
    sqlite3pager_unref(pPage);
  }
  for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
    void *pPage;
    rc = sqlite3pager_get(pBtTo->pPager, i, &pPage);
    if( rc ) break;
    rc = sqlite3pager_write(pPage);
    sqlite3pager_unref(pPage);
    sqlite3pager_dont_write(pBtTo->pPager, i);
  }
  if( !rc && nPage<nToPage ){
    rc = sqlite3pager_truncate(pBtTo->pPager, nPage);
  }
  if( rc ){
    sqlite3BtreeRollback(pBtTo);
  }
  return rc;  
}
#endif /* SQLITE_OMIT_VACUUM */

/*
** Return non-zero if a transaction is active.
*/
int sqlite3BtreeIsInTrans(Btree *pBt){
  return (pBt && (pBt->inTrans==TRANS_WRITE));
}

/*
** Return non-zero if a statement transaction is active.
*/
int sqlite3BtreeIsInStmt(Btree *pBt){
  return (pBt && pBt->inStmt);
}

/*
** This call is a no-op if no write-transaction is currently active on pBt.
**
** Otherwise, sync the database file for the btree pBt. zMaster points to
** the name of a master journal file that should be written into the
** individual journal file, or is NULL, indicating no master journal file 
** (single database transaction).
**
** When this is called, the master journal should already have been
** created, populated with this journal pointer and synced to disk.
**
** Once this is routine has returned, the only thing required to commit
** the write-transaction for this database file is to delete the journal.
*/
int sqlite3BtreeSync(Btree *pBt, const char *zMaster){
  if( pBt->inTrans==TRANS_WRITE ){
#ifndef SQLITE_OMIT_AUTOVACUUM
    Pgno nTrunc = 0;
    if( pBt->autoVacuum ){
      int rc = autoVacuumCommit(pBt, &nTrunc); 
      if( rc!=SQLITE_OK ) return rc;
    }
    return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
#endif
    return sqlite3pager_sync(pBt->pPager, zMaster, 0);
  }
  return SQLITE_OK;
}
Added SQLite.Interop/src/btree.h.




























































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2001 September 15
**
** 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 header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.1 2005/03/01 16:04:27 rmsimpson Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
#define SQLITE_N_BTREE_META 10

/*
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
*/
#ifndef SQLITE_DEFAULT_AUTOVACUUM
  #define SQLITE_DEFAULT_AUTOVACUUM 0
#endif

/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;


int sqlite3BtreeOpen(
  const char *zFilename,   /* Name of database file to open */
  Btree **,                /* Return open Btree* here */
  int flags                /* Flags */
);

/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
** following values.
**
** NOTE:  These values must match the corresponding PAGER_ values in
** pager.h.
*/
#define BTREE_OMIT_JOURNAL  1  /* Do not use journal.  No argument */
#define BTREE_NO_READLOCK   2  /* Omit readlocks on readonly files */
#define BTREE_MEMORY        4  /* In-memory DB.  No argument */

int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
int sqlite3BtreeSetCacheSize(Btree*,int);
int sqlite3BtreeSetSafetyLevel(Btree*,int);
int sqlite3BtreeSetPageSize(Btree*,int,int);
int sqlite3BtreeGetPageSize(Btree*);
int sqlite3BtreeGetReserve(Btree*);
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeBeginTrans(Btree*,int);
int sqlite3BtreeCommit(Btree*);
int sqlite3BtreeRollback(Btree*);
int sqlite3BtreeBeginStmt(Btree*);
int sqlite3BtreeCommitStmt(Btree*);
int sqlite3BtreeRollbackStmt(Btree*);
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
int sqlite3BtreeIsInTrans(Btree*);
int sqlite3BtreeIsInStmt(Btree*);
int sqlite3BtreeSync(Btree*, const char *zMaster);

const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetDirname(Btree *);
const char *sqlite3BtreeGetJournalname(Btree *);
int sqlite3BtreeCopyFile(Btree *, Btree *);

/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
** of the following flags:
*/
#define BTREE_INTKEY     1    /* Table has only 64-bit signed integer keys */
#define BTREE_ZERODATA   2    /* Table has keys only - no data */
#define BTREE_LEAFDATA   4    /* Data stored in leaves only.  Implies INTKEY */

int sqlite3BtreeDropTable(Btree*, int, int*);
int sqlite3BtreeClearTable(Btree*, int);
int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);

int sqlite3BtreeCursor(
  Btree*,                              /* BTree containing table to open */
  int iTable,                          /* Index of root page */
  int wrFlag,                          /* 1 for writing.  0 for read-only */
  int(*)(void*,int,const void*,int,const void*),  /* Key comparison function */
  void*,                               /* First argument to compare function */
  BtCursor **ppCursor                  /* Returned cursor */
);

void sqlite3BtreeSetCompare(
  BtCursor *,
  int(*)(void*,int,const void*,int,const void*),
  void*
);

int sqlite3BtreeCloseCursor(BtCursor*);
int sqlite3BtreeMoveto(BtCursor*, const void *pKey, i64 nKey, int *pRes);
int sqlite3BtreeDelete(BtCursor*);
int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
                                  const void *pData, int nData);
int sqlite3BtreeFirst(BtCursor*, int *pRes);
int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int *pRes);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreeFlags(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int *pRes);
int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);

char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot);
struct Pager *sqlite3BtreePager(Btree*);


#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
#endif

#ifdef SQLITE_DEBUG
int sqlite3BtreePageDump(Btree*, int, int recursive);
#else
#define sqlite3BtreePageDump(X,Y,Z) SQLITE_OK
#endif

#endif /* _BTREE_H_ */
Added SQLite.Interop/src/build.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
/*
** 2001 September 15
**
** 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 file contains C code routines that are called by the SQLite parser
** when syntax rules are reduced.  The routines in this file handle the
** following kinds of SQL syntax:
**
**     CREATE TABLE
**     DROP TABLE
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.1 2005/03/01 16:04:28 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
*/
void sqlite3BeginParse(Parse *pParse, int explainFlag){
  pParse->explain = explainFlag;
  pParse->nVar = 0;
}

/*
** This routine is called after a single SQL statement has been
** parsed and a VDBE program to execute that statement has been
** prepared.  This routine puts the finishing touches on the
** VDBE program and resets the pParse structure for the next
** parse.
**
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
void sqlite3FinishCoding(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( sqlite3_malloc_failed ) return;
  if( pParse->nested ) return;
  if( !pParse->pVdbe ){
    if( pParse->rc==SQLITE_OK && pParse->nErr ){
      pParse->rc = SQLITE_ERROR;
    }
    return;
  }

  /* Begin by generating some termination code at the end of the
  ** vdbe program
  */
  db = pParse->db;
  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_Halt, 0, 0);

    /* The cookie mask contains one bit for each database file open.
    ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
    ** set for each database that is used.  Generate code to start a
    ** transaction on each used database and to verify the schema cookie
    ** on each used database.
    */
    if( pParse->cookieGoto>0 ){
      u32 mask;
      int iDb;
      sqlite3VdbeChangeP2(v, pParse->cookieGoto-1, sqlite3VdbeCurrentAddr(v));
      for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
        if( (mask & pParse->cookieMask)==0 ) continue;
        sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
        sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
      }
      sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
    }

    /* Add a No-op that contains the complete text of the compiled SQL
    ** statement as its P3 argument.  This does not change the functionality
    ** of the program. 
    **
    ** This is used to implement sqlite3_trace().
    */
    sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);
  }


  /* Get the VDBE program ready for execution
  */
  if( v && pParse->nErr==0 ){
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqlite3VdbeTrace(v, trace);
    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
                         pParse->nTab+3, pParse->nMaxDepth+1, pParse->explain);
    pParse->rc = SQLITE_DONE;
    pParse->colNamesSet = 0;
  }else if( pParse->rc==SQLITE_OK ){
    pParse->rc = SQLITE_ERROR;
  }
  pParse->nTab = 0;
  pParse->nMem = 0;
  pParse->nSet = 0;
  pParse->nVar = 0;
  pParse->cookieMask = 0;
  pParse->cookieGoto = 0;
}

/*
** Run the parser and code generator recursively in order to generate
** code for the SQL statement given onto the end of the pParse context
** currently under construction.  When the parser is run recursively
** this way, the final OP_Halt is not appended and other initialization
** and finalization steps are omitted because those are handling by the
** outermost parser.
**
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  int rc;
# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
  char saveBuf[SAVE_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
  if( zSql==0 ){
    return;   /* A malloc must have failed */
  }
  pParse->nested++;
  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
  memset(&pParse->nVar, 0, SAVE_SZ);
  rc = sqlite3RunParser(pParse, zSql, 0);
  sqliteFree(zSql);
  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
  pParse->nested--;
}

/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
** database containing the table.  Return NULL if not found.
**
** If zDatabase is 0, all databases are searched for the table and the
** first matching table is returned.  (No checking for duplicate table
** names is done.)  The search order is TEMP first, then MAIN, then any
** auxiliary databases added using the ATTACH command.
**
** See also sqlite3LocateTable().
*/
Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
  Table *p = 0;
  int i;
  assert( zName!=0 );
  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
    if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
    p = sqlite3HashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
    if( p ) break;
  }
  return p;
}

/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
** database containing the table.  Return NULL if not found.  Also leave an
** error message in pParse->zErrMsg.
**
** The difference between this routine and sqlite3FindTable() is that this
** routine leaves an error message in pParse->zErrMsg where
** sqlite3FindTable() does not.
*/
Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){
  Table *p;

  /* Read the database schema. If an error occurs, leave an error message
  ** and code in pParse and return NULL. */
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    return 0;
  }

  p = sqlite3FindTable(pParse->db, zName, zDbase);
  if( p==0 ){
    if( zDbase ){
      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
    }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){
      sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
         zName, zDbase);
    }else{
      sqlite3ErrorMsg(pParse, "no such table: %s", zName);
    }
    pParse->checkSchema = 1;
  }
  return p;
}

/*
** Locate the in-memory structure that describes 
** a particular index given the name of that index
** and the name of the database that contains the index.
** Return NULL if not found.
**
** If zDatabase is 0, all databases are searched for the
** table and the first matching index is returned.  (No checking
** for duplicate index names is done.)  The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
*/
Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;
  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
    p = sqlite3HashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
    if( p ) break;
  }
  return p;
}

/*
** Reclaim the memory used by an index
*/
static void freeIndex(Index *p){
  sqliteFree(p->zColAff);
  sqliteFree(p);
}

/*
** Remove the given index from the index hash table, and free
** its memory structures.
**
** The index is removed from the database hash tables but
** it is not unlinked from the Table that it indexes.
** Unlinking from the Table must be done by the calling function.
*/
static void sqliteDeleteIndex(sqlite3 *db, Index *p){
  Index *pOld;

  assert( db!=0 && p->zName!=0 );
  pOld = sqlite3HashInsert(&db->aDb[p->iDb].idxHash, p->zName,
                          strlen(p->zName)+1, 0);
  if( pOld!=0 && pOld!=p ){
    sqlite3HashInsert(&db->aDb[p->iDb].idxHash, pOld->zName,
                     strlen(pOld->zName)+1, pOld);
  }
  freeIndex(p);
}

/*
** Unlink the given index from its table, then remove
** the index from the index hash table and free its memory
** structures.
*/
void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
  Index *pIndex;
  int len;

  len = strlen(zIdxName);
  pIndex = sqlite3HashInsert(&db->aDb[iDb].idxHash, zIdxName, len+1, 0);
  if( pIndex ){
    if( pIndex->pTable->pIndex==pIndex ){
      pIndex->pTable->pIndex = pIndex->pNext;
    }else{
      Index *p;
      for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}
      if( p && p->pNext==pIndex ){
        p->pNext = pIndex->pNext;
      }
    }
    freeIndex(pIndex);
  }
  db->flags |= SQLITE_InternChanges;
}

/*
** Erase all schema information from the in-memory hash tables of
** a single database.  This routine is called to reclaim memory
** before the database closes.  It is also called during a rollback
** if there were schema changes during the transaction or if a
** schema-cookie mismatch occurs.
**
** If iDb<=0 then reset the internal schema tables for all database
** files.  If iDb>=2 then reset the internal schema for only the
** single file indicated.
*/
void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
  HashElem *pElem;
  Hash temp1;
  Hash temp2;
  int i, j;

  assert( iDb>=0 && iDb<db->nDb );
  db->flags &= ~SQLITE_Initialized;
  for(i=iDb; i<db->nDb; i++){
    Db *pDb = &db->aDb[i];
    temp1 = pDb->tblHash;
    temp2 = pDb->trigHash;
    sqlite3HashInit(&pDb->trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashClear(&pDb->aFKey);
    sqlite3HashClear(&pDb->idxHash);
    for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
      sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
    }
    sqlite3HashClear(&temp2);
    sqlite3HashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0);
    for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
      Table *pTab = sqliteHashData(pElem);
      sqlite3DeleteTable(db, pTab);
    }
    sqlite3HashClear(&temp1);
    pDb->pSeqTab = 0;
    DbClearProperty(db, i, DB_SchemaLoaded);
    if( iDb>0 ) return;
  }
  assert( iDb==0 );
  db->flags &= ~SQLITE_InternChanges;

  /* If one or more of the auxiliary database files has been closed,
  ** then remove then from the auxiliary database list.  We take the
  ** opportunity to do this here since we have just deleted all of the
  ** schema hash tables and therefore do not have to make any changes
  ** to any of those tables.
  */
  for(i=0; i<db->nDb; i++){
    struct Db *pDb = &db->aDb[i];
    if( pDb->pBt==0 ){
      if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
      pDb->pAux = 0;
    }
  }
  for(i=j=2; i<db->nDb; i++){
    struct Db *pDb = &db->aDb[i];
    if( pDb->pBt==0 ){
      sqliteFree(pDb->zName);
      pDb->zName = 0;
      continue;
    }
    if( j<i ){
      db->aDb[j] = db->aDb[i];
    }
    j++;
  }
  memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
  db->nDb = j;
  if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
    memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
    sqliteFree(db->aDb);
    db->aDb = db->aDbStatic;
  }
}

/*
** This routine is called whenever a rollback occurs.  If there were
** schema changes during the transaction, then we have to reset the
** internal hash tables and reload them from disk.
*/
void sqlite3RollbackInternalChanges(sqlite3 *db){
  if( db->flags & SQLITE_InternChanges ){
    sqlite3ResetInternalSchema(db, 0);
  }
}

/*
** This routine is called when a commit occurs.
*/
void sqlite3CommitInternalChanges(sqlite3 *db){
  db->flags &= ~SQLITE_InternChanges;
}

/*
** Clear the column names from a table or view.
*/
static void sqliteResetColumnNames(Table *pTable){
  int i;
  Column *pCol;
  assert( pTable!=0 );
  for(i=0, pCol=pTable->aCol; i<pTable->nCol; i++, pCol++){
    sqliteFree(pCol->zName);
    sqlite3ExprDelete(pCol->pDflt);
    sqliteFree(pCol->zType);
  }
  sqliteFree(pTable->aCol);
  pTable->aCol = 0;
  pTable->nCol = 0;
}

/*
** Remove the memory data structures associated with the given
** Table.  No changes are made to disk by this routine.
**
** This routine just deletes the data structure.  It does not unlink
** the table data structure from the hash table.  Nor does it remove
** foreign keys from the sqlite.aFKey hash table.  But it does destroy
** memory structures of the indices and foreign keys associated with 
** the table.
**
** Indices associated with the table are unlinked from the "db"
** data structure if db!=NULL.  If db==NULL, indices attached to
** the table are deleted, but it is assumed they have already been
** unlinked.
*/
void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
  Index *pIndex, *pNext;
  FKey *pFKey, *pNextFKey;

  if( pTable==0 ) return;

  /* Delete all indices associated with this table
  */
  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
    pNext = pIndex->pNext;
    assert( pIndex->iDb==pTable->iDb || (pTable->iDb==0 && pIndex->iDb==1) );
    sqliteDeleteIndex(db, pIndex);
  }

#ifndef SQLITE_OMIT_FOREIGN_KEY
  /* Delete all foreign keys associated with this table.  The keys
  ** should have already been unlinked from the db->aFKey hash table 
  */
  for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
    pNextFKey = pFKey->pNextFrom;
    assert( pTable->iDb<db->nDb );
    assert( sqlite3HashFind(&db->aDb[pTable->iDb].aFKey,
                           pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
    sqliteFree(pFKey);
  }
#endif

  /* Delete the Table structure itself.
  */
  sqliteResetColumnNames(pTable);
  sqliteFree(pTable->zName);
  sqliteFree(pTable->zColAff);
  sqlite3SelectDelete(pTable->pSelect);
  sqliteFree(pTable);
}

/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
*/
void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
  Table *p;
  FKey *pF1, *pF2;
  Db *pDb;

  assert( db!=0 );
  assert( iDb>=0 && iDb<db->nDb );
  assert( zTabName && zTabName[0] );
  pDb = &db->aDb[iDb];
  p = sqlite3HashInsert(&pDb->tblHash, zTabName, strlen(zTabName)+1, 0);
  if( p ){
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
      int nTo = strlen(pF1->zTo) + 1;
      pF2 = sqlite3HashFind(&pDb->aFKey, pF1->zTo, nTo);
      if( pF2==pF1 ){
        sqlite3HashInsert(&pDb->aFKey, pF1->zTo, nTo, pF1->pNextTo);
      }else{
        while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
        if( pF2 ){
          pF2->pNextTo = pF1->pNextTo;
        }
      }
    }
#endif
    sqlite3DeleteTable(db, p);
  }
  db->flags |= SQLITE_InternChanges;
}

/*
** Given a token, return a string that consists of the text of that
** token with any quotations removed.  Space to hold the returned string
** is obtained from sqliteMalloc() and must be freed by the calling
** function.
**
** Tokens are really just pointers into the original SQL text and so
** are not \000 terminated and are not persistent.  The returned string
** is \000 terminated and is persistent.
*/
char *sqlite3NameFromToken(Token *pName){
  char *zName;
  if( pName ){
    zName = sqliteStrNDup(pName->z, pName->n);
    sqlite3Dequote(zName);
  }else{
    zName = 0;
  }
  return zName;
}

/*
** Open the sqlite_master table stored in database number iDb for
** writing. The table is opened using cursor 0.
*/
void sqlite3OpenMasterTable(Vdbe *v, int iDb){
  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
}

/*
** The token *pName contains the name of a database (either "main" or
** "temp" or the name of an attached db). This routine returns the
** index of the named database in db->aDb[], or -1 if the named db 
** does not exist.
*/
static int findDb(sqlite3 *db, Token *pName){
  int i = -1;    /* Database number */
  int n;         /* Number of characters in the name */
  Db *pDb;       /* A database whose name space is being searched */
  char *zName;   /* Name we are searching for */

  zName = sqlite3NameFromToken(pName);
  if( zName ){
    n = strlen(zName);
    for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
      if( n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){
        break;
      }
    }
    sqliteFree(zName);
  }
  return i;
}

/* The table or view or trigger name is passed to this routine via tokens
** pName1 and pName2. If the table name was fully qualified, for example:
**
** CREATE TABLE xxx.yyy (...);
** 
** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
** the table name is not fully qualified, i.e.:
**
** CREATE TABLE yyy(...);
**
** Then pName1 is set to "yyy" and pName2 is "".
**
** This routine sets the *ppUnqual pointer to point at the token (pName1 or
** pName2) that stores the unqualified table name.  The index of the
** database "xxx" is returned.
*/
int sqlite3TwoPartName(
  Parse *pParse,      /* Parsing and code generating context */
  Token *pName1,      /* The "xxx" in the name "xxx.yyy" or "xxx" */
  Token *pName2,      /* The "yyy" in the name "xxx.yyy" */
  Token **pUnqual     /* Write the unqualified object name here */
){
  int iDb;                    /* Database holding the object */
  sqlite3 *db = pParse->db;

  if( pName2 && pName2->n>0 ){
    assert( !db->init.busy );
    *pUnqual = pName2;
    iDb = findDb(db, pName1);
    if( iDb<0 ){
      sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
      pParse->nErr++;
      return -1;
    }
  }else{
    assert( db->init.iDb==0 || db->init.busy );
    iDb = db->init.iDb;
    *pUnqual = pName1;
  }
  return iDb;
}

/*
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
** trigger). All names are legal except those that begin with the string
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
*/
int sqlite3CheckObjectName(Parse *pParse, const char *zName){
  if( !pParse->db->init.busy && pParse->nested==0 
          && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
    sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}

/*
** Begin constructing a new table representation in memory.  This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement.  In particular, this routine is called
** after seeing tokens "CREATE" and "TABLE" and the table name.  The
** pStart token is the CREATE and pName is the table name.  The isTemp
** flag is true if the table should be stored in the auxiliary database
** file instead of in the main database file.  This is normally the case
** when the "TEMP" or "TEMPORARY" keyword occurs in between
** CREATE and TABLE.
**
** The new table record is initialized and put in pParse->pNewTable.
** As more of the CREATE TABLE statement is parsed, additional action
** routines will be called to add more information to this record.
** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine
** is called to complete the construction of the new table record.
*/
void sqlite3StartTable(
  Parse *pParse,   /* Parser context */
  Token *pStart,   /* The "CREATE" token */
  Token *pName1,   /* First part of the name of the table or view */
  Token *pName2,   /* Second part of the name of the table or view */
  int isTemp,      /* True if this is a TEMP table */
  int isView       /* True if this is a VIEW */
){
  Table *pTable;
  Index *pIdx;
  char *zName = 0; /* The name of the new table */
  sqlite3 *db = pParse->db;
  Vdbe *v;
  int iDb;         /* Database number to create the table in */
  Token *pName;    /* Unqualified name of the table to create */

  /* The table or view name to create is passed to this routine via tokens
  ** pName1 and pName2. If the table name was fully qualified, for example:
  **
  ** CREATE TABLE xxx.yyy (...);
  ** 
  ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
  ** the table name is not fully qualified, i.e.:
  **
  ** CREATE TABLE yyy(...);
  **
  ** Then pName1 is set to "yyy" and pName2 is "".
  **
  ** The call below sets the pName pointer to point at the token (pName1 or
  ** pName2) that stores the unqualified table name. The variable iDb is
  ** set to the index of the database that the table or view is to be
  ** created in.
  */
  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
  if( iDb<0 ) return;
  if( isTemp && iDb>1 ){
    /* If creating a temp table, the name may not be qualified */
    sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
    return;
  }
  if( isTemp ) iDb = 1;

  pParse->sNameToken = *pName;
  zName = sqlite3NameFromToken(pName);
  if( zName==0 ) return;
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto begin_table_error;
  }
  if( db->init.iDb==1 ) isTemp = 1;
#ifndef SQLITE_OMIT_AUTHORIZATION
  assert( (isTemp & 1)==isTemp );
  {
    int code;
    char *zDb = db->aDb[iDb].zName;
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
      goto begin_table_error;
    }
    if( isView ){
      if( isTemp ){
        code = SQLITE_CREATE_TEMP_VIEW;
      }else{
        code = SQLITE_CREATE_VIEW;
      }
    }else{
      if( isTemp ){
        code = SQLITE_CREATE_TEMP_TABLE;
      }else{
        code = SQLITE_CREATE_TABLE;
      }
    }
    if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
      goto begin_table_error;
    }
  }
#endif

  /* Make sure the new table name does not collide with an existing
  ** index or table name in the same database.  Issue an error message if
  ** it does.
  */
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto begin_table_error;
  }
  pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
  if( pTable ){
    sqlite3ErrorMsg(pParse, "table %T already exists", pName);
    goto begin_table_error;
  }
  if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 && 
      ( iDb==0 || !db->init.busy) ){
    sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
    goto begin_table_error;
  }
  pTable = sqliteMalloc( sizeof(Table) );
  if( pTable==0 ){
    pParse->rc = SQLITE_NOMEM;
    pParse->nErr++;
    goto begin_table_error;
  }
  pTable->zName = zName;
  pTable->nCol = 0;
  pTable->aCol = 0;
  pTable->iPKey = -1;
  pTable->pIndex = 0;
  pTable->iDb = iDb;
  if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable);
  pParse->pNewTable = pTable;

  /* If this is the magic sqlite_sequence table used by autoincrement,
  ** then record a pointer to this table in the main database structure
  ** so that INSERT can find the table easily.
  */
#ifndef SQLITE_OMIT_AUTOINCREMENT
  if( strcmp(zName, "sqlite_sequence")==0 ){
    db->aDb[iDb].pSeqTab = pTable;
  }
#endif

  /* Begin generating the code that will insert the table record into
  ** the SQLITE_MASTER table.  Note in particular that we must go ahead
  ** and allocate the record number for the table entry now.  Before any
  ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
  ** indices to be created and the table record must come before the 
  ** indices.  Hence, the record number for the table must be allocated
  ** now.
  */
  if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
    int lbl;
    sqlite3BeginWriteOperation(pParse, 0, iDb);

    /* If the file format and encoding in the database have not been set, 
    ** set them now.
    */
    sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);   /* file_format */
    lbl = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_If, 0, lbl);
    sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
    sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
    sqlite3VdbeResolveLabel(v, lbl);

    /* This just creates a place-holder record in the sqlite_master table.
    ** The record created does not contain anything yet.  It will be replaced
    ** by the real entry in code generated at sqlite3EndTable().
    **
    ** The rowid for the new entry is left on the top of the stack.
    ** The rowid value is needed by the code that sqlite3EndTable will
    ** generate.
    */
#ifndef SQLITE_OMIT_VIEW
    if( isView ){
      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
    }else
#endif
    {
      sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
    }
    sqlite3OpenMasterTable(v, iDb);
    sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
  }

  /* Normal (non-error) return. */
  return;

  /* If an error occurs, we jump here */
begin_table_error:
  sqliteFree(zName);
  return;
}

/*
** This macro is used to compare two strings in a case-insensitive manner.
** It is slightly faster than calling sqlite3StrICmp() directly, but
** produces larger code.
**
** WARNING: This macro is not compatible with the strcmp() family. It
** returns true if the two strings are equal, otherwise false.
*/
#define STRICMP(x, y) (\
sqlite3UpperToLower[*(unsigned char *)(x)]==   \
sqlite3UpperToLower[*(unsigned char *)(y)]     \
&& sqlite3StrICmp((x)+1,(y)+1)==0 )

/*
** Add a new column to the table currently being constructed.
**
** The parser calls this routine once for each column declaration
** in a CREATE TABLE statement.  sqlite3StartTable() gets called
** first to get things going.  Then this routine is called for each
** column.
*/
void sqlite3AddColumn(Parse *pParse, Token *pName){
  Table *p;
  int i;
  char *z;
  Column *pCol;
  if( (p = pParse->pNewTable)==0 ) return;
  z = sqlite3NameFromToken(pName);
  if( z==0 ) return;
  for(i=0; i<p->nCol; i++){
    if( STRICMP(z, p->aCol[i].zName) ){
      sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
      sqliteFree(z);
      return;
    }
  }
  if( (p->nCol & 0x7)==0 ){
    Column *aNew;
    aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
    if( aNew==0 ) return;
    p->aCol = aNew;
  }
  pCol = &p->aCol[p->nCol];
  memset(pCol, 0, sizeof(p->aCol[0]));
  pCol->zName = z;
 
  /* If there is no type specified, columns have the default affinity
  ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will
  ** be called next to set pCol->affinity correctly.
  */
  pCol->affinity = SQLITE_AFF_NONE;
  pCol->pColl = pParse->db->pDfltColl;
  p->nCol++;
}

/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.  A "NOT NULL" constraint has
** been seen on a column.  This routine sets the notNull flag on
** the column currently under construction.
*/
void sqlite3AddNotNull(Parse *pParse, int onError){
  Table *p;
  int i;
  if( (p = pParse->pNewTable)==0 ) return;
  i = p->nCol-1;
  if( i>=0 ) p->aCol[i].notNull = onError;
}

/*
** Scan the column type name zType (length nType) and return the
** associated affinity type.
**
** This routine does a case-independent search of zType for the 
** substrings in the following table. If one of the substrings is
** found, the corresponding affinity is returned. If zType contains
** more than one of the substrings, entries toward the top of 
** the table take priority. For example, if zType is 'BLOBINT', 
** SQLITE_AFF_INTEGER is returned.
**
** Substring     | Affinity
** --------------------------------
** 'INT'         | SQLITE_AFF_INTEGER
** 'CHAR'        | SQLITE_AFF_TEXT
** 'CLOB'        | SQLITE_AFF_TEXT
** 'TEXT'        | SQLITE_AFF_TEXT
** 'BLOB'        | SQLITE_AFF_NONE
**
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
static char sqlite3AffinityType(const char *zType, int nType){
  u32 h = 0;
  char aff = SQLITE_AFF_NUMERIC;
  const unsigned char *zIn = zType;
  const unsigned char *zEnd = (zIn+nType);

  while( zIn!=zEnd ){
    h = (h<<8) + sqlite3UpperToLower[*zIn];
    zIn++;
    if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){             /* CHAR */
      aff = SQLITE_AFF_TEXT; 
    }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){       /* CLOB */
      aff = SQLITE_AFF_TEXT;
    }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){       /* TEXT */
      aff = SQLITE_AFF_TEXT;
    }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b')          /* BLOB */
        && aff==SQLITE_AFF_NUMERIC ){
      aff = SQLITE_AFF_NONE;
    }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){    /* INT */
      aff = SQLITE_AFF_INTEGER; 
      break;
    }
  }

  return aff;
}

/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.  The pFirst token is the first
** token in the sequence of tokens that describe the type of the
** column currently under construction.   pLast is the last token
** in the sequence.  Use this information to construct a string
** that contains the typename of the column and store that string
** in zType.
*/ 
void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
  Table *p;
  int i, j;
  int n;
  char *z;
  const unsigned char *zIn;

  Column *pCol;
  if( (p = pParse->pNewTable)==0 ) return;
  i = p->nCol-1;
  if( i<0 ) return;
  pCol = &p->aCol[i];
  zIn = pFirst->z;
  n = pLast->n + (pLast->z - zIn);
  assert( pCol->zType==0 );
  z = pCol->zType = sqliteMallocRaw(n+1);
  if( z==0 ) return;
  for(i=j=0; i<n; i++){
    int c = zIn[i];
    if( isspace(c) ) continue;
    z[j++] = c;
  }
  z[j] = 0;
  pCol->affinity = sqlite3AffinityType(z, n);
}

/*
** The expression is the default value for the most recently added column
** of the table currently under construction.
**
** Default value expressions must be constant.  Raise an exception if this
** is not the case.
**
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
  Table *p;
  Column *pCol;
  if( (p = pParse->pNewTable)==0 ) return;
  pCol = &(p->aCol[p->nCol-1]);
  if( !sqlite3ExprIsConstant(pExpr) ){
    sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
        pCol->zName);
  }else{
    sqlite3ExprDelete(pCol->pDflt);
    pCol->pDflt = sqlite3ExprDup(pExpr);
  }
  sqlite3ExprDelete(pExpr);
}

/*
** Designate the PRIMARY KEY for the table.  pList is a list of names 
** of columns that form the primary key.  If pList is NULL, then the
** most recently added column of the table is the primary key.
**
** A table can have at most one primary key.  If the table already has
** a primary key (and this is the second primary key) then create an
** error.
**
** If the PRIMARY KEY is on a single column whose datatype is INTEGER,
** then we will try to use that column as the rowid.  Set the Table.iPKey
** field of the table under construction to be the index of the
** INTEGER PRIMARY KEY column.  Table.iPKey is set to -1 if there is
** no INTEGER PRIMARY KEY.
**
** If the key is not an INTEGER PRIMARY KEY, then create a unique
** index for the key.  No index is created for INTEGER PRIMARY KEYs.
*/
void sqlite3AddPrimaryKey(
  Parse *pParse,    /* Parsing context */
  ExprList *pList,  /* List of field names to be indexed */
  int onError,      /* What to do with a uniqueness conflict */
  int autoInc       /* True if the AUTOINCREMENT keyword is present */
){
  Table *pTab = pParse->pNewTable;
  char *zType = 0;
  int iCol = -1, i;
  if( pTab==0 ) goto primary_key_exit;
  if( pTab->hasPrimKey ){
    sqlite3ErrorMsg(pParse, 
      "table \"%s\" has more than one primary key", pTab->zName);
    goto primary_key_exit;
  }
  pTab->hasPrimKey = 1;
  if( pList==0 ){
    iCol = pTab->nCol - 1;
    pTab->aCol[iCol].isPrimKey = 1;
  }else{
    for(i=0; i<pList->nExpr; i++){
      for(iCol=0; iCol<pTab->nCol; iCol++){
        if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
          break;
        }
      }
      if( iCol<pTab->nCol ) pTab->aCol[iCol].isPrimKey = 1;
    }
    if( pList->nExpr>1 ) iCol = -1;
  }
  if( iCol>=0 && iCol<pTab->nCol ){
    zType = pTab->aCol[iCol].zType;
  }
  if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){
    pTab->iPKey = iCol;
    pTab->keyConf = onError;
    pTab->autoInc = autoInc;
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{
    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0);
    pList = 0;
  }

primary_key_exit:
  sqlite3ExprListDelete(pList);
  return;
}

/*
** Set the collation function of the most recently parsed table column
** to the CollSeq given.
*/
void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){
  Table *p;
  Index *pIdx;
  CollSeq *pColl;
  int i;

  if( (p = pParse->pNewTable)==0 ) return;
  i = p->nCol-1;

  pColl = sqlite3LocateCollSeq(pParse, zType, nType);
  p->aCol[i].pColl = pColl;

  /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
  ** then an index may have been created on this column before the
  ** collation type was added. Correct this if it is the case.
  */
  for(pIdx = p->pIndex; pIdx; pIdx=pIdx->pNext){
    assert( pIdx->nColumn==1 );
    if( pIdx->aiColumn[0]==i ) pIdx->keyInfo.aColl[0] = pColl;
  }
}

/*
** Locate and return an entry from the db.aCollSeq hash table. If the entry
** specified by zName and nName is not found and parameter 'create' is
** true, then create a new entry. Otherwise return NULL.
**
** Each pointer stored in the sqlite3.aCollSeq hash table contains an
** array of three CollSeq structures. The first is the collation sequence
** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
**
** Stored immediately after the three collation sequences is a copy of
** the collation sequence name. A pointer to this string is stored in
** each collation sequence structure.
*/
static CollSeq * findCollSeqEntry(
  sqlite3 *db,
  const char *zName,
  int nName,
  int create
){
  CollSeq *pColl;
  if( nName<0 ) nName = strlen(zName);
  pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);

  if( 0==pColl && create ){
    pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
    if( pColl ){
      pColl[0].zName = (char*)&pColl[3];
      pColl[0].enc = SQLITE_UTF8;
      pColl[1].zName = (char*)&pColl[3];
      pColl[1].enc = SQLITE_UTF16LE;
      pColl[2].zName = (char*)&pColl[3];
      pColl[2].enc = SQLITE_UTF16BE;
      memcpy(pColl[0].zName, zName, nName);
      pColl[0].zName[nName] = 0;
      sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
    }
  }
  return pColl;
}

/*
** Parameter zName points to a UTF-8 encoded string nName bytes long.
** Return the CollSeq* pointer for the collation sequence named zName
** for the encoding 'enc' from the database 'db'.
**
** If the entry specified is not found and 'create' is true, then create a
** new entry.  Otherwise return NULL.
*/
CollSeq *sqlite3FindCollSeq(
  sqlite3 *db,
  u8 enc,
  const char *zName,
  int nName,
  int create
){
  CollSeq *pColl = findCollSeqEntry(db, zName, nName, create);
  assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
  assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
  if( pColl ) pColl += enc-1;
  return pColl;
}

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
** If the collation sequence
*/
static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
  assert( !db->xCollNeeded || !db->xCollNeeded16 );
  if( nName<0 ) nName = strlen(zName);
  if( db->xCollNeeded ){
    char *zExternal = sqliteStrNDup(zName, nName);
    if( !zExternal ) return;
    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
    sqliteFree(zExternal);
  }
#ifndef SQLITE_OMIT_UTF16
  if( db->xCollNeeded16 ){
    char const *zExternal;
    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
    if( !zExternal ) return;
    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
  }
#endif
}

/*
** This routine is called if the collation factory fails to deliver a
** collation function in the best encoding but there may be other versions
** of this collation function (for other text encodings) available. Use one
** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
** possible.
*/
static int synthCollSeq(Parse *pParse, CollSeq *pColl){
  CollSeq *pColl2;
  char *z = pColl->zName;
  int n = strlen(z);
  sqlite3 *db = pParse->db;
  int i;
  static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
  for(i=0; i<3; i++){
    pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
    if( pColl2->xCmp!=0 ){
      memcpy(pColl, pColl2, sizeof(CollSeq));
      return SQLITE_OK;
    }
  }
  if( pParse->nErr==0 ){
    sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", n, z);
  }
  pParse->nErr++;
  return SQLITE_ERROR;
}

/*
** This routine is called on a collation sequence before it is used to
** check that it is defined. An undefined collation sequence exists when
** a database is loaded that contains references to collation sequences
** that have not been defined by sqlite3_create_collation() etc.
**
** If required, this routine calls the 'collation needed' callback to
** request a definition of the collating sequence. If this doesn't work, 
** an equivalent collating sequence that uses a text encoding different
** from the main database is substituted, if one is available.
*/
int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
  if( pColl && !pColl->xCmp ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName));
    if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){
      return SQLITE_ERROR;
    }
  }
  return SQLITE_OK;
}

/*
** Call sqlite3CheckCollSeq() for all collating sequences in an index,
** in order to verify that all the necessary collating sequences are
** loaded.
*/
int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){
  if( pIdx ){
    int i;
    for(i=0; i<pIdx->nColumn; i++){
      if( sqlite3CheckCollSeq(pParse, pIdx->keyInfo.aColl[i]) ){
        return SQLITE_ERROR;
      }
    }
  }
  return SQLITE_OK;
}

/*
** This function returns the collation sequence for database native text
** encoding identified by the string zName, length nName.
**
** If the requested collation sequence is not available, or not available
** in the database native encoding, the collation factory is invoked to
** request it. If the collation factory does not supply such a sequence,
** and the sequence is available in another text encoding, then that is
** returned instead.
**
** If no versions of the requested collations sequence are available, or
** another error occurs, NULL is returned and an error message written into
** pParse.
*/
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
  u8 enc = pParse->db->enc;
  u8 initbusy = pParse->db->init.busy;
  CollSeq *pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, initbusy);
  if( nName<0 ) nName = strlen(zName);
  if( !initbusy && (!pColl || !pColl->xCmp) ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(pParse->db, zName, nName);
    pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0);
    if( pColl && !pColl->xCmp ){
      /* There may be a version of the collation sequence that requires
      ** translation between encodings. Search for it with synthCollSeq().
      */
      if( synthCollSeq(pParse, pColl) ){
        return 0;
      }
    }
  }

  /* If nothing has been found, write the error message into pParse */
  if( !initbusy && (!pColl || !pColl->xCmp) ){
    if( pParse->nErr==0 ){
      sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
    }
    pColl = 0;
  }
  return pColl;
}


/*
** Generate code that will increment the schema cookie.
**
** The schema cookie is used to determine when the schema for the
** database changes.  After each schema change, the cookie value
** changes.  When a process first reads the schema it records the
** cookie.  Thereafter, whenever it goes to access the database,
** it checks the cookie to make sure the schema has not changed
** since it was last read.
**
** This plan is not completely bullet-proof.  It is possible for
** the schema to change multiple times and for the cookie to be
** set back to prior value.  But schema changes are infrequent
** and the probability of hitting the same cookie value is only
** 1 chance in 2^32.  So we're safe enough.
*/
void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){
  sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].schema_cookie+1, 0);
  sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
}

/*
** Measure the number of characters needed to output the given
** identifier.  The number returned includes any quotes used
** but does not include the null terminator.
**
** The estimate is conservative.  It might be larger that what is
** really needed.
*/
static int identLength(const char *z){
  int n;
  for(n=0; *z; n++, z++){
    if( *z=='"' ){ n++; }
  }
  return n + 2;
}

/*
** Write an identifier onto the end of the given string.  Add
** quote characters as needed.
*/
static void identPut(char *z, int *pIdx, char *zSignedIdent){
  unsigned char *zIdent = (unsigned char*)zSignedIdent;
  int i, j, needQuote;
  i = *pIdx;
  for(j=0; zIdent[j]; j++){
    if( !isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
  }
  needQuote =  zIdent[j]!=0 || isdigit(zIdent[0])
                  || sqlite3KeywordCode(zIdent, j)!=TK_ID;
  if( needQuote ) z[i++] = '"';
  for(j=0; zIdent[j]; j++){
    z[i++] = zIdent[j];
    if( zIdent[j]=='"' ) z[i++] = '"';
  }
  if( needQuote ) z[i++] = '"';
  z[i] = 0;
  *pIdx = i;
}

/*
** Generate a CREATE TABLE statement appropriate for the given
** table.  Memory to hold the text of the statement is obtained
** from sqliteMalloc() and must be freed by the calling function.
*/
static char *createTableStmt(Table *p){
  int i, k, n;
  char *zStmt;
  char *zSep, *zSep2, *zEnd, *z;
  Column *pCol;
  n = 0;
  for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
    n += identLength(pCol->zName);
    z = pCol->zType;
    if( z ){
      n += (strlen(z) + 1);
    }
  }
  n += identLength(p->zName);
  if( n<50 ){
    zSep = "";
    zSep2 = ",";
    zEnd = ")";
  }else{
    zSep = "\n  ";
    zSep2 = ",\n  ";
    zEnd = "\n)";
  }
  n += 35 + 6*p->nCol;
  zStmt = sqliteMallocRaw( n );
  if( zStmt==0 ) return 0;
  strcpy(zStmt, p->iDb==1 ? "CREATE TEMP TABLE " : "CREATE TABLE ");
  k = strlen(zStmt);
  identPut(zStmt, &k, p->zName);
  zStmt[k++] = '(';
  for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
    strcpy(&zStmt[k], zSep);
    k += strlen(&zStmt[k]);
    zSep = zSep2;
    identPut(zStmt, &k, pCol->zName);
    if( (z = pCol->zType)!=0 ){
      zStmt[k++] = ' ';
      strcpy(&zStmt[k], z);
      k += strlen(z);
    }
  }
  strcpy(&zStmt[k], zEnd);
  return zStmt;
}

/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have
** occurred.
**
** An entry for the table is made in the master table on disk, unless
** this is a temporary table or db->init.busy==1.  When db->init.busy==1
** it means we are reading the sqlite_master table because we just
** connected to the database or because the sqlite_master table has
** recently changes, so the entry for this table already exists in
** the sqlite_master table.  We do not want to create it again.
**
** If the pSelect argument is not NULL, it means that this routine
** was called to create a table generated from a 
** "CREATE TABLE ... AS SELECT ..." statement.  The column names of
** the new table will match the result set of the SELECT.
*/
void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
  Table *p;
  sqlite3 *db = pParse->db;

  if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite3_malloc_failed ) return;
  p = pParse->pNewTable;
  if( p==0 ) return;

  assert( !db->init.busy || !pSelect );

  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number
  ** should have been put there by the sqliteOpenCb routine.)
  */
  if( db->init.busy ){
    p->tnum = db->init.newTnum;
  }

  /* If not initializing, then create a record for the new table
  ** in the SQLITE_MASTER table of the database.  The record number
  ** for the new table entry should already be on the stack.
  **
  ** If this is a TEMPORARY table, write the entry into the auxiliary
  ** file instead of into the main database file.
  */
  if( !db->init.busy ){
    int n;
    Vdbe *v;
    char *zType;    /* "view" or "table" */
    char *zType2;   /* "VIEW" or "TABLE" */
    char *zStmt;    /* Text of the CREATE TABLE or CREATE VIEW statement */

    v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;

    sqlite3VdbeAddOp(v, OP_Close, 0, 0);

    /* Create the rootpage for the new table and push it onto the stack.
    ** A view has no rootpage, so just push a zero onto the stack for
    ** views.  Initialize zType at the same time.
    */
    if( p->pSelect==0 ){
      /* A regular table */
      /* sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); */
      zType = "table";
      zType2 = "TABLE";
#ifndef SQLITE_OMIT_VIEW
    }else{
      /* A view */
    /*  sqlite3VdbeAddOp(v, OP_Integer, 0, 0); */
      zType = "view";
      zType2 = "VIEW";
#endif
    }

    /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
    ** statement to populate the new table. The root-page number for the
    ** new table is on the top of the vdbe stack.
    **
    ** Once the SELECT has been coded by sqlite3Select(), it is in a
    ** suitable state to query for the column names and types to be used
    ** by the new table.
    */
    if( pSelect ){
      Table *pSelTab;
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      sqlite3VdbeAddOp(v, OP_Integer, p->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0);
      pParse->nTab = 2;
      sqlite3Select(pParse, pSelect, SRT_Table, 1, 0, 0, 0, 0);
      sqlite3VdbeAddOp(v, OP_Close, 1, 0);
      if( pParse->nErr==0 ){
        pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
        if( pSelTab==0 ) return;
        assert( p->aCol==0 );
        p->nCol = pSelTab->nCol;
        p->aCol = pSelTab->aCol;
        pSelTab->nCol = 0;
        pSelTab->aCol = 0;
        sqlite3DeleteTable(0, pSelTab);
      }
    }

    /* Compute the complete text of the CREATE statement */
    if( pSelect ){
      zStmt = createTableStmt(p);
    }else{
      n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1;
      zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z);
    }

    /* A slot for the record has already been allocated in the 
    ** SQLITE_MASTER table.  We just need to update that slot with all
    ** the information we've collected.  The rowid for the preallocated
    ** slot is the 2nd item on the stack.  The top of the stack is the
    ** root page for the new table (or a 0 if this is a view).
    */
    sqlite3NestedParse(pParse,
      "UPDATE %Q.%s "
         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q "
       "WHERE rowid=#1",
      db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb),
      zType,
      p->zName,
      p->zName,
      zStmt
    );
    sqliteFree(zStmt);
    sqlite3ChangeCookie(db, v, p->iDb);

#ifndef SQLITE_OMIT_AUTOINCREMENT
    /* Check to see if we need to create an sqlite_sequence table for
    ** keeping track of autoincrement keys.
    */
    if( p->autoInc ){
      Db *pDb = &db->aDb[p->iDb];
      if( pDb->pSeqTab==0 ){
        sqlite3NestedParse(pParse,
          "CREATE TABLE %Q.sqlite_sequence(name,seq)",
          pDb->zName
        );
      }
    }
#endif

    /* Reparse everything to update our internal data structures */
    sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
        sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
  }


  /* Add the table to the in-memory representation of the database.
  */
  if( db->init.busy && pParse->nErr==0 ){
    Table *pOld;
    FKey *pFKey; 
    Db *pDb = &db->aDb[p->iDb];
    pOld = sqlite3HashInsert(&pDb->tblHash, p->zName, strlen(p->zName)+1, p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      return;
    }
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
      int nTo = strlen(pFKey->zTo) + 1;
      pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo);
      sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey);
    }
#endif
    pParse->pNewTable = 0;
    db->nTable++;
    db->flags |= SQLITE_InternChanges;
  }
}

#ifndef SQLITE_OMIT_VIEW
/*
** The parser calls this routine in order to create a new VIEW
*/
void sqlite3CreateView(
  Parse *pParse,     /* The parsing context */
  Token *pBegin,     /* The CREATE token that begins the statement */
  Token *pName1,     /* The token that holds the name of the view */
  Token *pName2,     /* The token that holds the name of the view */
  Select *pSelect,   /* A SELECT statement that will become the new view */
  int isTemp         /* TRUE for a TEMPORARY view */
){
  Table *p;
  int n;
  const unsigned char *z;
  Token sEnd;
  DbFixer sFix;
  Token *pName;

  sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1);
  p = pParse->pNewTable;
  if( p==0 || pParse->nErr ){
    sqlite3SelectDelete(pSelect);
    return;
  }
  sqlite3TwoPartName(pParse, pName1, pName2, &pName);
  if( sqlite3FixInit(&sFix, pParse, p->iDb, "view", pName)
    && sqlite3FixSelect(&sFix, pSelect)
  ){
    sqlite3SelectDelete(pSelect);
    return;
  }

  /* Make a copy of the entire SELECT statement that defines the view.
  ** This will force all the Expr.token.z values to be dynamically
  ** allocated rather than point to the input string - which means that
  ** they will persist after the current sqlite3_exec() call returns.
  */
  p->pSelect = sqlite3SelectDup(pSelect);
  sqlite3SelectDelete(pSelect);
  if( !pParse->db->init.busy ){
    sqlite3ViewGetColumnNames(pParse, p);
  }

  /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
  ** the end.
  */
  sEnd = pParse->sLastToken;
  if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
    sEnd.z += sEnd.n;
  }
  sEnd.n = 0;
  n = sEnd.z - pBegin->z;
  z = (const unsigned char*)pBegin->z;
  while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
  sEnd.z = &z[n-1];
  sEnd.n = 1;

  /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
  sqlite3EndTable(pParse, &sEnd, 0);
  return;
}
#endif /* SQLITE_OMIT_VIEW */

#ifndef SQLITE_OMIT_VIEW
/*
** The Table structure pTable is really a VIEW.  Fill in the names of
** the columns of the view in the pTable structure.  Return the number
** of errors.  If an error is seen leave an error message in pParse->zErrMsg.
*/
int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
  Table *pSelTab;   /* A fake table from which we get the result set */
  Select *pSel;     /* Copy of the SELECT that implements the view */
  int nErr = 0;     /* Number of errors encountered */
  int n;            /* Temporarily holds the number of cursors assigned */

  assert( pTable );

  /* A positive nCol means the columns names for this view are
  ** already known.
  */
  if( pTable->nCol>0 ) return 0;

  /* A negative nCol is a special marker meaning that we are currently
  ** trying to compute the column names.  If we enter this routine with
  ** a negative nCol, it means two or more views form a loop, like this:
  **
  **     CREATE VIEW one AS SELECT * FROM two;
  **     CREATE VIEW two AS SELECT * FROM one;
  **
  ** Actually, this error is caught previously and so the following test
  ** should always fail.  But we will leave it in place just to be safe.
  */
  if( pTable->nCol<0 ){
    sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
    return 1;
  }

  /* If we get this far, it means we need to compute the table names.
  ** Note that the call to sqlite3ResultSetOfSelect() will expand any
  ** "*" elements in the results set of the view and will assign cursors
  ** to the elements of the FROM clause.  But we do not want these changes
  ** to be permanent.  So the computation is done on a copy of the SELECT
  ** statement that defines the view.
  */
  assert( pTable->pSelect );
  pSel = sqlite3SelectDup(pTable->pSelect);
  n = pParse->nTab;
  sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
  pTable->nCol = -1;
  pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);
  pParse->nTab = n;
  if( pSelTab ){
    assert( pTable->aCol==0 );
    pTable->nCol = pSelTab->nCol;
    pTable->aCol = pSelTab->aCol;
    pSelTab->nCol = 0;
    pSelTab->aCol = 0;
    sqlite3DeleteTable(0, pSelTab);
    DbSetProperty(pParse->db, pTable->iDb, DB_UnresetViews);
  }else{
    pTable->nCol = 0;
    nErr++;
  }
  sqlite3SelectDelete(pSel);
  return nErr;  
}
#endif /* SQLITE_OMIT_VIEW */

#ifndef SQLITE_OMIT_VIEW
/*
** Clear the column names from every VIEW in database idx.
*/
static void sqliteViewResetAll(sqlite3 *db, int idx){
  HashElem *i;
  if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
  for(i=sqliteHashFirst(&db->aDb[idx].tblHash); i; i=sqliteHashNext(i)){
    Table *pTab = sqliteHashData(i);
    if( pTab->pSelect ){
      sqliteResetColumnNames(pTab);
    }
  }
  DbClearProperty(db, idx, DB_UnresetViews);
}
#else
# define sqliteViewResetAll(A,B)
#endif /* SQLITE_OMIT_VIEW */

/*
** This function is called by the VDBE to adjust the internal schema
** used by SQLite when the btree layer moves a table root page. The
** root-page of a table or index in database iDb has changed from iFrom
** to iTo.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
  HashElem *pElem;
  
  for(pElem=sqliteHashFirst(&pDb->tblHash); pElem; pElem=sqliteHashNext(pElem)){
    Table *pTab = sqliteHashData(pElem);
    if( pTab->tnum==iFrom ){
      pTab->tnum = iTo;
      return;
    }
  }
  for(pElem=sqliteHashFirst(&pDb->idxHash); pElem; pElem=sqliteHashNext(pElem)){
    Index *pIdx = sqliteHashData(pElem);
    if( pIdx->tnum==iFrom ){
      pIdx->tnum = iTo;
      return;
    }
  }
  assert(0);
}
#endif

/*
** Write code to erase the table with root-page iTable from database iDb.
** Also write code to modify the sqlite_master table and internal schema
** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
*/ 
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
  Vdbe *v = sqlite3GetVdbe(pParse);
  sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb);
#ifndef SQLITE_OMIT_AUTOVACUUM
  /* OP_Destroy pushes an integer onto the stack. If this integer
  ** is non-zero, then it is the root page number of a table moved to
  ** location iTable. The following code modifies the sqlite_master table to
  ** reflect this.
  **
  ** The "#0" in the SQL is a special constant that means whatever value
  ** is on the top of the stack.  See sqlite3RegisterExpr().
  */
  sqlite3NestedParse(pParse, 
     "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0",
     pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable);
#endif
}

/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
*/
static void destroyTable(Parse *pParse, Table *pTab){
#ifdef SQLITE_OMIT_AUTOVACUUM
  Index *pIdx;
  destroyRootPage(pParse, pTab->tnum, pTab->iDb);
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    destroyRootPage(pParse, pIdx->tnum, pIdx->iDb);
  }
#else
  /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
  ** is not defined), then it is important to call OP_Destroy on the
  ** table and index root-pages in order, starting with the numerically 
  ** largest root-page number. This guarantees that none of the root-pages
  ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the
  ** following were coded:
  **
  ** OP_Destroy 4 0
  ** ...
  ** OP_Destroy 5 0
  **
  ** and root page 5 happened to be the largest root-page number in the
  ** database, then root page 5 would be moved to page 4 by the 
  ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit
  ** a free-list page.
  */
  int iTab = pTab->tnum;
  int iDestroyed = 0;

  while( 1 ){
    Index *pIdx;
    int iLargest = 0;

    if( iDestroyed==0 || iTab<iDestroyed ){
      iLargest = iTab;
    }
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int iIdx = pIdx->tnum;
      assert( pIdx->iDb==pTab->iDb );
      if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
        iLargest = iIdx;
      }
    }
    if( iLargest==0 ) return;
    destroyRootPage(pParse, iLargest, pTab->iDb);
    iDestroyed = iLargest;
  }
#endif
}

/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
  Table *pTab;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  if( pParse->nErr || sqlite3_malloc_failed ) goto exit_drop_table;
  assert( pName->nSrc==1 );
  pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);

  if( pTab==0 ) goto exit_drop_table;
  iDb = pTab->iDb;
  assert( iDb>=0 && iDb<db->nDb );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code;
    const char *zTab = SCHEMA_TABLE(pTab->iDb);
    const char *zDb = db->aDb[pTab->iDb].zName;
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
      goto exit_drop_table;
    }
    if( isView ){
      if( iDb==1 ){
        code = SQLITE_DROP_TEMP_VIEW;
      }else{
        code = SQLITE_DROP_VIEW;
      }
    }else{
      if( iDb==1 ){
        code = SQLITE_DROP_TEMP_TABLE;
      }else{
        code = SQLITE_DROP_TABLE;
      }
    }
    if( sqlite3AuthCheck(pParse, code, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.
  */
  if( isView && pTab->pSelect==0 ){
    sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
    goto exit_drop_table;
  }
  if( !isView && pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
    goto exit_drop_table;
  }
#endif

  /* Generate code to remove the table from the master table
  ** on disk.
  */
  v = sqlite3GetVdbe(pParse);
  if( v ){
    Trigger *pTrigger;
    int iDb = pTab->iDb;
    Db *pDb = &db->aDb[iDb];
    sqlite3BeginWriteOperation(pParse, 0, iDb);

    /* Drop all triggers associated with the table being dropped. Code
    ** is generated to remove entries from sqlite_master and/or
    ** sqlite_temp_master if required.
    */
    pTrigger = pTab->pTrigger;
    while( pTrigger ){
      assert( pTrigger->iDb==iDb || pTrigger->iDb==1 );
      sqlite3DropTriggerPtr(pParse, pTrigger, 1);
      pTrigger = pTrigger->pNext;
    }

#ifndef SQLITE_OMIT_AUTOINCREMENT
    /* Remove any entries of the sqlite_sequence table associated with
    ** the table being dropped. This is done before the table is dropped
    ** at the btree level, in case the sqlite_sequence table needs to
    ** move as a result of the drop (can happen in auto-vacuum mode).
    */
    if( pTab->autoInc ){
      sqlite3NestedParse(pParse,
        "DELETE FROM %s.sqlite_sequence WHERE name=%Q",
        pDb->zName, pTab->zName
      );
    }
#endif

    /* Drop all SQLITE_MASTER table and index entries that refer to the
    ** table. The program name loops through the master table and deletes
    ** every row that refers to a table of the same name as the one being
    ** dropped. Triggers are handled seperately because a trigger can be
    ** created in the temp database that refers to a table in another
    ** database.
    */
    sqlite3NestedParse(pParse, 
        "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
        pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
    if( !isView ){
      destroyTable(pParse, pTab);
    }

    /* Remove the table entry from SQLite's internal schema and modify
    ** the schema cookie.
    */
    sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
    sqlite3ChangeCookie(db, v, iDb);
  }
  sqliteViewResetAll(db, iDb);

exit_drop_table:
  sqlite3SrcListDelete(pName);
}

/*
** This routine is called to create a new foreign key on the table
** currently under construction.  pFromCol determines which columns
** in the current table point to the foreign key.  If pFromCol==0 then
** connect the key to the last column inserted.  pTo is the name of
** the table referred to.  pToCol is a list of tables in the other
** pTo table that the foreign key points to.  flags contains all
** information about the conflict resolution algorithms specified
** in the ON DELETE, ON UPDATE and ON INSERT clauses.
**
** An FKey structure is created and added to the table currently
** under construction in the pParse->pNewTable field.  The new FKey
** is not linked into db->aFKey at this point - that does not happen
** until sqlite3EndTable().
**
** The foreign key is set for IMMEDIATE processing.  A subsequent call
** to sqlite3DeferForeignKey() might change this to DEFERRED.
*/
void sqlite3CreateForeignKey(
  Parse *pParse,       /* Parsing context */
  ExprList *pFromCol,  /* Columns in this table that point to other table */
  Token *pTo,          /* Name of the other table */
  ExprList *pToCol,    /* Columns in the other table */
  int flags            /* Conflict resolution algorithms. */
){
#ifndef SQLITE_OMIT_FOREIGN_KEY
  FKey *pFKey = 0;
  Table *p = pParse->pNewTable;
  int nByte;
  int i;
  int nCol;
  char *z;

  assert( pTo!=0 );
  if( p==0 || pParse->nErr ) goto fk_end;
  if( pFromCol==0 ){
    int iCol = p->nCol-1;
    if( iCol<0 ) goto fk_end;
    if( pToCol && pToCol->nExpr!=1 ){
      sqlite3ErrorMsg(pParse, "foreign key on %s"
         " should reference only one column of table %T",
         p->aCol[iCol].zName, pTo);
      goto fk_end;
    }
    nCol = 1;
  }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){
    sqlite3ErrorMsg(pParse,
        "number of columns in foreign key does not match the number of "
        "columns in the referenced table");
    goto fk_end;
  }else{
    nCol = pFromCol->nExpr;
  }
  nByte = sizeof(*pFKey) + nCol*sizeof(pFKey->aCol[0]) + pTo->n + 1;
  if( pToCol ){
    for(i=0; i<pToCol->nExpr; i++){
      nByte += strlen(pToCol->a[i].zName) + 1;
    }
  }
  pFKey = sqliteMalloc( nByte );
  if( pFKey==0 ) goto fk_end;
  pFKey->pFrom = p;
  pFKey->pNextFrom = p->pFKey;
  z = (char*)&pFKey[1];
  pFKey->aCol = (struct sColMap*)z;
  z += sizeof(struct sColMap)*nCol;
  pFKey->zTo = z;
  memcpy(z, pTo->z, pTo->n);
  z[pTo->n] = 0;
  z += pTo->n+1;
  pFKey->pNextTo = 0;
  pFKey->nCol = nCol;
  if( pFromCol==0 ){
    pFKey->aCol[0].iFrom = p->nCol-1;
  }else{
    for(i=0; i<nCol; i++){
      int j;
      for(j=0; j<p->nCol; j++){
        if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
          pFKey->aCol[i].iFrom = j;
          break;
        }
      }
      if( j>=p->nCol ){
        sqlite3ErrorMsg(pParse, 
          "unknown column \"%s\" in foreign key definition", 
          pFromCol->a[i].zName);
        goto fk_end;
      }
    }
  }
  if( pToCol ){
    for(i=0; i<nCol; i++){
      int n = strlen(pToCol->a[i].zName);
      pFKey->aCol[i].zCol = z;
      memcpy(z, pToCol->a[i].zName, n);
      z[n] = 0;
      z += n+1;
    }
  }
  pFKey->isDeferred = 0;
  pFKey->deleteConf = flags & 0xff;
  pFKey->updateConf = (flags >> 8 ) & 0xff;
  pFKey->insertConf = (flags >> 16 ) & 0xff;

  /* Link the foreign key to the table as the last step.
  */
  p->pFKey = pFKey;
  pFKey = 0;

fk_end:
  sqliteFree(pFKey);
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
  sqlite3ExprListDelete(pFromCol);
  sqlite3ExprListDelete(pToCol);
}

/*
** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED
** clause is seen as part of a foreign key definition.  The isDeferred
** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE.
** The behavior of the most recently created foreign key is adjusted
** accordingly.
*/
void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){
#ifndef SQLITE_OMIT_FOREIGN_KEY
  Table *pTab;
  FKey *pFKey;
  if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
  pFKey->isDeferred = isDeferred;
#endif
}

/*
** Generate code that will erase and refill index *pIdx.  This is
** used to initialize a newly created index or to recompute the
** content of an index in response to a REINDEX command.
**
** if memRootPage is not negative, it means that the index is newly
** created.  The memory cell specified by memRootPage contains the
** root page number of the index.  If memRootPage is negative, then
** the index already exists and must be cleared before being refilled and
** the root page number of the index is taken from pIndex->tnum.
*/
static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
  Table *pTab = pIndex->pTable;  /* The table that is indexed */
  int iTab = pParse->nTab;       /* Btree cursor used for pTab */
  int iIdx = pParse->nTab+1;     /* Btree cursor used for pIndex */
  int addr1;                     /* Address of top of loop */
  int tnum;                      /* Root page of index */
  Vdbe *v;                       /* Generate code into this virtual machine */
  int isUnique;                  /* True for a unique index */

#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
      pParse->db->aDb[pIndex->iDb].zName ) ){
    return;
  }
#endif

  /* Ensure all the required collation sequences are available. This
  ** routine will invoke the collation-needed callback if necessary (and
  ** if one has been registered).
  */
  if( sqlite3CheckIndexCollSeq(pParse, pIndex) ){
    return;
  }

  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;
  if( memRootPage>=0 ){
    sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0);
    tnum = 0;
  }else{
    tnum = pIndex->tnum;
    sqlite3VdbeAddOp(v, OP_Clear, tnum, pIndex->iDb);
  }
  sqlite3VdbeAddOp(v, OP_Integer, pIndex->iDb, 0);
  sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum,
                    (char*)&pIndex->keyInfo, P3_KEYINFO);
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenRead, iTab, pTab->tnum);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pTab->nCol);
  addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
  sqlite3GenerateIndexKey(v, pIndex, iTab);
  isUnique = pIndex->onError!=OE_None;
  sqlite3VdbeAddOp(v, OP_IdxPut, iIdx, isUnique);
  if( isUnique ){
    sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);
  }
  sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1);
  sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v));
  sqlite3VdbeAddOp(v, OP_Close, iTab, 0);
  sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
}

/*
** Create a new index for an SQL table.  pName1.pName2 is the name of the index 
** and pTblList is the name of the table that is to be indexed.  Both will 
** be NULL for a primary key or an index that is created to satisfy a
** UNIQUE constraint.  If pTable and pIndex are NULL, use pParse->pNewTable
** as the table to be indexed.  pParse->pNewTable is a table that is
** currently being constructed by a CREATE TABLE statement.
**
** pList is a list of columns to be indexed.  pList will be NULL if this
** is a primary key or unique-constraint on the most recent column added
** to the table currently under construction.  
*/
void sqlite3CreateIndex(
  Parse *pParse,     /* All information about this parse */
  Token *pName1,     /* First part of index name. May be NULL */
  Token *pName2,     /* Second part of index name. May be NULL */
  SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  ExprList *pList,   /* A list of columns to be indexed */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  Token *pStart,     /* The CREATE token that begins a CREATE TABLE statement */
  Token *pEnd        /* The ")" that closes the CREATE INDEX statement */
){
  Table *pTab = 0;   /* Table to be indexed */
  Index *pIndex = 0; /* The index to be created */
  char *zName = 0;
  int i, j;
  Token nullId;    /* Fake token for an empty ID list */
  DbFixer sFix;    /* For assigning database names to pTable */
  int isTemp;      /* True for a temporary index */
  sqlite3 *db = pParse->db;

  int iDb;          /* Index of the database that is being written */
  Token *pName = 0; /* Unqualified name of the index to create */

  if( pParse->nErr || sqlite3_malloc_failed ) goto exit_create_index;

  /*
  ** Find the table that is to be indexed.  Return early if not found.
  */
  if( pTblName!=0 ){

    /* Use the two-part index name to determine the database 
    ** to search for the table. 'Fix' the table name to this db
    ** before looking up the table.
    */
    assert( pName1 && pName2 );
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ) goto exit_create_index;

    /* If the index name was unqualified, check if the the table
    ** is a temp table. If so, set the database to 1.
    */
    pTab = sqlite3SrcListLookup(pParse, pTblName);
    if( pName2 && pName2->n==0 && pTab && pTab->iDb==1 ){
      iDb = 1;
    }

    if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
        sqlite3FixSrcList(&sFix, pTblName)
    ){
      goto exit_create_index;
    }
    pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName, 
        pTblName->a[0].zDatabase);
    if( !pTab ) goto exit_create_index;
    assert( iDb==pTab->iDb );
  }else{
    assert( pName==0 );
    pTab =  pParse->pNewTable;
    iDb = pTab->iDb;
  }

  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( pTab->readOnly ){
    sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
  }
#endif
  isTemp = pTab->iDb==1;

  /*
  ** Find the name of the index.  Make sure there is not already another
  ** index or table with the same name.  
  **
  ** Exception:  If we are reading the names of permanent indices from the
  ** sqlite_master table (because some other process changed the schema) and
  ** one of the index names collides with the name of a temporary table or
  ** index, then we will continue to process this index.
  **
  ** If pName==0 it means that we are
  ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  ** own name.
  */
  if( pName ){
    zName = sqlite3NameFromToken(pName);
    if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
    if( zName==0 ) goto exit_create_index;
    if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
      goto exit_create_index;
    }
    if( !db->init.busy ){
      Index *pISameName;    /* Another index with the same name */
      Table *pTSameName;    /* A table with same name as the index */
      if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
      if( (pISameName = sqlite3FindIndex(db, zName, db->aDb[iDb].zName))!=0 ){
        sqlite3ErrorMsg(pParse, "index %s already exists", zName);
        goto exit_create_index;
      }
      if( (pTSameName = sqlite3FindTable(db, zName, 0))!=0 ){
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;
      }
    }
  }else{
    char zBuf[30];
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
    sprintf(zBuf,"_%d",n);
    zName = 0;
    sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0);
    if( zName==0 ) goto exit_create_index;
  }

  /* Check for authorization to create an index.
  */
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    const char *zDb = db->aDb[pTab->iDb].zName;
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
      goto exit_create_index;
    }
    i = SQLITE_CREATE_INDEX;
    if( isTemp ) i = SQLITE_CREATE_TEMP_INDEX;
    if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
      goto exit_create_index;
    }
  }
#endif

  /* If pList==0, it means this routine was called to make a primary
  ** key out of the last column added to the table under construction.
  ** So create a fake list to simulate this.
  */
  if( pList==0 ){
    nullId.z = pTab->aCol[pTab->nCol-1].zName;
    nullId.n = strlen(nullId.z);
    pList = sqlite3ExprListAppend(0, 0, &nullId);
    if( pList==0 ) goto exit_create_index;
  }

  /* 
  ** Allocate the index structure. 
  */
  pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +
                        (sizeof(int) + sizeof(CollSeq*))*pList->nExpr );
  if( pIndex==0 ) goto exit_create_index;
  pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
  pIndex->zName = (char*)&pIndex->aiColumn[pList->nExpr];
  strcpy(pIndex->zName, zName);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nExpr;
  pIndex->onError = onError;
  pIndex->autoIndex = pName==0;
  pIndex->iDb = iDb;

  /* Scan the names of the columns of the table to be indexed and
  ** load the column indices into the Index structure.  Report an error
  ** if any column is not found.
  */
  for(i=0; i<pList->nExpr; i++){
    for(j=0; j<pTab->nCol; j++){
      if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
    }
    if( j>=pTab->nCol ){
      sqlite3ErrorMsg(pParse, "table %s has no column named %s",
        pTab->zName, pList->a[i].zName);
      goto exit_create_index;
    }
    pIndex->aiColumn[i] = j;
    if( pList->a[i].pExpr ){
      assert( pList->a[i].pExpr->pColl );
      pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl;
    }else{
      pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl;
    }
    assert( pIndex->keyInfo.aColl[i] );
    if( !db->init.busy && 
        sqlite3CheckCollSeq(pParse, pIndex->keyInfo.aColl[i]) 
    ){
      goto exit_create_index;
    }
  }
  pIndex->keyInfo.nField = pList->nExpr;

  if( pTab==pParse->pNewTable ){
    /* This routine has been called to create an automatic index as a
    ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
    ** a PRIMARY KEY or UNIQUE clause following the column definitions.
    ** i.e. one of:
    **
    ** CREATE TABLE t(x PRIMARY KEY, y);
    ** CREATE TABLE t(x, y, UNIQUE(x, y));
    **
    ** Either way, check to see if the table already has such an index. If
    ** so, don't bother creating this one. This only applies to
    ** automatically created indices. Users can do as they wish with
    ** explicit indices.
    */
    Index *pIdx;
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int k;
      assert( pIdx->onError!=OE_None );
      assert( pIdx->autoIndex );
      assert( pIndex->onError!=OE_None );

      if( pIdx->nColumn!=pIndex->nColumn ) continue;
      for(k=0; k<pIdx->nColumn; k++){
        if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
        if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
      }
      if( k==pIdx->nColumn ){
        if( pIdx->onError!=pIndex->onError ){
          /* This constraint creates the same index as a previous
          ** constraint specified somewhere in the CREATE TABLE statement.
          ** However the ON CONFLICT clauses are different. If both this 
          ** constraint and the previous equivalent constraint have explicit
          ** ON CONFLICT clauses this is an error. Otherwise, use the
          ** explicitly specified behaviour for the index.
          */
          if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
            sqlite3ErrorMsg(pParse, 
                "conflicting ON CONFLICT clauses specified", 0);
          }
          if( pIdx->onError==OE_Default ){
            pIdx->onError = pIndex->onError;
          }
        }
        goto exit_create_index;
      }
    }
  }

  /* Link the new Index structure to its table and to the other
  ** in-memory database structures. 
  */
  if( db->init.busy ){
    Index *p;
    p = sqlite3HashInsert(&db->aDb[pIndex->iDb].idxHash, 
                         pIndex->zName, strlen(pIndex->zName)+1, pIndex);
    if( p ){
      assert( p==pIndex );  /* Malloc must have failed */
      goto exit_create_index;
    }
    db->flags |= SQLITE_InternChanges;
    if( pTblName!=0 ){
      pIndex->tnum = db->init.newTnum;
    }
  }

  /* If the db->init.busy is 0 then create the index on disk.  This
  ** involves writing the index into the master table and filling in the
  ** index with the current table contents.
  **
  ** The db->init.busy is 0 when the user first enters a CREATE INDEX 
  ** command.  db->init.busy is 1 when a database is opened and 
  ** CREATE INDEX statements are read out of the master table.  In
  ** the latter case the index already exists on disk, which is why
  ** we don't want to recreate it.
  **
  ** If pTblName==0 it means this index is generated as a primary key
  ** or UNIQUE constraint of a CREATE TABLE statement.  Since the table
  ** has just been created, it contains no data and the index initialization
  ** step can be skipped.
  */
  else if( db->init.busy==0 ){
    Vdbe *v;
    char *zStmt;
    int iMem = pParse->nMem++;

    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto exit_create_index;

    /* Create the rootpage for the index
    */
    sqlite3BeginWriteOperation(pParse, 1, iDb);
    sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);

    /* Gather the complete text of the CREATE INDEX statement into
    ** the zStmt variable
    */
    if( pStart && pEnd ){
      /* A named index with an explicit CREATE INDEX statement */
      zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s",
        onError==OE_None ? "" : " UNIQUE",
        Addr(pEnd->z) - Addr(pName->z) + 1,
        pName->z);
    }else{
      /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
      /* zStmt = sqlite3MPrintf(""); */
      zStmt = 0;
    }

    /* Add an entry in sqlite_master for this index
    */
    sqlite3NestedParse(pParse, 
        "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);",
        db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
        pIndex->zName,
        pTab->zName,
        zStmt
    );
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
    sqliteFree(zStmt);

    /* Fill the index with data and reparse the schema. Code an OP_Expire
    ** to invalidate all pre-compiled statements.
    */
    if( pTblName ){
      sqlite3RefillIndex(pParse, pIndex, iMem);
      sqlite3ChangeCookie(db, v, iDb);
      sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
         sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC);
      sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
    }
  }

  /* When adding an index to the list of indices for a table, make
  ** sure all indices labeled OE_Replace come after all those labeled
  ** OE_Ignore.  This is necessary for the correct operation of UPDATE
  ** and INSERT.
  */
  if( db->init.busy || pTblName==0 ){
    if( onError!=OE_Replace || pTab->pIndex==0
         || pTab->pIndex->onError==OE_Replace){
      pIndex->pNext = pTab->pIndex;
      pTab->pIndex = pIndex;
    }else{
      Index *pOther = pTab->pIndex;
      while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
        pOther = pOther->pNext;
      }
      pIndex->pNext = pOther->pNext;
      pOther->pNext = pIndex;
    }
    pIndex = 0;
  }

  /* Clean up before exiting */
exit_create_index:
  if( pIndex ){
    freeIndex(pIndex);
  }
  sqlite3ExprListDelete(pList);
  sqlite3SrcListDelete(pTblName);
  sqliteFree(zName);
  return;
}

/*
** This routine will drop an existing named index.  This routine
** implements the DROP INDEX statement.
*/
void sqlite3DropIndex(Parse *pParse, SrcList *pName){
  Index *pIndex;
  Vdbe *v;
  sqlite3 *db = pParse->db;

  if( pParse->nErr || sqlite3_malloc_failed ) return;
  assert( pName->nSrc==1 );
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return;
  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){
    sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
    sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);
    goto exit_drop_index;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_INDEX;
    Table *pTab = pIndex->pTable;
    const char *zDb = db->aDb[pIndex->iDb].zName;
    const char *zTab = SCHEMA_TABLE(pIndex->iDb);
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      goto exit_drop_index;
    }
    if( pIndex->iDb ) code = SQLITE_DROP_TEMP_INDEX;
    if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
      goto exit_drop_index;
    }
  }
#endif

  /* Generate code to remove the index and from the master table */
  v = sqlite3GetVdbe(pParse);
  if( v ){
    int iDb = pIndex->iDb;
    sqlite3NestedParse(pParse,
       "DELETE FROM %Q.%s WHERE name=%Q",
       db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
       pIndex->zName
    );
    sqlite3ChangeCookie(db, v, iDb);
    destroyRootPage(pParse, pIndex->tnum, iDb);
    sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0);
  }

exit_drop_index:
  sqlite3SrcListDelete(pName);
}

/*
** Append a new element to the given IdList.  Create a new IdList if
** need be.
**
** A new IdList is returned, or NULL if malloc() fails.
*/
IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){
  if( pList==0 ){
    pList = sqliteMalloc( sizeof(IdList) );
    if( pList==0 ) return 0;
    pList->nAlloc = 0;
  }
  if( pList->nId>=pList->nAlloc ){
    struct IdList_item *a;
    pList->nAlloc = pList->nAlloc*2 + 5;
    a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) );
    if( a==0 ){
      sqlite3IdListDelete(pList);
      return 0;
    }
    pList->a = a;
  }
  memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
  pList->a[pList->nId].zName = sqlite3NameFromToken(pToken);
  pList->nId++;
  return pList;
}

/*
** Append a new table name to the given SrcList.  Create a new SrcList if
** need be.  A new entry is created in the SrcList even if pToken is NULL.
**
** A new SrcList is returned, or NULL if malloc() fails.
**
** If pDatabase is not null, it means that the table has an optional
** database name prefix.  Like this:  "database.table".  The pDatabase
** points to the table name and the pTable points to the database name.
** The SrcList.a[].zName field is filled with the table name which might
** come from pTable (if pDatabase is NULL) or from pDatabase.  
** SrcList.a[].zDatabase is filled with the database name from pTable,
** or with NULL if no database is specified.
**
** In other words, if call like this:
**
**         sqlite3SrcListAppend(A,B,0);
**
** Then B is a table name and the database name is unspecified.  If called
** like this:
**
**         sqlite3SrcListAppend(A,B,C);
**
** Then C is the table name and B is the database name.
*/
SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){
  struct SrcList_item *pItem;
  if( pList==0 ){
    pList = sqliteMalloc( sizeof(SrcList) );
    if( pList==0 ) return 0;
    pList->nAlloc = 1;
  }
  if( pList->nSrc>=pList->nAlloc ){
    SrcList *pNew;
    pList->nAlloc *= 2;
    pNew = sqliteRealloc(pList,
               sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) );
    if( pNew==0 ){
      sqlite3SrcListDelete(pList);
      return 0;
    }
    pList = pNew;
  }
  pItem = &pList->a[pList->nSrc];
  memset(pItem, 0, sizeof(pList->a[0]));
  if( pDatabase && pDatabase->z==0 ){
    pDatabase = 0;
  }
  if( pDatabase && pTable ){
    Token *pTemp = pDatabase;
    pDatabase = pTable;
    pTable = pTemp;
  }
  pItem->zName = sqlite3NameFromToken(pTable);
  pItem->zDatabase = sqlite3NameFromToken(pDatabase);
  pItem->iCursor = -1;
  pList->nSrc++;
  return pList;
}

/*
** Assign cursors to all tables in a SrcList
*/
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pItem->iCursor>=0 ) break;
    pItem->iCursor = pParse->nTab++;
    if( pItem->pSelect ){
      sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
    }
  }
}

/*
** Add an alias to the last identifier on the given identifier list.
*/
void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){
  if( pList && pList->nSrc>0 ){
    pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken);
  }
}

/*
** Delete an IdList.
*/
void sqlite3IdListDelete(IdList *pList){
  int i;
  if( pList==0 ) return;
  for(i=0; i<pList->nId; i++){
    sqliteFree(pList->a[i].zName);
  }
  sqliteFree(pList->a);
  sqliteFree(pList);
}

/*
** Return the index in pList of the identifier named zId.  Return -1
** if not found.
*/
int sqlite3IdListIndex(IdList *pList, const char *zName){
  int i;
  if( pList==0 ) return -1;
  for(i=0; i<pList->nId; i++){
    if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
  }
  return -1;
}

/*
** Delete an entire SrcList including all its substructure.
*/
void sqlite3SrcListDelete(SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  if( pList==0 ) return;
  for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
    sqliteFree(pItem->zDatabase);
    sqliteFree(pItem->zName);
    sqliteFree(pItem->zAlias);
    if( pItem->pTab && pItem->pTab->isTransient ){
      sqlite3DeleteTable(0, pItem->pTab);
    }
    sqlite3SelectDelete(pItem->pSelect);
    sqlite3ExprDelete(pItem->pOn);
    sqlite3IdListDelete(pItem->pUsing);
  }
  sqliteFree(pList);
}

/*
** Begin a transaction
*/
void sqlite3BeginTransaction(Parse *pParse, int type){
  sqlite3 *db;
  Vdbe *v;
  int i;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3_malloc_failed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  if( type!=TK_DEFERRED ){
    for(i=0; i<db->nDb; i++){
      sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
    }
  }
  sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
}

/*
** Commit a transaction
*/
void sqlite3CommitTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3_malloc_failed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0);
  }
}

/*
** Rollback a transaction
*/
void sqlite3RollbackTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3_malloc_failed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1);
  }
}

/*
** Make sure the TEMP database is open and available for use.  Return
** the number of errors.  Leave any error messages in the pParse structure.
*/
static int sqlite3OpenTempDatabase(Parse *pParse){
  sqlite3 *db = pParse->db;
  if( db->aDb[1].pBt==0 && !pParse->explain ){
    int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
    if( rc!=SQLITE_OK ){
      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
        "file for storing temporary tables");
      pParse->rc = rc;
      return 1;
    }
    if( db->flags & !db->autoCommit ){
      rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1);
      if( rc!=SQLITE_OK ){
        sqlite3ErrorMsg(pParse, "unable to get a write lock on "
          "the temporary database file");
        pParse->rc = rc;
        return 1;
      }
    }
  }
  return 0;
}

/*
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.
**
** It is important that all schema cookies be verified and all
** read transactions be started before anything else happens in
** the VDBE program.  But this routine can be called after much other
** code has been generated.  So here is what we do:
**
** The first time this routine is called, we code an OP_Goto that
** will jump to a subroutine at the end of the program.  Then we
** record every database that needs its schema verified in the
** pParse->cookieMask field.  Later, after all other code has been
** generated, the subroutine that does the cookie verifications and
** starts the transactions will be coded and the OP_Goto P2 value
** will be made to point to that subroutine.  The generation of the
** cookie verification subroutine code happens in sqlite3FinishCoding().
**
** If iDb<0 then code the OP_Goto only - don't set flag to verify the
** schema on any databases.  This can be used to position the OP_Goto
** early in the code, before we know if any database tables will be used.
*/
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  sqlite3 *db;
  Vdbe *v;
  int mask;

  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;  /* This only happens if there was a prior error */
  db = pParse->db;
  if( pParse->cookieGoto==0 ){
    pParse->cookieGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0)+1;
  }
  if( iDb>=0 ){
    assert( iDb<db->nDb );
    assert( db->aDb[iDb].pBt!=0 || iDb==1 );
    assert( iDb<32 );
    mask = 1<<iDb;
    if( (pParse->cookieMask & mask)==0 ){
      pParse->cookieMask |= mask;
      pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie;
      if( iDb==1 ){
        sqlite3OpenTempDatabase(pParse);
      }
    }
  }
}

/*
** Generate VDBE code that prepares for doing an operation that
** might change the database.
**
** This routine starts a new transaction if we are not already within
** a transaction.  If we are already within a transaction, then a checkpoint
** is set if the setStatement parameter is true.  A checkpoint should
** be set for operations that might fail (due to a constraint) part of
** the way through and which will need to undo some writes without having to
** rollback the whole transaction.  For operations where all constraints
** can be checked before any changes are made to the database, it is never
** necessary to undo a write and the checkpoint should not be set.
**
** Only database iDb and the temp database are made writable by this call.
** If iDb==0, then the main and temp databases are made writable.   If
** iDb==1 then only the temp database is made writable.  If iDb>1 then the
** specified auxiliary database and the temp database are made writable.
*/
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;
  sqlite3CodeVerifySchema(pParse, iDb);
  pParse->writeMask |= 1<<iDb;
  if( setStatement && pParse->nested==0 ){
    sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
  }
  if( iDb!=1 && pParse->db->aDb[1].pBt!=0 ){
    sqlite3BeginWriteOperation(pParse, setStatement, 1);
  }
}

#ifndef SQLITE_OMIT_UTF16
/* 
** Return the transient sqlite3_value object used for encoding conversions
** during SQL compilation.
*/
sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){
  if( !db->pValue ){
    db->pValue = sqlite3ValueNew();
  }
  return db->pValue;
}
#endif

/*
** Check to see if pIndex uses the collating sequence pColl.  Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(CollSeq *pColl, Index *pIndex){
  int n = pIndex->keyInfo.nField;
  CollSeq **pp = pIndex->keyInfo.aColl;
  while( n-- ){
    if( *pp==pColl ) return 1;
    pp++;
  }
  return 0;
}
#endif

/*
** Recompute all indices of pTab that use the collating sequence pColl.
** If pColl==0 then recompute all indices of pTab.
*/
#ifndef SQLITE_OMIT_REINDEX
void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
  Index *pIndex;              /* An index associated with pTab */

  for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
    if( pColl==0 || collationMatch(pColl,pIndex) ){
      sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);
      sqlite3RefillIndex(pParse, pIndex, -1);
    }
  }
}
#endif

/*
** Recompute all indices of all tables in all databases where the
** indices use the collating sequence pColl.  If pColl==0 then recompute
** all indices everywhere.
*/
#ifndef SQLITE_OMIT_REINDEX
void reindexDatabases(Parse *pParse, CollSeq *pColl){
  Db *pDb;                    /* A single database */
  int iDb;                    /* The database index number */
  sqlite3 *db = pParse->db;   /* The database connection */
  HashElem *k;                /* For looping over tables in pDb */
  Table *pTab;                /* A table in the database */

  for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
    if( pDb==0 ) continue;
      for(k=sqliteHashFirst(&pDb->tblHash);  k; k=sqliteHashNext(k)){
      pTab = (Table*)sqliteHashData(k);
      reindexTable(pParse, pTab, pColl);
    }
  }
}
#endif

/*
** Generate code for the REINDEX command.
**
**        REINDEX                            -- 1
**        REINDEX  <collation>               -- 2
**        REINDEX  ?<database>.?<tablename>  -- 3
**        REINDEX  ?<database>.?<indexname>  -- 4
**
** Form 1 causes all indices in all attached databases to be rebuilt.
** Form 2 rebuilds all indices in all databases that use the named
** collating function.  Forms 3 and 4 rebuild the named index or all
** indices associated with the named table.
*/
#ifndef SQLITE_OMIT_REINDEX
void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
  CollSeq *pColl;             /* Collating sequence to be reindexed, or NULL */
  char *z;                    /* Name of a table or index */
  const char *zDb;            /* Name of the database */
  Table *pTab;                /* A table in the database */
  Index *pIndex;              /* An index associated with pTab */
  int iDb;                    /* The database index number */
  sqlite3 *db = pParse->db;   /* The database connection */
  Token *pObjName;            /* Name of the table or index to be reindexed */

  /* Read the database schema. If an error occurs, leave an error message
  ** and code in pParse and return NULL. */
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    return;
  }

  if( pName1==0 || pName1->z==0 ){
    reindexDatabases(pParse, 0);
    return;
  }else if( pName2==0 || pName2->z==0 ){
    pColl = sqlite3FindCollSeq(db, db->enc, pName1->z, pName1->n, 0);
    if( pColl ){
      reindexDatabases(pParse, pColl);
      return;
    }
  }
  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
  if( iDb<0 ) return;
  z = sqlite3NameFromToken(pObjName);
  zDb = db->aDb[iDb].zName;
  pTab = sqlite3FindTable(db, z, zDb);
  if( pTab ){
    reindexTable(pParse, pTab, 0);
    sqliteFree(z);
    return;
  }
  pIndex = sqlite3FindIndex(db, z, zDb);
  sqliteFree(z);
  if( pIndex ){
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3RefillIndex(pParse, pIndex, -1);
    return;
  }
  sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
}
#endif
Added SQLite.Interop/src/config.h.


>
1
#define SQLITE_PTR_SZ 4
Deleted SQLite.Interop/src/contrib/extension-functions.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
/*
This library will provide common mathematical and string functions in
SQL queries using the operating system math library.  It includes the
following functions:

Math: acos, asin, atan, atn2, atan2, acosh, asinh, atanh, difference,
degrees, radians, cos, sin, tan, cot, cosh, sinh, tanh, coth, exp,
log, log10, power, sign, sqrt, square, ceil, floor, pi.

String: replicate, charindex, leftstr, rightstr, ltrim, rtrim, trim,
replace, reverse, proper, padl, padr, padc, strfilter.

Aggregate: stdev, variance, mode, median, lower_quartile,
upper_quartile.

The string functions ltrim, rtrim, trim, replace are included in
recent versions of SQLite and so by default do not build.

Instructions:
1) Compile with
   Linux:
     gcc -fPIC -lm -shared extension-functions.c -o libsqlitefunctions.so
   Mac OS X:
     gcc -fno-common -dynamiclib extension-functions.c -o libsqlitefunctions.dylib
   (You may need to add flags
    -I /opt/local/include/ -L/opt/local/lib -lsqlite3
    if your sqlite3 is installed from Mac ports, or
    -I /sw/include/ -L/sw/lib -lsqlite3
    if installed with Fink.)
2) In your application, call sqlite3_enable_load_extension(db,1) to
   allow loading external libraries.  Then load the library libsqlitefunctions
   using sqlite3_load_extension; the third argument should be 0.
   See http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions.
3) Use, for example:
   SELECT cos(radians(inclination)) FROM satsum WHERE satnum = 25544;

Note: Loading extensions is by default prohibited as a
security measure; see "Security Considerations" in
http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions.
If the sqlite3 program and library are built this
way, you cannot use these functions from the program, you 
must write your own program using the sqlite3 API, and call
sqlite3_enable_load_extension as described above.

If the program is built so that loading extensions is permitted,
the following will work:
sqlite> SELECT load_extension('./libsqlitefunctions.so');
sqlite> select cos(radians(45));
0.707106781186548

Alterations:
The instructions are for Linux or Mac OS X; users of other OSes may
need to modify this procedure.  In particular, if your math library
lacks one or more of the needed trig or log functions, comment out the
appropriate HAVE_ #define at the top of file.  If you do not
wish to make a loadable module, comment out the define for
COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE.  If you are using a
version of SQLite without the trim functions and replace, comment out
the HAVE_TRIM #define.

Liam Healy

History:
2008-06-13 Change to instructions to indicate use of the math library
and that program might work.
2007-10-01 Minor clarification to instructions.
2007-09-29 Compilation as loadable module is optional with
COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE.
2007-09-28 Use sqlite3_extension_init and macros
SQLITE_EXTENSION_INIT1, SQLITE_EXTENSION_INIT2, so that it works with
sqlite3_load_extension.  Thanks to Eric Higashino and Joe Wilson.
New instructions for Mac compilation.
2007-09-17 With help from Joe Wilson and Nuno Luca, made use of
external interfaces so that compilation is no longer dependent on
SQLite source code.  Merged source, header, and README into a single
file.  Added casts so that Mac will compile without warnings (unsigned
and signed char).
2007-09-05 Included some definitions from sqlite 3.3.13 so that this
will continue to work in newer versions of sqlite.  Completed
description of functions available.
2007-03-27 Revised description.
2007-03-23 Small cleanup and a bug fix on the code.  This was mainly
letting errno flag errors encountered in the math library and checking
the result, rather than pre-checking.  This fixes a bug in power that
would cause an error if any non-positive number was raised to any
power.
2007-02-07 posted by Mikey C to sqlite mailing list.
Original code 2006 June 05 by relicoder.

*/

//#include "config.h"
#include <windows.h>

// #define COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE
//#define HAVE_ACOSH 1
//#define HAVE_ASINH 1
//#define HAVE_ATANH 1
#define HAVE_SINH 1
#define HAVE_COSH 1
#define HAVE_TANH 1
#define HAVE_LOG10 1
//#define HAVE_ISBLANK 1
#define SQLITE_SOUNDEX 1
#define HAVE_TRIM 1		/* LMH 2007-03-25 if sqlite has trim functions */

#ifdef COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE
#include "../core/sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#else
#include "../core/sqlite3.h"
#endif

#include <ctype.h>
/* relicoder */
#include <math.h>
#include <string.h>
#include <stdio.h>

#ifndef _WIN32_WCE
#include <errno.h>		/* LMH 2007-03-25 */
#else
int errno;
#define strerror(x) ""
#endif

#include <stdlib.h>
#include <assert.h>

#ifndef _MAP_H_
#define _MAP_H_

//#include <stdint.h>

typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed int int16_t;
typedef unsigned int uint16_t;
typedef signed long int int32_t;
typedef unsigned long int uint32_t;
typedef signed long long int int64_t;
typedef unsigned long long int uint64_t;

/*
** Simple binary tree implementation to use in median, mode and quartile calculations
** Tree is not necessarily balanced. That would require something like red&black trees of AVL
*/

typedef int(*cmp_func)(const void *, const void *);
typedef void(*map_iterator)(void*, int64_t, void*);

typedef struct node{
  struct node *l;
  struct node *r;
  void* data;
  int64_t count;
} node;

typedef struct map{
  node *base;
  cmp_func cmp;
  short free;
} map;

/*
** creates a map given a comparison function
*/
map map_make(cmp_func cmp);

/*
** inserts the element e into map m
*/
void map_insert(map *m, void *e);

/*
** executes function iter over all elements in the map, in key increasing order
*/
void map_iterate(map *m, map_iterator iter, void* p);

/*
** frees all memory used by a map
*/
void map_destroy(map *m);

/*
** compares 2 integers
** to use with map_make
*/
int int_cmp(const void *a, const void *b);

/*
** compares 2 doubles
** to use with map_make
*/
int double_cmp(const void *a, const void *b);

#endif /* _MAP_H_ */

typedef uint8_t         u8;
//typedef uint16_t        u16;
typedef int64_t         i64;

static char *sqlite3StrDup( const char *z ) {
    char *res = sqlite3_malloc( strlen(z)+1 );
    return strcpy( res, z );
}

/*
** These are copied verbatim from fun.c so as to not have the names exported
*/

/* LMH from sqlite3 3.3.13 */
/*
** This table maps from the first byte of a UTF-8 character to the number
** of trailing bytes expected. A value '4' indicates that the table key
** is not a legal first byte for a UTF-8 character.
*/
static const u8 xtra_utf8_bytes[256]  = {
/* 0xxxxxxx */
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,

/* 10wwwwww */
4, 4, 4, 4, 4, 4, 4, 4,     4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,     4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,     4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,     4, 4, 4, 4, 4, 4, 4, 4,

/* 110yyyyy */
1, 1, 1, 1, 1, 1, 1, 1,     1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,     1, 1, 1, 1, 1, 1, 1, 1,

/* 1110zzzz */
2, 2, 2, 2, 2, 2, 2, 2,     2, 2, 2, 2, 2, 2, 2, 2,

/* 11110yyy */
3, 3, 3, 3, 3, 3, 3, 3,     4, 4, 4, 4, 4, 4, 4, 4,
};


/*
** This table maps from the number of trailing bytes in a UTF-8 character
** to an integer constant that is effectively calculated for each character
** read by a naive implementation of a UTF-8 character reader. The code
** in the READ_UTF8 macro explains things best.
*/
static const int xtra_utf8_bits[] =  {
  0,
  12416,          /* (0xC0 << 6) + (0x80) */
  925824,         /* (0xE0 << 12) + (0x80 << 6) + (0x80) */
  63447168        /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */
};

/*
** If a UTF-8 character contains N bytes extra bytes (N bytes follow
** the initial byte so that the total character length is N+1) then
** masking the character with utf8_mask[N] must produce a non-zero
** result.  Otherwise, we have an (illegal) overlong encoding.
*/
static const int utf_mask[] = {
  0x00000000,
  0xffffff80,
  0xfffff800,
  0xffff0000,
};

/* LMH salvaged from sqlite3 3.3.13 source code src/utf.c */
#define OLD_READ_UTF8(zIn, c) { \
  int xtra;                                            \
  c = *(zIn)++;                                        \
  xtra = xtra_utf8_bytes[c];                           \
  switch( xtra ){                                      \
    case 4: c = (int)0xFFFD; break;                    \
    case 3: c = (c<<6) + *(zIn)++;                     \
    case 2: c = (c<<6) + *(zIn)++;                     \
    case 1: c = (c<<6) + *(zIn)++;                     \
    c -= xtra_utf8_bits[xtra];                         \
    if( (utf_mask[xtra]&c)==0                          \
        || (c&0xFFFFF800)==0xD800                      \
        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }    \
  }                                                    \
}

static int sqlite3ReadUtf8(const unsigned char *z){
  int c;
  OLD_READ_UTF8(z, c);
  return c;
}

#define SKIP_UTF8(zIn) {                               \
  zIn += (xtra_utf8_bytes[*(u8 *)zIn] + 1);            \
}

/*
** X is a pointer to the first byte of a UTF-8 character.  Increment
** X so that it points to the next character.  This only works right
** if X points to a well-formed UTF-8 string.
*/
#define sqliteNextChar(X)  while( (0xc0&*++(X))==0x80 ){}
#define sqliteCharVal(X)   sqlite3ReadUtf8(X)

/*
** This is a macro that facilitates writting wrappers for math.h functions
** it creates code for a function to use in SQlite that gets one numeric input
** and returns a floating point value.
**
** Could have been implemented using pointers to functions but this way it's inline
** and thus more efficient. Lower * ranking though...
** 
** Parameters:
** name:      function name to de defined (eg: sinFunc)
** function:  function defined in math.h to wrap (eg: sin)
** domain:    boolean condition that CAN'T happen in terms of the input parameter rVal
**            (eg: rval<0 for sqrt)
*/
/* LMH 2007-03-25 Changed to use errno and remove domain; no pre-checking for errors. */
#define GEN_MATH_WRAP_DOUBLE_1(name, function) \
static void name(sqlite3_context *context, int argc, sqlite3_value **argv){\
  double rVal = 0.0, val;\
  assert( argc==1 );\
  switch( sqlite3_value_type(argv[0]) ){\
    case SQLITE_NULL: {\
      sqlite3_result_null(context);\
      break;\
    }\
    default: {\
      rVal = sqlite3_value_double(argv[0]);\
      errno = 0;\
      val = function(rVal);\
      if (errno == 0) {\
        sqlite3_result_double(context, val);\
      } else {\
        sqlite3_result_error(context, strerror(errno), errno);\
      }\
      break;\
    }\
  }\
}\


/*
** Example of GEN_MATH_WRAP_DOUBLE_1 usage
** this creates function sqrtFunc to wrap the math.h standard function sqrt(x)=x^0.5
*/
GEN_MATH_WRAP_DOUBLE_1(sqrtFunc, sqrt)

/* trignometric functions */
GEN_MATH_WRAP_DOUBLE_1(acosFunc, acos)
GEN_MATH_WRAP_DOUBLE_1(asinFunc, asin)
GEN_MATH_WRAP_DOUBLE_1(atanFunc, atan)

/*
** Many of systems don't have inverse hyperbolic trig functions so this will emulate
** them on those systems in terms of log and sqrt (formulas are too trivial to demand 
** written proof here)
*/

#ifndef HAVE_ACOSH
static double acosh(double x){
  return log(x + sqrt(x*x - 1.0));
}
#endif

GEN_MATH_WRAP_DOUBLE_1(acoshFunc, acosh)

#ifndef HAVE_ASINH
static double asinh(double x){
  return log(x + sqrt(x*x + 1.0));
}
#endif

GEN_MATH_WRAP_DOUBLE_1(asinhFunc, asinh)

#ifndef HAVE_ATANH
static double atanh(double x){
  return (1.0/2.0)*log((1+x)/(1-x)) ;
}
#endif

GEN_MATH_WRAP_DOUBLE_1(atanhFunc, atanh)

/*
** math.h doesn't require cot (cotangent) so it's defined here
*/
static double cot(double x){
  return 1.0/tan(x);
}

GEN_MATH_WRAP_DOUBLE_1(sinFunc, sin)
GEN_MATH_WRAP_DOUBLE_1(cosFunc, cos)
GEN_MATH_WRAP_DOUBLE_1(tanFunc, tan)
GEN_MATH_WRAP_DOUBLE_1(cotFunc, cot)

static double coth(double x){
  return 1.0/tanh(x);
}

/*
** Many systems don't have hyperbolic trigonometric functions so this will emulate
** them on those systems directly from the definition in terms of exp
*/
#ifndef HAVE_SINH
static double sinh(double x){
  return (exp(x)-exp(-x))/2.0;
}
#endif

GEN_MATH_WRAP_DOUBLE_1(sinhFunc, sinh)

#ifndef HAVE_COSH
static double cosh(double x){
  return (exp(x)+exp(-x))/2.0;
}
#endif

GEN_MATH_WRAP_DOUBLE_1(coshFunc, cosh)

#ifndef HAVE_TANH
static double tanh(double x){
  return sinh(x)/cosh(x);
}
#endif

GEN_MATH_WRAP_DOUBLE_1(tanhFunc, tanh)

GEN_MATH_WRAP_DOUBLE_1(cothFunc, coth)

/*
** Some systems lack log in base 10. This will emulate it
*/

#ifndef HAVE_LOG10
static double log10(double x){
  static double l10 = -1.0;
  if( l10<0.0 ){
    l10 = log(10.0);
  }
  return log(x)/l10;
}
#endif

GEN_MATH_WRAP_DOUBLE_1(logFunc, log)
GEN_MATH_WRAP_DOUBLE_1(log10Func, log10)
GEN_MATH_WRAP_DOUBLE_1(expFunc, exp)

/*
** Fallback for systems where math.h doesn't define M_PI
*/
#undef M_PI
#ifndef M_PI
/*
** static double PI = acos(-1.0);
** #define M_PI (PI)
*/
#define M_PI 3.14159265358979323846
#endif

/* Convert Degrees into Radians */
static double deg2rad(double x){
  return x*M_PI/180.0;
}

/* Convert Radians into Degrees */
static double rad2deg(double x){
  return 180.0*x/M_PI;
}

GEN_MATH_WRAP_DOUBLE_1(rad2degFunc, rad2deg)
GEN_MATH_WRAP_DOUBLE_1(deg2radFunc, deg2rad)

/* constant function that returns the value of PI=3.1415... */
static void piFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  sqlite3_result_double(context, M_PI);
}

/*
** Implements the sqrt function, it has the peculiarity of returning an integer when the
** the argument is an integer.
** Since SQLite isn't strongly typed (almost untyped actually) this is a bit pedantic
*/
static void squareFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  i64 iVal = 0;
  double rVal = 0.0;
  assert( argc==2 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_INTEGER: {
      iVal = sqlite3_value_int64(argv[0]);
      sqlite3_result_int64(context, iVal*iVal);
      break;
    }
    case SQLITE_NULL: {
      sqlite3_result_null(context);
      break;
    }
    default: {
      rVal = sqlite3_value_double(argv[0]);
      sqlite3_result_double(context, rVal*rVal);
      break;
    }
  }
}

/*
** Wraps the pow math.h function
** When both the base and the exponent are integers the result should be integer
** (see sqrt just before this). Here the result is always double
*/
/* LMH 2007-03-25 Changed to use errno; no pre-checking for errors.  Also removes
  but that was present in the pre-checking that called sqlite3_result_error on 
  a non-positive first argument, which is not always an error. */
static void powerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  double r1 = 0.0;
  double r2 = 0.0;
  double val;

  assert( argc==2 );
  
  if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){
    sqlite3_result_null(context); 
  }else{
    r1 = sqlite3_value_double(argv[0]);
    r2 = sqlite3_value_double(argv[1]);
    errno = 0;
    val = pow(r1,r2);
    if (errno == 0) {
      sqlite3_result_double(context, val);
    } else {  
      sqlite3_result_error(context, strerror(errno), errno);
    }  
  }
}

/*
** atan2 wrapper
*/
static void atn2Func(sqlite3_context *context, int argc, sqlite3_value **argv){
  double r1 = 0.0;
  double r2 = 0.0;

  assert( argc==2 );
  
  if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){
    sqlite3_result_null(context); 
  }else{
    r1 = sqlite3_value_double(argv[0]);
    r2 = sqlite3_value_double(argv[1]);
    sqlite3_result_double(context, atan2(r1,r2));
  }
}

/*
** Implementation of the sign() function
** return one of 3 possibilities +1,0 or -1 when the argument is respectively
** positive, 0 or negative.
** When the argument is NULL the result is also NULL (completly conventional)
*/
static void signFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  double rVal=0.0;
  i64 iVal=0;
  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_INTEGER: {
      iVal = sqlite3_value_int64(argv[0]);
      iVal = ( iVal > 0) ? 1: ( iVal < 0 ) ? -1: 0;
      sqlite3_result_int64(context, iVal);
      break;
    }
    case SQLITE_NULL: {
      sqlite3_result_null(context);
      break;
    }
    default: {
 /* 2nd change below. Line for abs was: if( rVal<0 ) rVal = rVal * -1.0;  */

      rVal = sqlite3_value_double(argv[0]);
      rVal = ( rVal > 0) ? 1: ( rVal < 0 ) ? -1: 0;
      sqlite3_result_double(context, rVal);
      break;
    }
  }
}


/*
** smallest integer value not less than argument
*/
static void ceilFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  double rVal=0.0;
  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_INTEGER: {
      i64 iVal = sqlite3_value_int64(argv[0]);
      sqlite3_result_int64(context, iVal);
      break;
    }
    case SQLITE_NULL: {
      sqlite3_result_null(context);
      break;
    }
    default: {
      rVal = sqlite3_value_double(argv[0]);
      sqlite3_result_int64(context, (i64) ceil(rVal));
      break;
    }
  }
}

/*
** largest integer value not greater than argument
*/
static void floorFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  double rVal=0.0;
  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_INTEGER: {
      i64 iVal = sqlite3_value_int64(argv[0]);
      sqlite3_result_int64(context, iVal);
      break;
    }
    case SQLITE_NULL: {
      sqlite3_result_null(context);
      break;
    }
    default: {
      rVal = sqlite3_value_double(argv[0]);
      sqlite3_result_int64(context, (i64) floor(rVal));
      break;
    }
  }
}

/*
** Given a string (s) in the first argument and an integer (n) in the second returns the 
** string that constains s contatenated n times
*/
static void replicateFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  unsigned char *z;        /* input string */
  unsigned char *zo;       /* result string */
  i64 iCount;              /* times to repeat */
  i64 nLen;                /* length of the input string (no multibyte considerations) */ 
  i64 nTLen;               /* length of the result string (no multibyte considerations) */
  i64 i=0;

  if( argc!=2 || SQLITE_NULL==sqlite3_value_type(argv[0]) )
    return;

  iCount = sqlite3_value_int64(argv[1]);

  if( iCount<0 ){
    sqlite3_result_error(context, "domain error", -1);
  }else{

    nLen  = sqlite3_value_bytes(argv[0]);
    nTLen = nLen*iCount;
    z=sqlite3_malloc(nTLen+1);
    zo=sqlite3_malloc(nLen+1);
    if (!z || !zo){
      sqlite3_result_error_nomem(context);
      if (z) sqlite3_free(z);
      if (zo) sqlite3_free(zo);
      return;
    }
    strcpy((char*)zo, (char*)sqlite3_value_text(argv[0]));

    for(i=0; i<iCount; ++i){
      strcpy((char*)(z+i*nLen), (char*)zo);
    }

    sqlite3_result_text(context, (char*)z, -1, SQLITE_TRANSIENT);
    sqlite3_free(z);
    sqlite3_free(zo);
  }
}

/* 
** Some systems (win32 among others) don't have an isblank function, this will emulate it.
** This function is not UFT-8 safe since it only analyses a byte character.
*/
#ifndef HAVE_ISBLANK
int isblank(char c){
  return( ' '==c || '\t'==c );
}
#endif

static void properFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  const unsigned char *z;     /* input string */
  unsigned char *zo;          /* output string */
  unsigned char *zt;          /* iterator */
  char r;
  int c=1;

  assert( argc!=1);
  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ){
    sqlite3_result_null(context);
    return;
  }

  z = sqlite3_value_text(argv[0]);
  zo = (unsigned char *)sqlite3StrDup((char *) z);
  if (!zo) {
    sqlite3_result_error_nomem(context);
    return;
  }
  zt = zo;

  while( (r = *(z++))!=0 ){
    if( isblank(r) ){
      c=1;
    }else{
      if( c==1 ){
        r = toupper(r);
      }else{
        r = tolower(r);
      }
      c=0;
    }
    *(zt++) = r;
  }
  *zt = '\0';

  sqlite3_result_text(context, (char*)zo, -1, SQLITE_TRANSIENT);
  sqlite3_free(zo);
}

/*
** given an input string (s) and an integer (n) adds spaces at the begining of  s
** until it has a length of n characters.
** When s has a length >=n it's a NOP
** padl(NULL) = NULL
*/
static void padlFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  i64 ilen;          /* length to pad to */
  i64 zl;            /* length of the input string (UTF-8 chars) */
  int i = 0;
  const char *zi;    /* input string */
  char *zo;          /* output string */
  char *zt;

  assert( argc==2 );
  
  if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){
    sqlite3_result_null(context); 
  }else{
    zi = (char *)sqlite3_value_text(argv[0]);
    ilen = sqlite3_value_int64(argv[1]);
    /* check domain */
    if(ilen<0){
      sqlite3_result_error(context, "domain error", -1);
      return;
    }
    zl = sqlite3Utf8CharLen(zi, -1);
    if( zl>=ilen ){
      /* string is longer than the requested pad length, return the same string (dup it) */
      zo = sqlite3StrDup(zi);
      if (!zo){
        sqlite3_result_error_nomem(context);
        return;
      }
      sqlite3_result_text(context, zo, -1, SQLITE_TRANSIENT);
    }else{
      zo = sqlite3_malloc(strlen(zi)+ilen-zl+1);
      if (!zo){
        sqlite3_result_error_nomem(context);
        return;
      }
      zt = zo;
      for(i=1; i+zl<=ilen; ++i){
        *(zt++)=' ';
      }
      /* no need to take UTF-8 into consideration here */
      strcpy(zt,zi);
    }
    sqlite3_result_text(context, zo, -1, SQLITE_TRANSIENT);
    sqlite3_free(zo);
  }
}

/*
** given an input string (s) and an integer (n) appends spaces at the end of  s
** until it has a length of n characters.
** When s has a length >=n it's a NOP
** padl(NULL) = NULL
*/
static void padrFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  i64 ilen;          /* length to pad to */
  i64 zl;            /* length of the input string (UTF-8 chars) */
  i64 zll;           /* length of the input string (bytes) */
  int i = 0;
  const char *zi;    /* input string */
  char *zo;          /* output string */
  char *zt;

  assert( argc==2 );
  
  if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){
    sqlite3_result_null(context); 
  }else{
    zi = (char *)sqlite3_value_text(argv[0]);
    ilen = sqlite3_value_int64(argv[1]);
    /* check domain */
    if(ilen<0){
      sqlite3_result_error(context, "domain error", -1);
      return;
    }
    zl = sqlite3Utf8CharLen(zi, -1);
    if( zl>=ilen ){
      /* string is longer than the requested pad length, return the same string (dup it) */
      zo = sqlite3StrDup(zi);
      if (!zo){
        sqlite3_result_error_nomem(context);
        return;
      }
      sqlite3_result_text(context, zo, -1, SQLITE_TRANSIENT);
    }else{
      zll = strlen(zi);
      zo = sqlite3_malloc(zll+ilen-zl+1);
      if (!zo){
        sqlite3_result_error_nomem(context);
        return;
      }
      zt = strcpy(zo,zi)+zll;
      for(i=1; i+zl<=ilen; ++i){
        *(zt++) = ' ';
      }
      *zt = '\0';
    }
    sqlite3_result_text(context, zo, -1, SQLITE_TRANSIENT);
    sqlite3_free(zo);
  }
}

/*
** given an input string (s) and an integer (n) appends spaces at the end of  s
** and adds spaces at the begining of s until it has a length of n characters.
** Tries to add has many characters at the left as at the right.
** When s has a length >=n it's a NOP
** padl(NULL) = NULL
*/
static void padcFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  i64 ilen;           /* length to pad to */
  i64 zl;             /* length of the input string (UTF-8 chars) */
  i64 zll;            /* length of the input string (bytes) */
  int i = 0;
  const char *zi;     /* input string */
  char *zo;           /* output string */
  char *zt;

  assert( argc==2 );
  
  if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){
    sqlite3_result_null(context); 
  }else{
    zi = (char *)sqlite3_value_text(argv[0]);
    ilen = sqlite3_value_int64(argv[1]);
    /* check domain */
    if(ilen<0){
      sqlite3_result_error(context, "domain error", -1);
      return;
    }
    zl = sqlite3Utf8CharLen(zi, -1);
    if( zl>=ilen ){
      /* string is longer than the requested pad length, return the same string (dup it) */
      zo = sqlite3StrDup(zi);
      if (!zo){
        sqlite3_result_error_nomem(context);
        return;
      }
      sqlite3_result_text(context, zo, -1, SQLITE_TRANSIENT);
    }else{
      zll = strlen(zi);
      zo = sqlite3_malloc(zll+ilen-zl+1);
      if (!zo){
        sqlite3_result_error_nomem(context);
        return;
      }
      zt = zo;
      for(i=1; 2*i+zl<=ilen; ++i){
        *(zt++) = ' ';
      }
      strcpy(zt, zi);
      zt+=zll;
      for(; i+zl<=ilen; ++i){
        *(zt++) = ' ';
      }
      *zt = '\0';
    }
    sqlite3_result_text(context, zo, -1, SQLITE_TRANSIENT);
    sqlite3_free(zo);
  }
}

/*
** given 2 string (s1,s2) returns the string s1 with the characters NOT in s2 removed
** assumes strings are UTF-8 encoded
*/
static void strfilterFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char *zi1;        /* first parameter string (searched string) */
  const char *zi2;        /* second parameter string (vcontains valid characters) */
  const char *z1;
  const char *z21;
  const char *z22;
  char *zo;               /* output string */
  char *zot;
  int c1 = 0;
  int c2 = 0;

  assert( argc==2 );
  
  if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){
    sqlite3_result_null(context); 
  }else{
    zi1 = (char *)sqlite3_value_text(argv[0]);
    zi2 = (char *)sqlite3_value_text(argv[1]);
    /* 
    ** maybe I could allocate less, but that would imply 2 passes, rather waste 
    ** (possibly) some memory
    */
    zo = sqlite3_malloc(strlen(zi1)+1); 
    if (!zo){
      sqlite3_result_error_nomem(context);
      return;
    }
    zot = zo;
    z1 = zi1;
    while( (c1=sqliteCharVal((unsigned char *)z1))!=0 ){
      z21=zi2;
      while( (c2=sqliteCharVal((unsigned char *)z21))!=0 && c2!=c1 ){
        sqliteNextChar(z21);
      }
      if( c2!=0){
        z22=z21;
        sqliteNextChar(z22);
        strncpy(zot, z21, z22-z21);
        zot+=z22-z21;
      }
      sqliteNextChar(z1);
    }
    *zot = '\0';

    sqlite3_result_text(context, zo, -1, SQLITE_TRANSIENT);
    sqlite3_free(zo);
  }
}

/*
** Given a string z1, retutns the (0 based) index of it's first occurence
** in z2 after the first s characters.
** Returns -1 when there isn't a match.
** updates p to point to the character where the match occured.
** This is an auxiliary function.
*/
static int _substr(const char* z1, const char* z2, int s, CollSeq *pColl, const char** p){
  int c = 0;
  int rVal=-1;
  const char* zt1;
  const char* zt2;
  int c1,c2;

  if( '\0'==*z1 ){
    return -1;
  }
  
  while( (sqliteCharVal((unsigned char *)z2) != 0) && (c++)<s){
    sqliteNextChar(z2);
  }
  
  c = 0;
  while( (sqliteCharVal((unsigned char *)z2)) != 0 ){
    zt1 = z1;
    zt2 = z2;

    do{
      c1 = sqliteCharVal((unsigned char *)zt1);
      c2 = sqliteCharVal((unsigned char *)zt2);
      if (pColl->enc == SQLITE_UTF8){
        if (pColl->xCmp(pColl->pUser, 1, zt1, 1, zt2) == 0) {
          c1 = c2;
        }
        else {
          c1 = (c1) ? 1 : 0;
          c2 = (c2) ? 2 : 0;
        }
      }
      // TODO:  Maybe try and convert the chars to UTF16 and run them thru the collating sequence?
      sqliteNextChar(zt1);
      sqliteNextChar(zt2);
    }while( c1 == c2 && c1 != 0 && c2 != 0 );

    if( c1 == 0 ){
      rVal = c;
      break; 
    }
    
    sqliteNextChar(z2);
    ++c;
  }
  if(p){
    *p=z2;
  }
  return rVal >=0 ? rVal+s : rVal;
}

/*
** given 2 input strings (s1,s2) and an integer (n) searches from the nth character
** for the string s1. Returns the position where the match occured.
** Characters are counted from 1.
** 0 is returned when no match occurs.
*/

static void charindexFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  const u8 *z1;          /* s1 string */
  u8 *z2;                /* s2 string */
  int s=0;
  int rVal=0;
  CollSeq *pColl = context->pColl;

  assert( argc==3 ||argc==2);

  if( SQLITE_NULL==sqlite3_value_type(argv[0]) || SQLITE_NULL==sqlite3_value_type(argv[1])){
    sqlite3_result_null(context);
    return;
  }

  z1 = sqlite3_value_text(argv[0]);
  if( z1==0 ) return;
  z2 = (u8*) sqlite3_value_text(argv[1]);
  if(argc==3){
    s = sqlite3_value_int(argv[2])-1;
    if(s<0){
      s=0;
    }
  }else{
    s = 0;
  }

  rVal = _substr((char *)z1,(char *)z2,s,pColl,NULL);
  sqlite3_result_int(context, rVal+1);
}

/*
** given a string (s) and an integer (n) returns the n leftmost (UTF-8) characters
** if the string has a length<=n or is NULL this function is NOP
*/
static void leftFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  int c=0;
  int cc=0;
  int l=0;
  const unsigned char *z;       /* input string */
  const unsigned char *zt;
  unsigned char *rz;            /* output string */

  assert( argc==2);

  if( SQLITE_NULL==sqlite3_value_type(argv[0]) || SQLITE_NULL==sqlite3_value_type(argv[1])){
    sqlite3_result_null(context);
    return;
  }

  z  = sqlite3_value_text(argv[0]);
  l  = sqlite3_value_int(argv[1]);
  zt = z;

  while( sqliteCharVal(zt) && c++<l)
    sqliteNextChar(zt);

  cc=zt-z;

  rz = sqlite3_malloc(zt-z+1);
  if (!rz){
    sqlite3_result_error_nomem(context);
    return;
  }
  strncpy((char*) rz, (char*) z, zt-z);
  *(rz+cc) = '\0';
  sqlite3_result_text(context, (char*)rz, -1, SQLITE_TRANSIENT); 
  sqlite3_free(rz);
}

/*
** given a string (s) and an integer (n) returns the n rightmost (UTF-8) characters
** if the string has a length<=n or is NULL this function is NOP
*/
static void rightFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  int l=0;
  int c=0;
  int cc=0;
  const char *z;
  const char *zt;
  const char *ze;
  char *rz;

  assert( argc==2);

  if( SQLITE_NULL == sqlite3_value_type(argv[0]) || SQLITE_NULL == sqlite3_value_type(argv[1])){
    sqlite3_result_null(context);
    return;
  }

  z  = (char *)sqlite3_value_text(argv[0]);
  l  = sqlite3_value_int(argv[1]);
  zt = z;

  while( sqliteCharVal((unsigned char *)zt)!=0){
    sqliteNextChar(zt);
    ++c;
  }

  ze = zt;
  zt = z;

  cc=c-l;
  if(cc<0)
    cc=0;
  
  while( cc-- > 0 ){
    sqliteNextChar(zt);
  }

  rz = sqlite3_malloc(ze-zt+1);
  if (!rz){
    sqlite3_result_error_nomem(context);
    return;
  }
  strcpy((char*) rz, (char*) (zt));
  sqlite3_result_text(context, (char*)rz, -1, SQLITE_TRANSIENT); 
  sqlite3_free(rz);
}

#ifndef HAVE_TRIM
/*
** removes the whitespaces at the begining of a string.
*/
const char* ltrim(const char* s){
  while( *s==' ' )
    ++s;
  return s;
}

/*
** removes the whitespaces at the end of a string.
** !mutates the input string!
*/
void rtrim(char* s){
  char* ss = s+strlen(s)-1;
  while( ss>=s && *ss==' ' )
    --ss;
  *(ss+1)='\0';
}

/*
**  Removes the whitespace at the begining of a string
*/
static void ltrimFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char *z;

  assert( argc==1);

  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ){
    sqlite3_result_null(context);
    return;
  }
  z = sqlite3_value_text(argv[0]);
  sqlite3_result_text(context, ltrim(z), -1, SQLITE_TRANSIENT); 
}

/*
**  Removes the whitespace at the end of a string
*/
static void rtrimFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char *z;
  char *rz;
  /* try not to change data in argv */

  assert( argc==1);

  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ){
    sqlite3_result_null(context);
    return;
  }
  z = sqlite3_value_text(argv[0]);
  rz = sqlite3StrDup(z);
  rtrim(rz);
  sqlite3_result_text(context, rz, -1, SQLITE_TRANSIENT);
  sqlite3_free(rz);
}

/*
**  Removes the whitespace at the begining and end of a string
*/
static void trimFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char *z;
  char *rz;
  /* try not to change data in argv */

  assert( argc==1);

  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ){
    sqlite3_result_null(context);
    return;
  }
  z = sqlite3_value_text(argv[0]);
  rz = sqlite3StrDup(z);
  rtrim(rz);
  sqlite3_result_text(context, ltrim(rz), -1, SQLITE_TRANSIENT);
  sqlite3_free(rz);
}
#endif

/*
** given a pointer to a string s1, the length of that string (l1), a new string (s2)
** and it's length (l2) appends s2 to s1.
** All lengths in bytes.
** This is just an auxiliary function
*/
// static void _append(char **s1, int l1, const char *s2, int l2){
//   *s1 = realloc(*s1, (l1+l2+1)*sizeof(char));
//   strncpy((*s1)+l1, s2, l2);
//   *(*(s1)+l1+l2) = '\0';
// }

#ifndef HAVE_TRIM

/*
** given strings s, s1 and s2 replaces occurrences of s1 in s by s2
*/
static void replaceFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char *z1;     /* string s (first parameter) */
  const char *z2;     /* string s1 (second parameter) string to look for */
  const char *z3;     /* string s2 (third parameter) string to replace occurrences of s1 with */
  int lz1;
  int lz2;
  int lz3;
  int lzo=0;
  char *zo=0;
  int ret=0;
  const char *zt1;
  const char *zt2;

  assert( 3==argc );

  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ){
    sqlite3_result_null(context);
    return;
  }

  z1 = sqlite3_value_text(argv[0]);
  z2 = sqlite3_value_text(argv[1]);
  z3 = sqlite3_value_text(argv[2]);
  /* handle possible null values */
  if( 0==z2 ){
    z2="";
  }
  if( 0==z3 ){
    z3="";
  }

  lz1 = strlen(z1);
  lz2 = strlen(z2);
  lz3 = strlen(z3);

#if 0
  /* special case when z2 is empty (or null) nothing will be changed */
  if( 0==lz2 ){
    sqlite3_result_text(context, z1, -1, SQLITE_TRANSIENT);
    return;
  }
#endif

  zt1=z1;
  zt2=z1;

  while(1){
    ret=_substr(z2,zt1 , 0, &zt2);

    if( ret<0 )
      break;

    _append(&zo, lzo, zt1, zt2-zt1);
    lzo+=zt2-zt1;
    _append(&zo, lzo, z3, lz3);
    lzo+=lz3;

    zt1=zt2+lz2;
  }
  _append(&zo, lzo, zt1, lz1-(zt1-z1));
  sqlite3_result_text(context, zo, -1, SQLITE_TRANSIENT);
  sqlite3_free(zo);
}
#endif

/*
** given a string returns the same string but with the characters in reverse order
*/
static void reverseFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char *z;
  const char *zt;
  char *rz;
  char *rzt;
  int l = 0;
  int i = 0;

  assert( 1==argc );

  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ){
    sqlite3_result_null(context);
    return;
  }
  z = (char *)sqlite3_value_text(argv[0]);
  l = strlen(z);
  rz = sqlite3_malloc(l+1);
  if (!rz){
    sqlite3_result_error_nomem(context);
    return;
  }
  rzt = rz+l;
  *(rzt--) = '\0';

  zt=z;
  while( sqliteCharVal((unsigned char *)zt)!=0 ){
    z=zt;
    sqliteNextChar(zt);
    for(i=1; zt-i>=z; ++i){
      *(rzt--)=*(zt-i);
    }
  }

  sqlite3_result_text(context, rz, -1, SQLITE_TRANSIENT);
  sqlite3_free(rz);
}

/*
** An instance of the following structure holds the context of a
** stdev() or variance() aggregate computation.
** implementaion of http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Algorithm_II
** less prone to rounding errors
*/
typedef struct StdevCtx StdevCtx;
struct StdevCtx {
  double rM;
  double rS;
  i64 cnt;          /* number of elements */
};

/*
** An instance of the following structure holds the context of a
** mode() or median() aggregate computation.
** Depends on structures defined in map.c (see map & map)
** These aggregate functions only work for integers and floats although
** they could be made to work for strings. This is usually considered meaningless.
** Only usuall order (for median), no use of collation functions (would this even make sense?)
*/
typedef struct ModeCtx ModeCtx;
struct ModeCtx {
  i64 riM;            /* integer value found so far */
  double rdM;         /* double value found so far */
  i64 cnt;            /* number of elements so far */
  double pcnt;        /* number of elements smaller than a percentile */
  i64 mcnt;           /* maximum number of occurrences (for mode) */
  i64 mn;             /* number of occurrences (for mode and percentiles) */
  i64 is_double;      /* whether the computation is being done for doubles (>0) or integers (=0) */
  map* m;             /* map structure used for the computation */
  int done;           /* whether the answer has been found */
};

/*
** called for each value received during a calculation of stdev or variance
*/
static void varianceStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  StdevCtx *p;

  double delta;
  double x;

  assert( argc==1 );
  p = sqlite3_aggregate_context(context, sizeof(*p));
  /* only consider non-null values */
  if( SQLITE_NULL != sqlite3_value_numeric_type(argv[0]) ){
    p->cnt++;
    x = sqlite3_value_double(argv[0]);
    delta = (x-p->rM);
    p->rM += delta/p->cnt;
    p->rS += delta*(x-p->rM);
  }
}

/*
** called for each value received during a calculation of mode of median
*/
static void modeStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  ModeCtx *p;
  i64 xi=0;
  double xd=0.0;
  i64 *iptr;
  double *dptr;
  int type;

  assert( argc==1 );
  type = sqlite3_value_numeric_type(argv[0]);

  if( type == SQLITE_NULL)
    return;
  
  p = sqlite3_aggregate_context(context, sizeof(*p));

  if( 0==(p->m) ){
    p->m = calloc(1, sizeof(map));
    if( type==SQLITE_INTEGER ){
      /* map will be used for integers */
      *(p->m) = map_make(int_cmp);
      p->is_double = 0;
    }else{
      p->is_double = 1;
      /* map will be used for doubles */
      *(p->m) = map_make(double_cmp);
    }
  }

  ++(p->cnt);

  if( 0==p->is_double ){
    xi = sqlite3_value_int64(argv[0]);
    iptr = (i64*)calloc(1,sizeof(i64));
    *iptr = xi;
    map_insert(p->m, iptr);
  }else{
    xd = sqlite3_value_double(argv[0]);
    dptr = (double*)calloc(1,sizeof(double));
    *dptr = xd;
    map_insert(p->m, dptr);
  }
}

/*
**  Auxiliary function that iterates all elements in a map and finds the mode
**  (most frequent value)
*/
static void modeIterate(void* e, i64 c, void* pp){
  i64 ei;
  double ed;
  ModeCtx *p = (ModeCtx*)pp;
  
  if( 0==p->is_double ){
    ei = *(int*)(e);

	if( p->mcnt==c ){
      ++p->mn;
    }else if( p->mcnt<c ){
      p->riM = ei;
      p->mcnt = c;
	  p->mn=1;
    }
  }else{
    ed = *(double*)(e);

	if( p->mcnt==c ){
      ++p->mn;
    }else if(p->mcnt<c){
      p->rdM = ed;
      p->mcnt = c;
	  p->mn=1;
    }
  }
}

/*
**  Auxiliary function that iterates all elements in a map and finds the median
**  (the value such that the number of elements smaller is equal the the number of 
**  elements larger)
*/
static void medianIterate(void* e, i64 c, void* pp){
  i64 ei;
  double ed;
  double iL;
  double iR;
  int il;
  int ir;
  ModeCtx *p = (ModeCtx*)pp;

  if(p->done>0)
    return;

  iL = p->pcnt;
  iR = p->cnt - p->pcnt;
  il = p->mcnt + c;
  ir = p->cnt - p->mcnt;

  if( il >= iL ){
    if( ir >= iR ){
    ++p->mn;
      if( 0==p->is_double ){
        ei = *(int*)(e);
        p->riM += ei;
      }else{
        ed = *(double*)(e);
        p->rdM += ed;
      }
    }else{
      p->done=1;
    }
  }
  p->mcnt+=c;
}

/*
** Returns the mode value
*/
static void modeFinalize(sqlite3_context *context){
  ModeCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->m ){
    map_iterate(p->m, modeIterate, p);
    map_destroy(p->m);
    free(p->m);

    if( 1==p->mn ){
      if( 0==p->is_double )
        sqlite3_result_int64(context, p->riM);
      else
        sqlite3_result_double(context, p->rdM);
    }
  }
}

/*
** auxiliary function for percentiles
*/
static void _medianFinalize(sqlite3_context *context){
  ModeCtx *p;
  p = (ModeCtx*) sqlite3_aggregate_context(context, 0);
  if( p && p->m ){
    p->done=0;
    map_iterate(p->m, medianIterate, p);
    map_destroy(p->m);
    free(p->m);

    if( 0==p->is_double )
      if( 1==p->mn )
      	sqlite3_result_int64(context, p->riM);
      else
      	sqlite3_result_double(context, p->riM*1.0/p->mn);
    else
      sqlite3_result_double(context, p->rdM/p->mn);
  }
}

/*
** Returns the median value
*/
static void medianFinalize(sqlite3_context *context){
  ModeCtx *p;
  p = (ModeCtx*) sqlite3_aggregate_context(context, 0);
  if( p!=0 ){
    p->pcnt = (p->cnt)/2.0;
    _medianFinalize(context);
  }
}

/*
** Returns the lower_quartile value
*/
static void lower_quartileFinalize(sqlite3_context *context){
  ModeCtx *p;
  p = (ModeCtx*) sqlite3_aggregate_context(context, 0);
  if( p!=0 ){
    p->pcnt = (p->cnt)/4.0;
    _medianFinalize(context);
  }
}

/*
** Returns the upper_quartile value
*/
static void upper_quartileFinalize(sqlite3_context *context){
  ModeCtx *p;
  p = (ModeCtx*) sqlite3_aggregate_context(context, 0);
  if( p!=0 ){
    p->pcnt = (p->cnt)*3/4.0;
    _medianFinalize(context);
  }
}

/*
** Returns the stdev value
*/
static void stdevFinalize(sqlite3_context *context){
  StdevCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>1 ){
    sqlite3_result_double(context, sqrt(p->rS/(p->cnt-1)));
  }else{
    sqlite3_result_double(context, 0.0);
  }
}

/*
** Returns the variance value
*/
static void varianceFinalize(sqlite3_context *context){
  StdevCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>1 ){
    sqlite3_result_double(context, p->rS/(p->cnt-1));
  }else{
    sqlite3_result_double(context, 0.0);
  }
}

#ifdef SQLITE_SOUNDEX

/* relicoder factored code */
/*
** Calculates the soundex value of a string
*/

static void soundex(const u8 *zIn, char *zResult){
  int i, j;
  static const unsigned char iCode[] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
  };

  for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
  if( zIn[i] ){
    zResult[0] = toupper(zIn[i]);
    for(j=1; j<4 && zIn[i]; i++){
      int code = iCode[zIn[i]&0x7f];
      if( code>0 ){
        zResult[j++] = code + '0';
      }
    }
    while( j<4 ){
      zResult[j++] = '0';
    }
    zResult[j] = 0;
  }else{
    strcpy(zResult, "?000");
  }
}

/*
** computes the number of different characters between the soundex value fo 2 strings
*/
static void differenceFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  char zResult1[8];
  char zResult2[8];
  char *zR1 = zResult1;
  char *zR2 = zResult2;
  int rVal = 0;
  int i = 0;
  const u8 *zIn1;
  const u8 *zIn2;

  assert( argc==2 );
  
  if( sqlite3_value_type(argv[0])==SQLITE_NULL || sqlite3_value_type(argv[1])==SQLITE_NULL ){
    sqlite3_result_null(context);
    return;
  }
  
  zIn1 = (u8*)sqlite3_value_text(argv[0]);
  zIn2 = (u8*)sqlite3_value_text(argv[1]);

  soundex(zIn1, zR1);
  soundex(zIn2, zR2);

  for(i=0; i<4; ++i){
    if( sqliteCharVal((unsigned char *)zR1)==sqliteCharVal((unsigned char *)zR2) )
      ++rVal;
    sqliteNextChar(zR1);
    sqliteNextChar(zR2);
  }
  sqlite3_result_int(context, rVal);
}
#endif

static void lastRowsFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  sqlite3 *db = sqlite3_context_db_handle(context);
  sqlite3_result_int64(context, sqlite3_changes(db));
}

/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
*/
int RegisterExtensionFunctions(sqlite3 *db){
  static const struct FuncDefs {
     char *zName;
     signed char nArg;
     u8 argType;           /* 0: none.  1: db  2: (-1) */
     u8 eTextRep;          /* 1: UTF-16.  0: UTF-8 */
     u8 needCollSeq;
     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
  } aFuncs[] = {
    /* math.h */
    { "acos",               1, 0, SQLITE_UTF8,    0, acosFunc  },
    { "asin",               1, 0, SQLITE_UTF8,    0, asinFunc  },
    { "atan",               1, 0, SQLITE_UTF8,    0, atanFunc  },
    { "atn2",               2, 0, SQLITE_UTF8,    0, atn2Func  },
    /* XXX alias */
    { "atan2",              2, 0, SQLITE_UTF8,    0, atn2Func  },
    { "acosh",              1, 0, SQLITE_UTF8,    0, acoshFunc  },
    { "asinh",              1, 0, SQLITE_UTF8,    0, asinhFunc  },
    { "atanh",              1, 0, SQLITE_UTF8,    0, atanhFunc  },

    { "difference",         2, 0, SQLITE_UTF8,    0, differenceFunc},
    { "degrees",            1, 0, SQLITE_UTF8,    0, rad2degFunc  },
    { "radians",            1, 0, SQLITE_UTF8,    0, deg2radFunc  },

    { "cos",                1, 0, SQLITE_UTF8,    0, cosFunc  },
    { "sin",                1, 0, SQLITE_UTF8,    0, sinFunc },
    { "tan",                1, 0, SQLITE_UTF8,    0, tanFunc },
    { "cot",                1, 0, SQLITE_UTF8,    0, cotFunc },
    { "cosh",               1, 0, SQLITE_UTF8,    0, coshFunc  },
    { "sinh",               1, 0, SQLITE_UTF8,    0, sinhFunc },
    { "tanh",               1, 0, SQLITE_UTF8,    0, tanhFunc },
    { "coth",               1, 0, SQLITE_UTF8,    0, cothFunc },

    { "exp",                1, 0, SQLITE_UTF8,    0, expFunc  },
    { "log",                1, 0, SQLITE_UTF8,    0, logFunc  },
    { "log10",              1, 0, SQLITE_UTF8,    0, log10Func  },
    { "power",              2, 0, SQLITE_UTF8,    0, powerFunc  },
    { "sign",               1, 0, SQLITE_UTF8,    0, signFunc },
    { "sqrt",               1, 0, SQLITE_UTF8,    0, sqrtFunc },
    { "square",             1, 0, SQLITE_UTF8,    0, squareFunc },

    { "ceil",               1, 0, SQLITE_UTF8,    0, ceilFunc },
    { "ceiling",            1, 0, SQLITE_UTF8,    0, ceilFunc },
    { "floor",              1, 0, SQLITE_UTF8,    0, floorFunc },

    { "pi",                 0, 0, SQLITE_UTF8,    0, piFunc },
    { "last_rows_affected", 0, 0, SQLITE_UTF8,    0, lastRowsFunc },

    /* string */
    { "replicate",          2, 0, SQLITE_UTF8,    0, replicateFunc },
    { "charindex",          2, 0, SQLITE_UTF8,    1, charindexFunc },
    { "charindex",          3, 0, SQLITE_UTF8,    1, charindexFunc },
    { "leftstr",            2, 0, SQLITE_UTF8,    0, leftFunc },
    { "rightstr",           2, 0, SQLITE_UTF8,    0, rightFunc },
#ifndef HAVE_TRIM
    { "ltrim",              1, 0, SQLITE_UTF8,    0, ltrimFunc },
    { "rtrim",              1, 0, SQLITE_UTF8,    0, rtrimFunc },
    { "trim",               1, 0, SQLITE_UTF8,    0, trimFunc },
    { "replace",            3, 0, SQLITE_UTF8,    0, replaceFunc },
#endif
    { "reverse",            1, 0, SQLITE_UTF8,    0, reverseFunc },
    { "proper",             1, 0, SQLITE_UTF8,    0, properFunc },
    { "padl",               2, 0, SQLITE_UTF8,    0, padlFunc },
    { "padr",               2, 0, SQLITE_UTF8,    0, padrFunc },
    { "padc",               2, 0, SQLITE_UTF8,    0, padcFunc },
    { "strfilter",          2, 0, SQLITE_UTF8,    0, strfilterFunc },

  };
  /* Aggregate functions */
  static const struct FuncDefAgg {
    char *zName;
    signed char nArg;
    u8 argType;
    u8 needCollSeq;
    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
    void (*xFinalize)(sqlite3_context*);
  } aAggs[] = {
    { "stdev",            1, 0, 0, varianceStep, stdevFinalize  },
    { "variance",         1, 0, 0, varianceStep, varianceFinalize  },
    { "mode",             1, 0, 0, modeStep,     modeFinalize  },
    { "median",           1, 0, 0, modeStep,     medianFinalize  },
    { "lower_quartile",   1, 0, 0, modeStep,     lower_quartileFinalize  },
    { "upper_quartile",   1, 0, 0, modeStep,     upper_quartileFinalize  },
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
    void *pArg = 0;
    switch( aFuncs[i].argType ){
      case 1: pArg = db; break;
      case 2: pArg = (void *)(-1); break;
    }
    //sqlite3CreateFunc
    /* LMH no error checking */
    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
        aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
#if 1
    if( aFuncs[i].needCollSeq ){
      struct FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, 
          strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0);
      if( pFunc && aFuncs[i].needCollSeq ){
        pFunc->flags |= SQLITE_FUNC_NEEDCOLL;
      }
    }
#endif
  }

  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
    void *pArg = 0;
    switch( aAggs[i].argType ){
      case 1: pArg = db; break;
      case 2: pArg = (void *)(-1); break;
    }
    //sqlite3CreateFunc
    /* LMH no error checking */
    sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
        pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
#if 0
    if( aAggs[i].needCollSeq ){
      struct FuncDefAgg *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
          strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
      if( pFunc && aAggs[i].needCollSeq ){
        pFunc->needCollSeq = 1;
      }
    }
#endif
  }
  return 0;
}

#ifdef COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE
int sqlite3_extension_init(
    sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi){
  SQLITE_EXTENSION_INIT2(pApi);
  RegisterExtensionFunctions(db);
  return 0;
}
#endif /* COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE */

map map_make(cmp_func cmp){
  map r;
  r.cmp=cmp;
  r.base = 0;

  return r;
}

void* xcalloc(size_t nmemb, size_t size, char* s){
  void* ret = calloc(nmemb, size);
  return ret;
}

void xfree(void* p){
  free(p);
}

void node_insert(node** n, cmp_func cmp, void *e){
  int c;
  node* nn;
  if(*n==0){
    nn = (node*)xcalloc(1,sizeof(node), "for node");
    nn->data = e;
    nn->count = 1;
    *n=nn;
  }else{
    c=cmp((*n)->data,e);
    if(0==c){
      ++((*n)->count);
      xfree(e);
    }else if(c>0){
      /* put it right here */
      node_insert(&((*n)->l), cmp, e);
    }else{
      node_insert(&((*n)->r), cmp, e);
    }
  }
}

void map_insert(map *m, void *e){
  node_insert(&(m->base), m->cmp, e);
}

void node_iterate(node *n, map_iterator iter, void* p){
  if(n){
    if(n->l)
      node_iterate(n->l, iter, p);
    iter(n->data, n->count, p);
    if(n->r)
      node_iterate(n->r, iter, p);
  }
}

void map_iterate(map *m, map_iterator iter, void* p){
  node_iterate(m->base, iter, p);
}

void node_destroy(node *n){
  if(0!=n){
    xfree(n->data);
    if(n->l)
      node_destroy(n->l);
    if(n->r)
      node_destroy(n->r);

    xfree(n);
  }
}

void map_destroy(map *m){
  node_destroy(m->base);
}

int int_cmp(const void *a, const void *b){
  int64_t aa = *(int64_t *)(a);
  int64_t bb = *(int64_t *)(b);
  /* printf("cmp %d <=> %d\n",aa,bb); */
  if(aa==bb)
    return 0;
  else if(aa<bb)
    return -1;
  else
    return 1;
}

int double_cmp(const void *a, const void *b){
  double aa = *(double *)(a);
  double bb = *(double *)(b);
  /* printf("cmp %d <=> %d\n",aa,bb); */
  if(aa==bb)
    return 0;
  else if(aa<bb)
    return -1;
  else
    return 1;
}

void print_elem(void *e, int64_t c, void* p){
  int ee = *(int*)(e);
  printf("%d => %lld\n", ee,c);
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/src/core/sqlite3.c.

more than 10,000 changes

Deleted SQLite.Interop/src/core/sqlite3.h.
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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
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
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
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
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
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
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
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
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
/*
** 2001 September 15
**
** 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 header file defines the interface that the SQLite library
** presents to client programs.  If a C-function, structure, datatype,
** or constant definition does not appear in this file, then it is
** not a published API of SQLite, is subject to change without
** notice, and should not be referenced by programs that use SQLite.
**
** Some of the definitions that are in this file are marked as
** "experimental".  Experimental interfaces are normally new
** features recently added to SQLite.  We do not anticipate changes
** to experimental interfaces but reserve the right to make minor changes
** if experience from use "in the wild" suggest such changes are prudent.
**
** The official C-language API documentation for SQLite is derived
** from comments in this file.  This file is the authoritative source
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif


/*
** Add the ability to override 'extern'
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif

#ifndef SQLITE_API
# define SQLITE_API
#endif


/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental.  New applications
** should not use deprecated interfaces - they are support for backwards
** compatibility only.  Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
** These macros used to resolve to various kinds of compiler magic that
** would generate warning messages when they were used.  But that
** compiler magic ended up generating such a flurry of bug reports
** that we have taken it all out and gone back to using simple
** noop macros.
*/
#define SQLITE_DEPRECATED
#define SQLITE_EXPERIMENTAL

/*
** Ensure these symbols were not defined by some previous header file.
*/
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#endif
#ifdef SQLITE_VERSION_NUMBER
# undef SQLITE_VERSION_NUMBER
#endif

/*
** CAPI3REF: Compile-Time Library Version Numbers
**
** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header
** evaluates to a string literal that is the SQLite version in the
** format "X.Y.Z" where X is the major version number (always 3 for
** SQLite3) and Y is the minor version number and Z is the release number.)^
** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer
** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
** numbers used in [SQLITE_VERSION].)^
** The SQLITE_VERSION_NUMBER for any given release of SQLite will also
** be larger than the release from which it is derived.  Either Y will
** be held constant and Z will be incremented or else Y will be incremented
** and Z will be reset to zero.
**
** Since version 3.6.18, SQLite source code has been stored in the
** <a href="http://www.fossil-scm.org/">Fossil configuration management
** system</a>.  ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
** within its configuration management system.  ^The SQLITE_SOURCE_ID
** 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.7.9"
#define SQLITE_VERSION_NUMBER 3007009
#define SQLITE_SOURCE_ID      "2011-11-08 15:06:05 a499ae3835ed7f1591c40bea20e0c97f58ceedbb"

/*
** 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
** but are associated with the library instead of the header file.  ^(Cautious
** programmers might include assert() statements in their application to
** verify that values returned by these interfaces match the macros in
** the header, and thus insure that the application is
** compiled with matching library and header files.
**
** <blockquote><pre>
** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
** </pre></blockquote>)^
**
** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION]
** macro.  ^The sqlite3_libversion() function returns a pointer to the
** to the sqlite3_version[] string constant.  The sqlite3_libversion()
** function is provided for use in DLLs since DLL users usually do not have
** direct access to string constants within the DLL.  ^The
** sqlite3_libversion_number() function returns an integer equal to
** [SQLITE_VERSION_NUMBER].  ^The sqlite3_sourceid() function returns 
** a pointer to a string constant whose value is the same as the 
** [SQLITE_SOURCE_ID] C preprocessor macro.
**
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
SQLITE_API const char *sqlite3_libversion(void);
SQLITE_API const char *sqlite3_sourceid(void);
SQLITE_API int sqlite3_libversion_number(void);

/*
** CAPI3REF: Run-Time Library Compilation Options Diagnostics
**
** ^The sqlite3_compileoption_used() function returns 0 or 1 
** indicating whether the specified option was defined at 
** compile time.  ^The SQLITE_ prefix may be omitted from the 
** option name passed to sqlite3_compileoption_used().  
**
** ^The sqlite3_compileoption_get() function allows iterating
** over the list of options that were defined at compile time by
** returning the N-th compile time option string.  ^If N is out of range,
** sqlite3_compileoption_get() returns a NULL pointer.  ^The SQLITE_ 
** prefix is omitted from any strings returned by 
** sqlite3_compileoption_get().
**
** ^Support for the diagnostic functions sqlite3_compileoption_used()
** and sqlite3_compileoption_get() may be omitted by specifying the 
** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
**
** See also: SQL functions [sqlite_compileoption_used()] and
** [sqlite_compileoption_get()] and the [compile_options pragma].
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
SQLITE_API const char *sqlite3_compileoption_get(int N);
#endif

/*
** CAPI3REF: Test To See If The Library Is Threadsafe
**
** ^The sqlite3_threadsafe() function returns zero if and only if
** SQLite was compiled mutexing code omitted due to the
** [SQLITE_THREADSAFE] compile-time option being set to 0.
**
** SQLite can be compiled with or without mutexes.  When
** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
** are enabled and SQLite is threadsafe.  When the
** [SQLITE_THREADSAFE] macro is 0, 
** the mutexes are omitted.  Without the mutexes, it is not safe
** to use SQLite concurrently from more than one thread.
**
** Enabling mutexes incurs a measurable performance penalty.
** So if speed is of utmost importance, it makes sense to disable
** the mutexes.  But for maximum safety, mutexes should be enabled.
** ^The default behavior is for mutexes to be enabled.
**
** This interface can be used by an application to make sure that the
** version of SQLite that it is linking against was compiled with
** the desired setting of the [SQLITE_THREADSAFE] macro.
**
** This interface only reports on the compile-time mutex setting
** of the [SQLITE_THREADSAFE] flag.  If SQLite is compiled with
** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
** can be fully or partially disabled using a call to [sqlite3_config()]
** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
** or [SQLITE_CONFIG_MUTEX].  ^(The return value of the
** sqlite3_threadsafe() function shows only the compile-time setting of
** thread safety, not any run-time changes to that setting made by
** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
** is unchanged by calls to sqlite3_config().)^
**
** See the [threading mode] documentation for additional information.
*/
SQLITE_API int sqlite3_threadsafe(void);

/*
** CAPI3REF: Database Connection Handle
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
** is its destructor.  There are many other interfaces (such as
** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
** [sqlite3_busy_timeout()] to name but three) that are methods on an
** sqlite3 object.
*/
typedef struct sqlite3 sqlite3;

/*
** CAPI3REF: 64-Bit Integer Types
** KEYWORDS: sqlite_int64 sqlite_uint64
**
** Because there is no cross-platform way to specify 64-bit integer types
** SQLite includes typedefs for 64-bit signed and unsigned integers.
**
** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
** The sqlite_int64 and sqlite_uint64 types are supported for backwards
** compatibility only.
**
** ^The sqlite3_int64 and sqlite_int64 types can store integer values
** between -9223372036854775808 and +9223372036854775807 inclusive.  ^The
** sqlite3_uint64 and sqlite_uint64 types can store integer values 
** between 0 and +18446744073709551615 inclusive.
*/
#ifdef SQLITE_INT64_TYPE
  typedef SQLITE_INT64_TYPE sqlite_int64;
  typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
#elif defined(_MSC_VER) || defined(__BORLANDC__)
  typedef __int64 sqlite_int64;
  typedef unsigned __int64 sqlite_uint64;
#else
  typedef long long int sqlite_int64;
  typedef unsigned long long int sqlite_uint64;
#endif
typedef sqlite_int64 sqlite3_int64;
typedef sqlite_uint64 sqlite3_uint64;

/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite3_int64
#endif

/*
** CAPI3REF: Closing A Database Connection
**
** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
** successfully destroyed and all associated resources are deallocated.
**
** Applications must [sqlite3_finalize | finalize] all [prepared statements]
** and [sqlite3_blob_close | close] all [BLOB handles] associated with
** the [sqlite3] object prior to attempting to close the object.  ^If
** sqlite3_close() is called on a [database connection] that still has
** outstanding [prepared statements] or [BLOB handles], then it returns
** SQLITE_BUSY.
**
** ^If [sqlite3_close()] is invoked while a transaction is open,
** the transaction is automatically rolled back.
**
** The C parameter to [sqlite3_close(C)] must be either a NULL
** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
** [sqlite3_open_v2()], and not previously closed.
** ^Calling sqlite3_close() with a NULL pointer argument is a 
** harmless no-op.
*/
SQLITE_API int sqlite3_close(sqlite3 *);

/*
** The type for a callback function.
** This is legacy and deprecated.  It is included for historical
** compatibility and is not documented.
*/
typedef int (*sqlite3_callback)(void*,int,char**, char**);

/*
** CAPI3REF: One-Step Query Execution Interface
**
** The sqlite3_exec() interface is a convenience wrapper around
** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
** that allows an application to run multiple statements of SQL
** without having to use a lot of C code. 
**
** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded,
** semicolon-separate SQL statements passed into its 2nd argument,
** in the context of the [database connection] passed in as its 1st
** argument.  ^If the callback function of the 3rd argument to
** sqlite3_exec() is not NULL, then it is invoked for each result row
** coming out of the evaluated SQL statements.  ^The 4th argument to
** sqlite3_exec() is relayed through to the 1st argument of each
** callback invocation.  ^If the callback pointer to sqlite3_exec()
** is NULL, then no callback is ever invoked and result rows are
** ignored.
**
** ^If an error occurs while evaluating the SQL statements passed into
** sqlite3_exec(), then execution of the current statement stops and
** subsequent statements are skipped.  ^If the 5th parameter to sqlite3_exec()
** is not NULL then any error message is written into memory obtained
** from [sqlite3_malloc()] and passed back through the 5th parameter.
** To avoid memory leaks, the application should invoke [sqlite3_free()]
** on error message strings returned through the 5th parameter of
** of sqlite3_exec() after the error message string is no longer needed.
** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
** NULL before returning.
**
** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec()
** routine returns SQLITE_ABORT without invoking the callback again and
** without running any subsequent SQL statements.
**
** ^The 2nd argument to the sqlite3_exec() callback function is the
** number of columns in the result.  ^The 3rd argument to the sqlite3_exec()
** callback is an array of pointers to strings obtained as if from
** [sqlite3_column_text()], one for each column.  ^If an element of a
** result row is NULL then the corresponding string pointer for the
** sqlite3_exec() callback is a NULL pointer.  ^The 4th argument to the
** sqlite3_exec() callback is an array of pointers to strings where each
** entry represents the name of corresponding result column as obtained
** from [sqlite3_column_name()].
**
** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer
** to an empty string, or a pointer that contains only whitespace and/or 
** SQL comments, then no SQL statements are evaluated and the database
** is not changed.
**
** Restrictions:
**
** <ul>
** <li> The application must insure that the 1st parameter to sqlite3_exec()
**      is a valid and open [database connection].
** <li> The application must not close [database connection] specified by
**      the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
** <li> The application must not modify the SQL statement text passed into
**      the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
** </ul>
*/
SQLITE_API int sqlite3_exec(
  sqlite3*,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**),  /* Callback function */
  void *,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
);

/*
** CAPI3REF: Result Codes
** KEYWORDS: SQLITE_OK {error code} {error codes}
** KEYWORDS: {result code} {result codes}
**
** Many SQLite functions return an integer result code from the set shown
** here in order to indicates success or failure.
**
** New error codes may be added in future versions of SQLite.
**
** See also: [SQLITE_IOERR_READ | extended result codes],
** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes].
*/
#define SQLITE_OK           0   /* Successful result */
/* beginning-of-error-codes */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* Internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* Unknown opcode in sqlite3_file_control() */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* Database is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_FORMAT      24   /* Auxiliary database format error */
#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB      26   /* File opened that is not a database file */
#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
/* end-of-error-codes */

/*
** CAPI3REF: Extended Result Codes
** KEYWORDS: {extended error code} {extended error codes}
** KEYWORDS: {extended result code} {extended result codes}
**
** In its default configuration, SQLite API routines return one of 26 integer
** [SQLITE_OK | result codes].  However, experience has shown that many of
** these result codes are too coarse-grained.  They do not provide as
** much information about problems as programmers might like.  In an effort to
** address this, newer versions of SQLite (version 3.3.8 and later) include
** support for additional result codes that provide more detailed information
** about errors. The extended result codes are enabled or disabled
** on a per database connection basis using the
** [sqlite3_extended_result_codes()] API.
**
** Some of the available extended result codes are listed here.
** One may expect the number of extended result codes will be expand
** over time.  Software that uses extended result codes should expect
** to see new result codes in future releases of SQLite.
**
** The SQLITE_OK result code will never be extended.  It will always
** be exactly zero.
*/
#define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
#define SQLITE_IOERR_FSYNC             (SQLITE_IOERR | (4<<8))
#define SQLITE_IOERR_DIR_FSYNC         (SQLITE_IOERR | (5<<8))
#define SQLITE_IOERR_TRUNCATE          (SQLITE_IOERR | (6<<8))
#define SQLITE_IOERR_FSTAT             (SQLITE_IOERR | (7<<8))
#define SQLITE_IOERR_UNLOCK            (SQLITE_IOERR | (8<<8))
#define SQLITE_IOERR_RDLOCK            (SQLITE_IOERR | (9<<8))
#define SQLITE_IOERR_DELETE            (SQLITE_IOERR | (10<<8))
#define SQLITE_IOERR_BLOCKED           (SQLITE_IOERR | (11<<8))
#define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))
#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
#define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))

/*
** CAPI3REF: Flags For File Open Operations
**
** These bit values are intended for use in the
** 3rd parameter to the [sqlite3_open_v2()] interface and
** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
*/
#define SQLITE_OPEN_READONLY         0x00000001  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_READWRITE        0x00000002  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_CREATE           0x00000004  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_DELETEONCLOSE    0x00000008  /* VFS only */
#define SQLITE_OPEN_EXCLUSIVE        0x00000010  /* VFS only */
#define SQLITE_OPEN_AUTOPROXY        0x00000020  /* VFS only */
#define SQLITE_OPEN_URI              0x00000040  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_MAIN_DB          0x00000100  /* VFS only */
#define SQLITE_OPEN_TEMP_DB          0x00000200  /* VFS only */
#define SQLITE_OPEN_TRANSIENT_DB     0x00000400  /* VFS only */
#define SQLITE_OPEN_MAIN_JOURNAL     0x00000800  /* VFS only */
#define SQLITE_OPEN_TEMP_JOURNAL     0x00001000  /* VFS only */
#define SQLITE_OPEN_SUBJOURNAL       0x00002000  /* VFS only */
#define SQLITE_OPEN_MASTER_JOURNAL   0x00004000  /* VFS only */
#define SQLITE_OPEN_NOMUTEX          0x00008000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_FULLMUTEX        0x00010000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_SHAREDCACHE      0x00020000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_WAL              0x00080000  /* VFS only */

/* Reserved:                         0x00F00000 */

/*
** CAPI3REF: Device Characteristics
**
** The xDeviceCharacteristics method of the [sqlite3_io_methods]
** object returns an integer which is a vector of the these
** bit values expressing I/O characteristics of the mass storage
** device that holds the file that the [sqlite3_io_methods]
** refers to.
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
** any size are atomic.  The SQLITE_IOCAP_ATOMICnnn values
** mean that writes of blocks that are nnn bytes in size and
** are aligned to an address which is an integer multiple of
** nnn are atomic.  The SQLITE_IOCAP_SAFE_APPEND value means
** that when data is appended to a file, the data is appended
** first then the size of the file is extended, never the other
** way around.  The SQLITE_IOCAP_SEQUENTIAL property means that
** information is written to disk in the same order as calls
** to xWrite().
*/
#define SQLITE_IOCAP_ATOMIC                 0x00000001
#define SQLITE_IOCAP_ATOMIC512              0x00000002
#define SQLITE_IOCAP_ATOMIC1K               0x00000004
#define SQLITE_IOCAP_ATOMIC2K               0x00000008
#define SQLITE_IOCAP_ATOMIC4K               0x00000010
#define SQLITE_IOCAP_ATOMIC8K               0x00000020
#define SQLITE_IOCAP_ATOMIC16K              0x00000040
#define SQLITE_IOCAP_ATOMIC32K              0x00000080
#define SQLITE_IOCAP_ATOMIC64K              0x00000100
#define SQLITE_IOCAP_SAFE_APPEND            0x00000200
#define SQLITE_IOCAP_SEQUENTIAL             0x00000400
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800

/*
** CAPI3REF: File Locking Levels
**
** SQLite uses one of these integer values as the second
** argument to calls it makes to the xLock() and xUnlock() methods
** of an [sqlite3_io_methods] object.
*/
#define SQLITE_LOCK_NONE          0
#define SQLITE_LOCK_SHARED        1
#define SQLITE_LOCK_RESERVED      2
#define SQLITE_LOCK_PENDING       3
#define SQLITE_LOCK_EXCLUSIVE     4

/*
** CAPI3REF: Synchronization Type Flags
**
** When SQLite invokes the xSync() method of an
** [sqlite3_io_methods] object it uses a combination of
** these integer values as the second argument.
**
** When the SQLITE_SYNC_DATAONLY flag is used, it means that the
** sync operation only needs to flush data to mass storage.  Inode
** information need not be flushed. If the lower four bits of the flag
** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics.
** If the lower four bits equal SQLITE_SYNC_FULL, that means
** to use Mac OS X style fullsync instead of fsync().
**
** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags
** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL
** settings.  The [synchronous pragma] determines when calls to the
** xSync VFS method occur and applies uniformly across all platforms.
** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how
** energetic or rigorous or forceful the sync operations are and
** only make a difference on Mac OSX for the default SQLite code.
** (Third-party VFS implementations might also make the distinction
** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the
** operating systems natively supported by SQLite, only Mac OSX
** cares about the difference.)
*/
#define SQLITE_SYNC_NORMAL        0x00002
#define SQLITE_SYNC_FULL          0x00003
#define SQLITE_SYNC_DATAONLY      0x00010

/*
** CAPI3REF: OS Interface Open File Handle
**
** An [sqlite3_file] object represents an open file in the 
** [sqlite3_vfs | OS interface layer].  Individual OS interface
** implementations will
** want to subclass this object by appending additional fields
** for their own use.  The pMethods entry is a pointer to an
** [sqlite3_io_methods] object that defines methods for performing
** I/O operations on the open file.
*/
typedef struct sqlite3_file sqlite3_file;
struct sqlite3_file {
  const struct sqlite3_io_methods *pMethods;  /* Methods for an open file */
};

/*
** CAPI3REF: OS Interface File Virtual Methods Object
**
** Every file opened by the [sqlite3_vfs.xOpen] method populates an
** [sqlite3_file] object (or, more commonly, a subclass of the
** [sqlite3_file] object) with a pointer to an instance of this object.
** This object defines the methods used to perform various operations
** against the open file represented by the [sqlite3_file] object.
**
** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element 
** to a non-NULL pointer, then the sqlite3_io_methods.xClose method
** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed.  The
** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen]
** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element
** to NULL.
**
** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
** [SQLITE_SYNC_FULL].  The first choice is the normal fsync().
** The second choice is a Mac OS X style fullsync.  The [SQLITE_SYNC_DATAONLY]
** flag may be ORed in to indicate that only the data of the file
** and not its inode needs to be synced.
**
** The integer values to xLock() and xUnlock() are one of
** <ul>
** <li> [SQLITE_LOCK_NONE],
** <li> [SQLITE_LOCK_SHARED],
** <li> [SQLITE_LOCK_RESERVED],
** <li> [SQLITE_LOCK_PENDING], or
** <li> [SQLITE_LOCK_EXCLUSIVE].
** </ul>
** xLock() increases the lock. xUnlock() decreases the lock.
** The xCheckReservedLock() method checks whether any database connection,
** either in this process or in some other process, is holding a RESERVED,
** PENDING, or EXCLUSIVE lock on the file.  It returns true
** if such a lock exists and false otherwise.
**
** The xFileControl() method is a generic interface that allows custom
** VFS implementations to directly control an open file using the
** [sqlite3_file_control()] interface.  The second "op" argument is an
** integer opcode.  The third argument is a generic pointer intended to
** point to a structure that may contain arguments or space in which to
** write return values.  Potential uses for xFileControl() might be
** functions to enable blocking locks with timeouts, to change the
** locking strategy (for example to use dot-file locks), to inquire
** about the status of a lock, or to break stale locks.  The SQLite
** core reserves all opcodes less than 100 for its own use.
** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
** Applications that define a custom xFileControl method should use opcodes
** greater than 100 to avoid conflicts.  VFS implementations should
** return [SQLITE_NOTFOUND] for file control opcodes that they do not
** recognize.
**
** The xSectorSize() method returns the sector size of the
** device that underlies the file.  The sector size is the
** minimum write that can be performed without disturbing
** other bytes in the file.  The xDeviceCharacteristics()
** method returns a bit vector describing behaviors of the
** underlying device:
**
** <ul>
** <li> [SQLITE_IOCAP_ATOMIC]
** <li> [SQLITE_IOCAP_ATOMIC512]
** <li> [SQLITE_IOCAP_ATOMIC1K]
** <li> [SQLITE_IOCAP_ATOMIC2K]
** <li> [SQLITE_IOCAP_ATOMIC4K]
** <li> [SQLITE_IOCAP_ATOMIC8K]
** <li> [SQLITE_IOCAP_ATOMIC16K]
** <li> [SQLITE_IOCAP_ATOMIC32K]
** <li> [SQLITE_IOCAP_ATOMIC64K]
** <li> [SQLITE_IOCAP_SAFE_APPEND]
** <li> [SQLITE_IOCAP_SEQUENTIAL]
** </ul>
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
** any size are atomic.  The SQLITE_IOCAP_ATOMICnnn values
** mean that writes of blocks that are nnn bytes in size and
** are aligned to an address which is an integer multiple of
** nnn are atomic.  The SQLITE_IOCAP_SAFE_APPEND value means
** that when data is appended to a file, the data is appended
** first then the size of the file is extended, never the other
** way around.  The SQLITE_IOCAP_SEQUENTIAL property means that
** information is written to disk in the same order as calls
** to xWrite().
**
** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill
** in the unread portions of the buffer with zeros.  A VFS that
** fails to zero-fill short reads might seem to work.  However,
** failure to zero-fill short reads will eventually lead to
** database corruption.
*/
typedef struct sqlite3_io_methods sqlite3_io_methods;
struct sqlite3_io_methods {
  int iVersion;
  int (*xClose)(sqlite3_file*);
  int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
  int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
  int (*xTruncate)(sqlite3_file*, sqlite3_int64 size);
  int (*xSync)(sqlite3_file*, int flags);
  int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
  int (*xLock)(sqlite3_file*, int);
  int (*xUnlock)(sqlite3_file*, int);
  int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
  int (*xFileControl)(sqlite3_file*, int op, void *pArg);
  int (*xSectorSize)(sqlite3_file*);
  int (*xDeviceCharacteristics)(sqlite3_file*);
  /* Methods above are valid for version 1 */
  int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
  int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
  void (*xShmBarrier)(sqlite3_file*);
  int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
  /* Methods above are valid for version 2 */
  /* Additional methods may be added in future releases */
};

/*
** CAPI3REF: Standard File Control Opcodes
**
** These integer constants are opcodes for the xFileControl method
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
** interface.
**
** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging.  This
** opcode causes the xFileControl method to write the current state of
** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
** into an integer that the pArg argument points to. This capability
** is used during testing and only needs to be supported when SQLITE_TEST
** is defined.
**
** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
** layer a hint of how large the database file will grow to be during the
** current transaction.  This hint is not guaranteed to be accurate but it
** is often close.  The underlying VFS might choose to preallocate database
** file space based on this hint in order to help writes to the database
** file run faster.
**
** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
** extends and truncates the database file in chunks of a size specified
** by the user. The fourth argument to [sqlite3_file_control()] should 
** point to an integer (type int) containing the new chunk-size to use
** for the nominated database. Allocating database file space in large
** chunks (say 1MB at a time), may reduce file-system fragmentation and
** improve performance on some systems.
**
** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
** to the [sqlite3_file] object associated with a particular database
** connection.  See the [sqlite3_file_control()] documentation for
** additional information.
**
** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
** SQLite and sent to all VFSes in place of a call to the xSync method
** when the database connection has [PRAGMA synchronous] set to OFF.)^
** Some specialized VFSes need this signal in order to operate correctly
** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most 
** VFSes do not need this signal and should silently ignore this opcode.
** Applications should not call [sqlite3_file_control()] with this
** opcode as doing so may disrupt the operation of the specialized VFSes
** that do require it.  
**
** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
** retry counts and intervals for certain disk I/O operations for the
** windows [VFS] in order to work to provide robustness against
** anti-virus programs.  By default, the windows VFS will retry file read,
** file write, and file delete operations up to 10 times, with a delay
** of 25 milliseconds before the first retry and with the delay increasing
** by an additional 25 milliseconds with each subsequent retry.  This
** opcode allows those to values (10 retries and 25 milliseconds of delay)
** to be adjusted.  The values are changed for all database connections
** within the same process.  The argument is a pointer to an array of two
** integers where the first integer i the new retry count and the second
** integer is the delay.  If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
** interrogated.  The zDbName parameter is ignored.
**
** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
** persistent [WAL | Write AHead Log] setting.  By default, the auxiliary
** write ahead log and shared memory files used for transaction control
** are automatically deleted when the latest connection to the database
** closes.  Setting persistent WAL mode causes those files to persist after
** close.  Persisting the files is useful when other processes that do not
** have write permission on the directory containing the database file want
** to read the database file, as the WAL and shared memory files must exist
** in order for the database to be readable.  The fourth parameter to
** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
** WAL mode.  If the integer is -1, then it is overwritten with the current
** WAL persistence setting.
**
** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
** a write transaction to indicate that, unless it is rolled back for some
** reason, the entire database file will be overwritten by the current 
** transaction. This is used by VACUUM operations.
*/
#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

/*
** 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
** deals with pointers to the [sqlite3_mutex] object.
**
** Mutexes are created using [sqlite3_mutex_alloc()].
*/
typedef struct sqlite3_mutex sqlite3_mutex;

/*
** CAPI3REF: OS Interface Object
**
** An instance of the sqlite3_vfs object defines the interface between
** the SQLite core and the underlying operating system.  The "vfs"
** in the name of the object stands for "virtual file system".  See
** the [VFS | VFS documentation] for further information.
**
** The value of the iVersion field is initially 1 but may be larger in
** future versions of SQLite.  Additional fields may be appended to this
** object when the iVersion value is increased.  Note that the structure
** of the sqlite3_vfs object changes in the transaction between
** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
** modified.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
** structure used by this VFS.  mxPathname is the maximum length of
** a pathname in this VFS.
**
** Registered sqlite3_vfs objects are kept on a linked list formed by
** the pNext pointer.  The [sqlite3_vfs_register()]
** and [sqlite3_vfs_unregister()] interfaces manage this list
** in a thread-safe way.  The [sqlite3_vfs_find()] interface
** searches the list.  Neither the application code nor the VFS
** implementation should use the pNext pointer.
**
** The pNext field is the only field in the sqlite3_vfs
** structure that SQLite will ever modify.  SQLite will only access
** or modify this field while holding a particular static mutex.
** The application should never modify anything within the sqlite3_vfs
** object once the object has been registered.
**
** The zName field holds the name of the VFS module.  The name must
** be unique across all VFS modules.
**
** [[sqlite3_vfs.xOpen]]
** ^SQLite guarantees that the zFilename parameter to xOpen
** is either a NULL pointer or string obtained
** from xFullPathname() with an optional suffix added.
** ^If a suffix is added to the zFilename parameter, it will
** consist of a single "-" character followed by no more than
** 10 alphanumeric and/or "-" characters.
** ^SQLite further guarantees that
** the string will be valid and unchanged until xClose() is
** called. Because of the previous sentence,
** the [sqlite3_file] can safely store a pointer to the
** filename if it needs to remember the filename for some reason.
** If the zFilename parameter to xOpen is a NULL pointer then xOpen
** must invent its own temporary name for the file.  ^Whenever the 
** xFilename parameter is NULL it will also be the case that the
** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
**
** The flags argument to xOpen() includes all bits set in
** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
** or [sqlite3_open16()] is used, then flags includes at least
** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. 
** If xOpen() opens a file read-only then it sets *pOutFlags to
** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
**
** ^(SQLite will also add one of the following flags to the xOpen()
** call, depending on the object being opened:
**
** <ul>
** <li>  [SQLITE_OPEN_MAIN_DB]
** <li>  [SQLITE_OPEN_MAIN_JOURNAL]
** <li>  [SQLITE_OPEN_TEMP_DB]
** <li>  [SQLITE_OPEN_TEMP_JOURNAL]
** <li>  [SQLITE_OPEN_TRANSIENT_DB]
** <li>  [SQLITE_OPEN_SUBJOURNAL]
** <li>  [SQLITE_OPEN_MASTER_JOURNAL]
** <li>  [SQLITE_OPEN_WAL]
** </ul>)^
**
** The file I/O implementation can use the object type flags to
** change the way it deals with files.  For example, an application
** that does not care about crash recovery or rollback might make
** the open of a journal file a no-op.  Writes to this journal would
** also be no-ops, and any attempt to read the journal would return
** SQLITE_IOERR.  Or the implementation might recognize that a database
** file will be doing page-aligned sector reads and writes in a random
** order and set up its I/O subsystem accordingly.
**
** SQLite might also add one of the following flags to the xOpen method:
**
** <ul>
** <li> [SQLITE_OPEN_DELETEONCLOSE]
** <li> [SQLITE_OPEN_EXCLUSIVE]
** </ul>
**
** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
** deleted when it is closed.  ^The [SQLITE_OPEN_DELETEONCLOSE]
** will be set for TEMP databases and their journals, transient
** databases, and subjournals.
**
** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
** with the [SQLITE_OPEN_CREATE] flag, which are both directly
** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
** API.  The SQLITE_OPEN_EXCLUSIVE flag, when paired with the 
** SQLITE_OPEN_CREATE, is used to indicate that file should always
** be created, and that it is an error if it already exists.
** It is <i>not</i> used to indicate the file should be opened 
** for exclusive access.
**
** ^At least szOsFile bytes of memory are allocated by SQLite
** to hold the  [sqlite3_file] structure passed as the third
** argument to xOpen.  The xOpen method does not have to
** allocate the structure; it should just fill it in.  Note that
** the xOpen method must set the sqlite3_file.pMethods to either
** a valid [sqlite3_io_methods] object or to NULL.  xOpen must do
** this even if the open fails.  SQLite expects that the sqlite3_file.pMethods
** element will be valid after xOpen returns regardless of the success
** or failure of the xOpen call.
**
** [[sqlite3_vfs.xAccess]]
** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
** to test whether a file is at least readable.   The file can be a
** directory.
**
** ^SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname.  The exact size of the output buffer
** is also passed as a parameter to both  methods. If the output buffer
** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
** handled as a fatal error by SQLite, vfs implementations should endeavor
** to prevent this by setting mxPathname to a sufficiently large value.
**
** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
** interfaces are not strictly a part of the filesystem, but they are
** included in the VFS structure for completeness.
** The xRandomness() function attempts to return nBytes bytes
** of good-quality randomness into zOut.  The return value is
** the actual number of bytes of randomness obtained.
** The xSleep() method causes the calling thread to sleep for at
** least the number of microseconds given.  ^The xCurrentTime()
** method returns a Julian Day Number for the current date and time as
** a floating point value.
** ^The xCurrentTimeInt64() method returns, as an integer, the Julian
** Day Number multiplied by 86400000 (the number of milliseconds in 
** a 24-hour day).  
** ^SQLite will use the xCurrentTimeInt64() method to get the current
** date and time if that method is available (if iVersion is 2 or 
** greater and the function pointer is not NULL) and will fall back
** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
**
** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces
** are not used by the SQLite core.  These optional interfaces are provided
** by some VFSes to facilitate testing of the VFS code. By overriding 
** system calls with functions under its control, a test program can
** simulate faults and error conditions that would otherwise be difficult
** or impossible to induce.  The set of system calls that can be overridden
** varies from one VFS to another, and from one version of the same VFS to the
** next.  Applications that use these interfaces must be prepared for any
** or all of these interfaces to be NULL or for their behavior to change
** from one release to the next.  Applications must not attempt to access
** any of these methods if the iVersion of the VFS is less than 3.
*/
typedef struct sqlite3_vfs sqlite3_vfs;
typedef void (*sqlite3_syscall_ptr)(void);
struct sqlite3_vfs {
  int iVersion;            /* Structure version number (currently 3) */
  int szOsFile;            /* Size of subclassed sqlite3_file */
  int mxPathname;          /* Maximum file pathname length */
  sqlite3_vfs *pNext;      /* Next registered VFS */
  const char *zName;       /* Name of this virtual file system */
  void *pAppData;          /* Pointer to application-specific data */
  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
               int flags, int *pOutFlags);
  int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
  int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
  void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
  void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
  void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
  void (*xDlClose)(sqlite3_vfs*, void*);
  int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
  int (*xSleep)(sqlite3_vfs*, int microseconds);
  int (*xCurrentTime)(sqlite3_vfs*, double*);
  int (*xGetLastError)(sqlite3_vfs*, int, char *);
  /*
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** Those below are for version 3 and greater.
  */
  int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
  sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
  const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
  /*
  ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */
};

/*
** CAPI3REF: Flags for the xAccess VFS method
**
** These integer constants can be used as the third parameter to
** the xAccess method of an [sqlite3_vfs] object.  They determine
** what kind of permissions the xAccess method is looking for.
** With SQLITE_ACCESS_EXISTS, the xAccess method
** simply checks whether the file exists.
** With SQLITE_ACCESS_READWRITE, the xAccess method
** checks whether the named directory is both readable and writable
** (in other words, if files can be added, removed, and renamed within
** the directory).
** The SQLITE_ACCESS_READWRITE constant is currently used only by the
** [temp_store_directory pragma], though this could change in a future
** release of SQLite.
** With SQLITE_ACCESS_READ, the xAccess method
** checks whether the file is readable.  The SQLITE_ACCESS_READ constant is
** currently unused, though it might be used in a future release of
** SQLite.
*/
#define SQLITE_ACCESS_EXISTS    0
#define SQLITE_ACCESS_READWRITE 1   /* Used by PRAGMA temp_store_directory */
#define SQLITE_ACCESS_READ      2   /* Unused */

/*
** CAPI3REF: Flags for the xShmLock VFS method
**
** These integer constants define the various locking operations
** allowed by the xShmLock method of [sqlite3_io_methods].  The
** following are the only legal combinations of flags to the
** xShmLock method:
**
** <ul>
** <li>  SQLITE_SHM_LOCK | SQLITE_SHM_SHARED
** <li>  SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE
** <li>  SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED
** <li>  SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE
** </ul>
**
** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
** was given no the corresponding lock.  
**
** The xShmLock method can transition between unlocked and SHARED or
** between unlocked and EXCLUSIVE.  It cannot transition between SHARED
** and EXCLUSIVE.
*/
#define SQLITE_SHM_UNLOCK       1
#define SQLITE_SHM_LOCK         2
#define SQLITE_SHM_SHARED       4
#define SQLITE_SHM_EXCLUSIVE    8

/*
** CAPI3REF: Maximum xShmLock index
**
** The xShmLock method on [sqlite3_io_methods] may use values
** between 0 and this upper bound as its "offset" argument.
** The SQLite core will never attempt to acquire or release a
** lock outside of this range
*/
#define SQLITE_SHM_NLOCK        8


/*
** CAPI3REF: Initialize The SQLite Library
**
** ^The sqlite3_initialize() routine initializes the
** SQLite library.  ^The sqlite3_shutdown() routine
** deallocates any resources that were allocated by sqlite3_initialize().
** These routines are designed to aid in process initialization and
** shutdown on embedded systems.  Workstation applications using
** SQLite normally do not need to invoke either of these routines.
**
** A call to sqlite3_initialize() is an "effective" call if it is
** the first time sqlite3_initialize() is invoked during the lifetime of
** the process, or if it is the first time sqlite3_initialize() is invoked
** following a call to sqlite3_shutdown().  ^(Only an effective call
** of sqlite3_initialize() does any initialization.  All other calls
** are harmless no-ops.)^
**
** A call to sqlite3_shutdown() is an "effective" call if it is the first
** call to sqlite3_shutdown() since the last sqlite3_initialize().  ^(Only
** an effective call to sqlite3_shutdown() does any deinitialization.
** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^
**
** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown()
** is not.  The sqlite3_shutdown() interface must only be called from a
** single thread.  All open [database connections] must be closed and all
** other SQLite resources must be deallocated prior to invoking
** sqlite3_shutdown().
**
** Among other things, ^sqlite3_initialize() will invoke
** sqlite3_os_init().  Similarly, ^sqlite3_shutdown()
** will invoke sqlite3_os_end().
**
** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success.
** ^If for some reason, sqlite3_initialize() is unable to initialize
** the library (perhaps it is unable to allocate a needed resource such
** as a mutex) it returns an [error code] other than [SQLITE_OK].
**
** ^The sqlite3_initialize() routine is called internally by many other
** SQLite interfaces so that an application usually does not need to
** invoke sqlite3_initialize() directly.  For example, [sqlite3_open()]
** calls sqlite3_initialize() so the SQLite library will be automatically
** initialized when [sqlite3_open()] is called if it has not be initialized
** already.  ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT]
** compile-time option, then the automatic calls to sqlite3_initialize()
** are omitted and the application must call sqlite3_initialize() directly
** prior to using any other SQLite interface.  For maximum portability,
** it is recommended that applications always invoke sqlite3_initialize()
** directly prior to using any other SQLite interface.  Future releases
** of SQLite may require this.  In other words, the behavior exhibited
** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the
** default behavior in some future release of SQLite.
**
** The sqlite3_os_init() routine does operating-system specific
** initialization of the SQLite library.  The sqlite3_os_end()
** routine undoes the effect of sqlite3_os_init().  Typical tasks
** performed by these routines include allocation or deallocation
** of static resources, initialization of global variables,
** setting up a default [sqlite3_vfs] module, or setting up
** a default configuration using [sqlite3_config()].
**
** The application should never invoke either sqlite3_os_init()
** or sqlite3_os_end() directly.  The application should only invoke
** sqlite3_initialize() and sqlite3_shutdown().  The sqlite3_os_init()
** interface is called automatically by sqlite3_initialize() and
** sqlite3_os_end() is called by sqlite3_shutdown().  Appropriate
** implementations for sqlite3_os_init() and sqlite3_os_end()
** are built into SQLite when it is compiled for Unix, Windows, or OS/2.
** When [custom builds | built for other platforms]
** (using the [SQLITE_OS_OTHER=1] compile-time
** option) the application must supply a suitable implementation for
** sqlite3_os_init() and sqlite3_os_end().  An application-supplied
** implementation of sqlite3_os_init() or sqlite3_os_end()
** must return [SQLITE_OK] on success and some other [error code] upon
** failure.
*/
SQLITE_API int sqlite3_initialize(void);
SQLITE_API int sqlite3_shutdown(void);
SQLITE_API int sqlite3_os_init(void);
SQLITE_API int sqlite3_os_end(void);

/*
** CAPI3REF: Configuring The SQLite Library
**
** The sqlite3_config() interface is used to make global configuration
** changes to SQLite in order to tune SQLite to the specific needs of
** the application.  The default configuration is recommended for most
** applications and so this routine is usually not necessary.  It is
** provided to support rare applications with unusual needs.
**
** The sqlite3_config() interface is not threadsafe.  The application
** must insure that no other SQLite interfaces are invoked by other
** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
** may only be invoked prior to library initialization using
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
** Note, however, that ^sqlite3_config() can be called as part of the
** implementation of an application-defined [sqlite3_os_init()].
**
** The first argument to sqlite3_config() is an integer
** [configuration option] that determines
** what property of SQLite is to be configured.  Subsequent arguments
** vary depending on the [configuration option]
** in the first argument.
**
** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
*/
SQLITE_API int sqlite3_config(int, ...);

/*
** CAPI3REF: Configure database connections
**
** The sqlite3_db_config() interface is used to make configuration
** changes to a [database connection].  The interface is similar to
** [sqlite3_config()] except that the changes apply to a single
** [database connection] (specified in the first argument).
**
** The second argument to sqlite3_db_config(D,V,...)  is the
** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code 
** that indicates what aspect of the [database connection] is being configured.
** Subsequent arguments vary depending on the configuration verb.
**
** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
** the call is considered successful.
*/
SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);

/*
** CAPI3REF: Memory Allocation Routines
**
** An instance of this object defines the interface between SQLite
** and low-level memory allocation routines.
**
** This object is used in only one place in the SQLite interface.
** A pointer to an instance of this object is the argument to
** [sqlite3_config()] when the configuration option is
** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].  
** By creating an instance of this object
** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
** during configuration, an application can specify an alternative
** memory allocation subsystem for SQLite to use for all of its
** dynamic memory needs.
**
** Note that SQLite comes with several [built-in memory allocators]
** that are perfectly adequate for the overwhelming majority of applications
** and that this object is only useful to a tiny minority of applications
** with specialized memory allocation requirements.  This object is
** also used during testing of SQLite in order to specify an alternative
** memory allocator that simulates memory out-of-memory conditions in
** order to verify that SQLite recovers gracefully from such
** conditions.
**
** The xMalloc, xRealloc, and xFree methods must work like the
** malloc(), realloc() and free() functions from the standard C library.
** ^SQLite guarantees that the second argument to
** xRealloc is always a value returned by a prior call to xRoundup.
**
** xSize should return the allocated size of a memory allocation
** previously obtained from xMalloc or xRealloc.  The allocated size
** is always at least as big as the requested size but may be larger.
**
** The xRoundup method returns what would be the allocated size of
** a memory allocation given a particular requested size.  Most memory
** allocators round up memory allocations at least to the next multiple
** of 8.  Some allocators round up to a larger multiple or to a power of 2.
** Every memory allocation request coming in through [sqlite3_malloc()]
** or [sqlite3_realloc()] first calls xRoundup.  If xRoundup returns 0, 
** that causes the corresponding memory allocation to fail.
**
** The xInit method initializes the memory allocator.  (For example,
** it might allocate any require mutexes or initialize internal data
** structures.  The xShutdown method is invoked (indirectly) by
** [sqlite3_shutdown()] and should deallocate any resources acquired
** by xInit.  The pAppData pointer is used as the only parameter to
** xInit and xShutdown.
**
** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
** the xInit method, so the xInit method need not be threadsafe.  The
** xShutdown method is only called from [sqlite3_shutdown()] so it does
** not need to be threadsafe either.  For all other methods, SQLite
** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
** it is by default) and so the methods are automatically serialized.
** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
** methods must be threadsafe or else make their own arrangements for
** serialization.
**
** SQLite will never invoke xInit() more than once without an intervening
** call to xShutdown().
*/
typedef struct sqlite3_mem_methods sqlite3_mem_methods;
struct sqlite3_mem_methods {
  void *(*xMalloc)(int);         /* Memory allocation function */
  void (*xFree)(void*);          /* Free a prior allocation */
  void *(*xRealloc)(void*,int);  /* Resize an allocation */
  int (*xSize)(void*);           /* Return the size of an allocation */
  int (*xRoundup)(int);          /* Round up request size to allocation size */
  int (*xInit)(void*);           /* Initialize the memory allocator */
  void (*xShutdown)(void*);      /* Deinitialize the memory allocator */
  void *pAppData;                /* Argument to xInit() and xShutdown() */
};

/*
** CAPI3REF: Configuration Options
** KEYWORDS: {configuration option}
**
** These constants are the available integer configuration options that
** can be passed as the first argument to the [sqlite3_config()] interface.
**
** New configuration options may be added in future releases of SQLite.
** Existing configuration options might be discontinued.  Applications
** should check the return code from [sqlite3_config()] to make sure that
** the call worked.  The [sqlite3_config()] interface will return a
** non-zero [error code] if a discontinued or unsupported configuration option
** is invoked.
**
** <dl>
** [[SQLITE_CONFIG_SINGLETHREAD]] <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
** <dd>There are no arguments to this option.  ^This option sets the
** [threading mode] to Single-thread.  In other words, it disables
** all mutexing and puts SQLite into a mode where it can only be used
** by a single thread.   ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** it is not possible to change the [threading mode] from its default
** value of Single-thread and so [sqlite3_config()] will return 
** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD
** configuration option.</dd>
**
** [[SQLITE_CONFIG_MULTITHREAD]] <dt>SQLITE_CONFIG_MULTITHREAD</dt>
** <dd>There are no arguments to this option.  ^This option sets the
** [threading mode] to Multi-thread.  In other words, it disables
** mutexing on [database connection] and [prepared statement] objects.
** The application is responsible for serializing access to
** [database connections] and [prepared statements].  But other mutexes
** are enabled so that SQLite will be safe to use in a multi-threaded
** environment as long as no two threads attempt to use the same
** [database connection] at the same time.  ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** it is not possible to set the Multi-thread [threading mode] and
** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
** SQLITE_CONFIG_MULTITHREAD configuration option.</dd>
**
** [[SQLITE_CONFIG_SERIALIZED]] <dt>SQLITE_CONFIG_SERIALIZED</dt>
** <dd>There are no arguments to this option.  ^This option sets the
** [threading mode] to Serialized. In other words, this option enables
** all mutexes including the recursive
** mutexes on [database connection] and [prepared statement] objects.
** In this mode (which is the default when SQLite is compiled with
** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access
** to [database connections] and [prepared statements] so that the
** application is free to use the same [database connection] or the
** same [prepared statement] in different threads at the same time.
** ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** it is not possible to set the Serialized [threading mode] and
** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
**
** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure.  The argument specifies
** alternative low-level memory allocation routines to be used in place of
** the memory allocation routines built into SQLite.)^ ^SQLite makes
** its own private copy of the content of the [sqlite3_mem_methods] structure
** before the [sqlite3_config()] call returns.</dd>
**
** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure.  The [sqlite3_mem_methods]
** structure is filled with the currently defined memory allocation routines.)^
** This option can be used to overload the default memory allocation
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^This option takes single argument of type int, interpreted as a 
** boolean, which enables or disables the collection of memory allocation 
** statistics. ^(When memory allocation statistics are disabled, the 
** following SQLite interfaces become non-operational:
**   <ul>
**   <li> [sqlite3_memory_used()]
**   <li> [sqlite3_memory_highwater()]
**   <li> [sqlite3_soft_heap_limit64()]
**   <li> [sqlite3_status()]
**   </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
** allocation statistics are disabled by default.
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** scratch memory.  There are three arguments:  A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).  The sz
** argument must be a multiple of 16.
** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will use no more than two scratch buffers per thread.  So
** N should be set to twice the expected maximum number of threads.
** ^SQLite will never require a scratch buffer that is more than 6
** times the database page size. ^If SQLite needs needs additional
** scratch memory beyond what is provided by this configuration option, then 
** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** the database page cache with the default page cache implementation.  
** This configuration should not be used if an application-define page
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
** There are three arguments to this option: A pointer to 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 32768) plus a little extra for each
** page header.  ^The page header size is 20 to 40 bytes depending on
** the host architecture.  ^It is harmless, apart from the wasted memory,
** to make sz a little too large.  The first
** argument should point to an allocation of at least sz*N bytes of memory.
** ^SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache.  ^If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.
** The pointer in the first argument must
** be aligned to an 8-byte boundary or subsequent behavior of SQLite
** will be undefined.</dd>
**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^This option specifies a static memory buffer that SQLite will use
** for all of its dynamic memory allocation needs beyond those provided
** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
** There are three arguments: An 8-byte aligned pointer to the memory,
** the number of bytes in the memory buffer, and the minimum allocation size.
** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
** to using its default memory allocator (the system malloc() implementation),
** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
** allocator is engaged to handle all of SQLites memory allocation needs.
** The first pointer (the memory pointer) must be aligned to an 8-byte
** boundary or subsequent behavior of SQLite will be undefined.
** The minimum allocation size is capped at 2**12. Reasonable values
** for the minimum allocation size are 2**5 through 2**8.</dd>
**
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure.  The argument specifies
** alternative low-level mutex routines to be used in place
** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
** content of the [sqlite3_mutex_methods] structure before the call to
** [sqlite3_config()] returns. ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure.  The
** [sqlite3_mutex_methods]
** structure is filled with the currently defined mutex routines.)^
** This option can be used to overload the default mutex allocation
** routines with a wrapper used to track mutex usage for performance
** profiling or testing, for example.   ^If SQLite is compiled with
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(This option takes two arguments that determine the default
** memory allocation for the lookaside memory allocator on each
** [database connection].  The first argument is the
** size of each lookaside buffer slot and the second is the number of
** slots allocated to each database connection.)^  ^(This option sets the
** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
** verb to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.)^ </dd>
**
** [[SQLITE_CONFIG_PCACHE]] <dt>SQLITE_CONFIG_PCACHE</dt>
** <dd> ^(This option takes a single argument which is a pointer to
** an [sqlite3_pcache_methods] object.  This object specifies the interface
** to a custom page cache implementation.)^  ^SQLite makes a copy of the
** object and uses it for page cache memory allocations.</dd>
**
** [[SQLITE_CONFIG_GETPCACHE]] <dt>SQLITE_CONFIG_GETPCACHE</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** [sqlite3_pcache_methods] object.  SQLite copies of the current
** page cache implementation into that object.)^ </dd>
**
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
** <dd> ^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
** function with a call signature of void(*)(void*,int,const char*), 
** and a pointer to void. ^If the function pointer is not NULL, it is
** invoked by [sqlite3_log()] to process each logging event.  ^If the
** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op.
** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is
** passed through as the first parameter to the application-defined logger
** function whenever that function is invoked.  ^The second parameter to
** the logger function is a copy of the first parameter to the corresponding
** [sqlite3_log()] call and is intended to be a [result code] or an
** [extended result code].  ^The third parameter passed to the logger is
** 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
** URI handling is globally enabled. If the parameter is zero, then URI handling
** 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
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** 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.
** </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* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
#define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ 
#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
#define SQLITE_CONFIG_PCACHE       14  /* sqlite3_pcache_methods* */
#define SQLITE_CONFIG_GETPCACHE    15  /* sqlite3_pcache_methods* */
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
#define SQLITE_CONFIG_URI          17  /* int */

/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**
** New configuration options may be added in future releases of SQLite.
** Existing configuration options might be discontinued.  Applications
** should check the return code from [sqlite3_db_config()] to make sure that
** the call worked.  ^The [sqlite3_db_config()] interface will return a
** non-zero [error code] if a discontinued or unsupported configuration option
** is invoked.
**
** <dl>
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd> ^This option takes three additional arguments that determine the 
** [lookaside memory allocator] configuration for the [database connection].
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to a memory buffer to use for lookaside memory.
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
** may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
** size of each lookaside buffer slot.  ^The third argument is the number of
** slots.  The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.  The buffer
** must be aligned to an 8-byte boundary.  ^If the second argument to
** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
** rounded down to the next smaller multiple of 8.  ^(The lookaside memory
** configuration for a database connection can only be changed when that
** connection is not currently using lookaside memory, or in other words
** when the "current value" returned by
** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns 
** [SQLITE_BUSY].)^</dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
** <dd> ^This option is used to enable or disable the enforcement of
** [foreign key constraints].  There should be two additional arguments.
** The first argument is an integer which is 0 to disable FK enforcement,
** positive to enable FK enforcement or negative to leave FK enforcement
** unchanged.  The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether FK enforcement is off or on
** following this call.  The second parameter may be a NULL pointer, in
** which case the FK enforcement setting is not reported back. </dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable triggers,
** positive to enable triggers or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether triggers are disabled or enabled
** following this call.  The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back. </dd>
**
** </dl>
*/
#define SQLITE_DBCONFIG_LOOKASIDE       1001  /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY     1002  /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER  1003  /* int int* */


/*
** CAPI3REF: Enable Or Disable Extended Result Codes
**
** ^The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. ^The extended result
** 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 an SQLite table 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.
**
** ^(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.)^
**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
** routine.  ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
** and INSERT OR ABORT make no changes to the return value of this
** routine when their insertion fails.  ^(When INSERT OR REPLACE
** encounters a constraint violation, it does not fail.  The
** INSERT continues to completion after deleting rows that caused
** the constraint problem so INSERT OR REPLACE will always change
** the return value of this interface.)^
**
** ^For the purposes of this routine, an [INSERT] is considered to
** be successful even if it is subsequently rolled back.
**
** This function is accessible to SQL statements via the
** [last_insert_rowid() SQL function].
**
** If a separate thread performs a new [INSERT] on the same
** database connection while the [sqlite3_last_insert_rowid()]
** function is running and thus changes the last insert [rowid],
** then the value returned by [sqlite3_last_insert_rowid()] is
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);

/*
** CAPI3REF: Count The Number Of Rows Modified
**
** ^This function returns the number of database rows that were changed
** or inserted or deleted by the most recently completed SQL statement
** on the [database connection] specified by the first parameter.
** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
** or [DELETE] statement are counted.  Auxiliary changes caused by
** triggers or [foreign key actions] are not counted.)^ Use the
** [sqlite3_total_changes()] function to find the total number of changes
** including changes caused by triggers and foreign key actions.
**
** ^Changes to a view that are simulated by an [INSTEAD OF trigger]
** are not counted.  Only real table changes are counted.
**
** ^(A "row change" is a change to a single row of a single table
** caused by an INSERT, DELETE, or UPDATE statement.  Rows that
** are changed as side effects of [REPLACE] constraint resolution,
** rollback, ABORT processing, [DROP TABLE], or by any other
** mechanisms do not count as direct row changes.)^
**
** A "trigger context" is a scope of execution that begins and
** ends with the script of a [CREATE TRIGGER | trigger]. 
** Most SQL statements are
** evaluated outside of any trigger.  This is the "top level"
** trigger context.  If a trigger fires from the top level, a
** new trigger context is entered for the duration of that one
** trigger.  Subtriggers create subcontexts for their duration.
**
** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
** not create a new trigger context.
**
** ^This function returns the number of direct row changes in the
** most recent INSERT, UPDATE, or DELETE statement within the same
** trigger context.
**
** ^Thus, when called from the top level, this function returns the
** number of changes in the most recent INSERT, UPDATE, or DELETE
** that also occurred at the top level.  ^(Within the body of a trigger,
** the sqlite3_changes() interface can be called to find the number of
** changes in the most recently completed INSERT, UPDATE, or DELETE
** statement within the body of the same trigger.
** However, the number returned does not include changes
** caused by subtriggers since those have their own context.)^
**
** See also the [sqlite3_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
SQLITE_API int sqlite3_changes(sqlite3*);

/*
** CAPI3REF: Total Number Of Rows Modified
**
** ^This function returns the number of row changes caused by [INSERT],
** [UPDATE] or [DELETE] statements since the [database connection] was opened.
** ^(The count returned by sqlite3_total_changes() includes all changes
** from all [CREATE TRIGGER | trigger] contexts and changes made by
** [foreign key actions]. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing.  The
** count does not include rows of views that fire an [INSTEAD OF trigger],
** though if the INSTEAD OF trigger makes changes of its own, those changes 
** are counted.)^
** ^The sqlite3_total_changes() function counts the changes as soon as
** the statement that makes them is completed (when the statement handle
** is passed to [sqlite3_reset()] or [sqlite3_finalize()]).
**
** See also the [sqlite3_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
** If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
SQLITE_API int sqlite3_total_changes(sqlite3*);

/*
** CAPI3REF: Interrupt A Long-Running Query
**
** ^This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically
** called in response to a user action such as pressing "Cancel"
** or Ctrl-C where the user wants a long query operation to halt
** immediately.
**
** ^It is safe to call this routine from a thread different from the
** thread that is currently running the database operation.  But it
** is not safe to call this routine with a [database connection] that
** is closed or might close before sqlite3_interrupt() returns.
**
** ^If an SQL operation is very nearly finished at the time when
** sqlite3_interrupt() is called, then it might not have an opportunity
** to be interrupted and might continue to completion.
**
** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT].
** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
** that is inside an explicit transaction, then the entire transaction
** will be rolled back automatically.
**
** ^The sqlite3_interrupt(D) call is in effect until all currently running
** SQL statements on [database connection] D complete.  ^Any new SQL statements
** that are started after the sqlite3_interrupt() call and before the 
** running statements reaches zero are interrupted as if they had been
** running prior to the sqlite3_interrupt() call.  ^New SQL statements
** that are started after the running statement count reaches zero are
** not effected by the sqlite3_interrupt().
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
**
** If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);

/*
** CAPI3REF: Determine If An SQL Statement Is Complete
**
** These routines are useful during command-line input to determine if the
** currently entered text seems to form a complete SQL statement or
** if additional input is needed before sending the text into
** SQLite for parsing.  ^These routines return 1 if the input string
** appears to be a complete SQL statement.  ^A statement is judged to be
** complete if it ends with a semicolon token and is not a prefix of a
** well-formed CREATE TRIGGER statement.  ^Semicolons that are embedded within
** string literals or quoted identifier names or comments are not
** independent tokens (they are part of the token in which they are
** embedded) and thus do not count as a statement terminator.  ^Whitespace
** and comments that follow the final semicolon are ignored.
**
** ^These routines return 0 if the statement is incomplete.  ^If a
** memory allocation fails, then SQLITE_NOMEM is returned.
**
** ^These routines do not parse the SQL statements thus
** will not detect syntactically incorrect SQL.
**
** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior 
** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
** automatically by sqlite3_complete16().  If that initialization fails,
** then the return value from sqlite3_complete16() will be non-zero
** regardless of whether or not the input SQL is complete.)^
**
** The input to [sqlite3_complete()] must be a zero-terminated
** UTF-8 string.
**
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
SQLITE_API int sqlite3_complete(const char *sql);
SQLITE_API int sqlite3_complete16(const void *sql);

/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
**
** ^This routine sets a callback function that might be invoked whenever
** an attempt is made to open a database table that another thread
** or process has locked.
**
** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
** is returned immediately upon encountering the lock.  ^If the busy callback
** is not NULL, then the callback might be invoked with two arguments.
**
** ^The first argument to the busy handler is a copy of the void* pointer which
** is the third argument to sqlite3_busy_handler().  ^The second argument to
** the busy handler callback is the number of times that the busy handler has
** been invoked for this locking event.  ^If the
** busy callback returns 0, then no additional attempts are made to
** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned.
** ^If the callback returns non-zero, then another attempt
** is made to open the database for reading and the cycle repeats.
**
** The presence of a busy handler does not guarantee that it will be invoked
** when there is lock contention. ^If SQLite determines that invoking the busy
** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler.
** Consider a scenario where one process is holding a read lock that
** it is trying to promote to a reserved lock and
** a second process is holding a reserved lock that it is trying
** to promote to an exclusive lock.  The first process cannot proceed
** because it is blocked by the second and the second process cannot
** proceed because it is blocked by the first.  If both processes
** invoke the busy handlers, neither will make any progress.  Therefore,
** SQLite returns [SQLITE_BUSY] for the first process, hoping that this
** will induce the first process to release its read lock and allow
** the second process to proceed.
**
** ^The default busy callback is NULL.
**
** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED]
** when SQLite is in the middle of a large transaction where all the
** changes will not fit into the in-memory cache.  SQLite will
** already hold a RESERVED lock on the database file, but it needs
** to promote this lock to EXCLUSIVE so that it can spill cache
** pages into the database file without harm to concurrent
** readers.  ^If it is unable to promote the lock, then the in-memory
** cache will be left in an inconsistent state and so the error
** code is promoted from the relatively benign [SQLITE_BUSY] to
** the more severe [SQLITE_IOERR_BLOCKED].  ^This error code promotion
** forces an automatic rollback of the changes.  See the
** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
** CorruptionFollowingBusyError</a> wiki page for a discussion of why
** this is important.
**
** ^(There can only be a single busy handler defined for each
** [database connection].  Setting a new busy handler clears any
** previously set handler.)^  ^Note that calling [sqlite3_busy_timeout()]
** will also set or clear the busy handler.
**
** The busy callback should not take any actions which modify the
** database connection that invoked the busy handler.  Any such actions
** result in undefined behavior.
** 
** A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
*/
SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);

/*
** CAPI3REF: Set A Busy Timeout
**
** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
** for a specified amount of time when a table is locked.  ^The handler
** will sleep multiple times until at least "ms" milliseconds of sleeping
** have accumulated.  ^After at least "ms" milliseconds of sleeping,
** the handler returns 0 which causes [sqlite3_step()] to return
** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
**
** ^Calling this routine with an argument less than or equal to zero
** turns off all busy handlers.
**
** ^(There can only be a single busy handler for a particular
** [database connection] any any given moment.  If another busy handler
** was defined  (using [sqlite3_busy_handler()]) prior to calling
** this routine, that other busy handler is cleared.)^
*/
SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);

/*
** CAPI3REF: Convenience Routines For Running Queries
**
** This is a legacy interface that is preserved for backwards compatibility.
** Use of this interface is not recommended.
**
** Definition: A <b>result table</b> is memory data structure created by the
** [sqlite3_get_table()] interface.  A result table records the
** complete query results from one or more queries.
**
** The table conceptually has a number of rows and columns.  But
** these numbers are not part of the result table itself.  These
** numbers are obtained separately.  Let N be the number of rows
** and M be the number of columns.
**
** A result table is an array of pointers to zero-terminated UTF-8 strings.
** There are (N+1)*M elements in the array.  The first M pointers point
** to zero-terminated strings that  contain the names of the columns.
** The remaining entries all point to query results.  NULL values result
** in NULL pointers.  All other values are in their UTF-8 zero-terminated
** string representation as returned by [sqlite3_column_text()].
**
** A result table might consist of one or more memory allocations.
** It is not safe to pass a result table directly to [sqlite3_free()].
** A result table should be deallocated using [sqlite3_free_table()].
**
** ^(As an example of the result table format, suppose a query result
** is as follows:
**
** <blockquote><pre>
**        Name        | Age
**        -----------------------
**        Alice       | 43
**        Bob         | 28
**        Cindy       | 21
** </pre></blockquote>
**
** There are two column (M==2) and three rows (N==3).  Thus the
** result table has 8 entries.  Suppose the result table is stored
** in an array names azResult.  Then azResult holds this content:
**
** <blockquote><pre>
**        azResult&#91;0] = "Name";
**        azResult&#91;1] = "Age";
**        azResult&#91;2] = "Alice";
**        azResult&#91;3] = "43";
**        azResult&#91;4] = "Bob";
**        azResult&#91;5] = "28";
**        azResult&#91;6] = "Cindy";
**        azResult&#91;7] = "21";
** </pre></blockquote>)^
**
** ^The sqlite3_get_table() function evaluates one or more
** semicolon-separated SQL statements in the zero-terminated UTF-8
** string of its 2nd parameter and returns a result table to the
** pointer given in its 3rd parameter.
**
** After the application has finished with the result from sqlite3_get_table(),
** it must pass the result table pointer to sqlite3_free_table() in order to
** release the memory that was malloced.  Because of the way the
** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
** function must not try to call [sqlite3_free()] directly.  Only
** [sqlite3_free_table()] is able to release the memory properly and safely.
**
** The sqlite3_get_table() interface is implemented as a wrapper around
** [sqlite3_exec()].  The sqlite3_get_table() routine does not have access
** to any internal data structures of SQLite.  It uses only the public
** interface defined here.  As a consequence, errors that occur in the
** wrapper layer outside of the internal [sqlite3_exec()] call are not
** reflected in subsequent calls to [sqlite3_errcode()] or
** [sqlite3_errmsg()].
*/
SQLITE_API int sqlite3_get_table(
  sqlite3 *db,          /* An open database */
  const char *zSql,     /* SQL to be evaluated */
  char ***pazResult,    /* Results of the query */
  int *pnRow,           /* Number of result rows written here */
  int *pnColumn,        /* Number of result columns written here */
  char **pzErrmsg       /* Error msg written here */
);
SQLITE_API void sqlite3_free_table(char **result);

/*
** CAPI3REF: Formatted String Printing Functions
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc()].
** The strings returned by these two routines should be
** released by [sqlite3_free()].  ^Both routines return a
** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
** memory to hold the resulting string.
**
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
** the standard C library.  The result is written into the
** buffer supplied as the second parameter whose size is given by
** the first parameter. Note that the order of the
** first two parameters is reversed from snprintf().)^  This is an
** historical accident that cannot be fixed without breaking
** backwards compatibility.  ^(Note also that sqlite3_snprintf()
** returns a pointer to its buffer instead of the number of
** characters actually written into the buffer.)^  We admit that
** the number of characters written would be a more useful return
** value but we cannot change the implementation of sqlite3_snprintf()
** now without breaking compatibility.
**
** ^As long as the buffer size is greater than zero, sqlite3_snprintf()
** guarantees that the buffer is always zero-terminated.  ^The first
** parameter "n" is the total size of the buffer, including space for
** the zero terminator.  So the longest string that can be completely
** written will be n-1 characters.
**
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
**
** These routines all implement some additional formatting
** options that are useful for constructing SQL statements.
** All of the usual printf() formatting options apply.  In addition, there
** is are "%q", "%Q", and "%z" options.
**
** ^(The %q option works like %s in that it substitutes a null-terminated
** string from the argument list.  But %q also doubles every '\'' character.
** %q is designed for use inside a string literal.)^  By doubling each '\''
** character it escapes that character and allows it to be inserted into
** the string.
**
** For example, assume the string variable zText contains text as follows:
**
** <blockquote><pre>
**  char *zText = "It's a happy day!";
** </pre></blockquote>
**
** One can use this text in an SQL statement as follows:
**
** <blockquote><pre>
**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
**  sqlite3_exec(db, zSQL, 0, 0, 0);
**  sqlite3_free(zSQL);
** </pre></blockquote>
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
** <blockquote><pre>
**  INSERT INTO table1 VALUES('It''s a happy day!')
** </pre></blockquote>
**
** This is correct.  Had we used %s instead of %q, the generated SQL
** would have looked like this:
**
** <blockquote><pre>
**  INSERT INTO table1 VALUES('It's a happy day!');
** </pre></blockquote>
**
** This second example is an SQL syntax error.  As a general rule you should
** always use %q instead of %s when inserting text into a string literal.
**
** ^(The %Q option works like %q except it also adds single quotes around
** the outside of the total string.  Additionally, if the parameter in the
** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
** single quotes).)^  So, for example, one could say:
**
** <blockquote><pre>
**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
**  sqlite3_exec(db, zSQL, 0, 0, 0);
**  sqlite3_free(zSQL);
** </pre></blockquote>
**
** The code above will render a correct SQL statement in the zSQL
** variable even if the zText variable is a NULL pointer.
**
** ^(The "%z" formatting option works like "%s" but with the
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string.)^
*/
SQLITE_API char *sqlite3_mprintf(const char*,...);
SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);

/*
** CAPI3REF: Memory Allocation Subsystem
**
** The SQLite core uses these three routines for all of its own
** internal memory allocation needs. "Core" in the previous sentence
** does not include operating-system specific VFS implementation.  The
** Windows VFS uses native malloc() and free() for some operations.
**
** ^The sqlite3_malloc() routine returns a pointer to a block
** of memory at least N bytes in length, where N is the parameter.
** ^If sqlite3_malloc() is unable to obtain sufficient free
** memory, it returns a NULL pointer.  ^If the parameter N to
** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
** a NULL pointer.
**
** ^Calling sqlite3_free() with a pointer previously returned
** by sqlite3_malloc() or sqlite3_realloc() releases that memory so
** that it might be reused.  ^The sqlite3_free() routine is
** a no-op if is called with a NULL pointer.  Passing a NULL pointer
** to sqlite3_free() is harmless.  After being freed, memory
** should neither be read nor written.  Even reading previously freed
** memory might result in a segmentation fault or other severe error.
** Memory corruption, a segmentation fault, or other severe error
** might result if sqlite3_free() is called with a non-NULL pointer that
** was not obtained from sqlite3_malloc() or sqlite3_realloc().
**
** ^(The sqlite3_realloc() interface attempts to resize a
** prior memory allocation to be at least N bytes, where N is the
** second parameter.  The memory allocation to be resized is the first
** parameter.)^ ^ If the first parameter to sqlite3_realloc()
** is a NULL pointer then its behavior is identical to calling
** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc().
** ^If the second parameter to sqlite3_realloc() is zero or
** negative then the behavior is exactly the same as calling
** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
** ^sqlite3_realloc() returns a pointer to a memory allocation
** of at least N bytes in size or NULL if sufficient memory is unavailable.
** ^If M is the size of the prior allocation, then min(N,M) bytes
** of the prior allocation are copied into the beginning of buffer returned
** by sqlite3_realloc() and the prior allocation is freed.
** ^If sqlite3_realloc() returns NULL, then the prior allocation
** is not freed.
**
** ^The memory returned by sqlite3_malloc() and sqlite3_realloc()
** is always aligned to at least an 8 byte boundary, or to a
** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
** option is used.
**
** In SQLite version 3.5.0 and 3.5.1, it was possible to define
** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
** implementation of these routines to be omitted.  That capability
** is no longer provided.  Only built-in memory allocators can be used.
**
** The Windows OS interface layer calls
** the system malloc() and free() directly when converting
** filenames between the UTF-8 encoding used by SQLite
** and whatever filename encoding is used by the particular Windows
** installation.  Memory allocation errors are detected, but
** they are reported back as [SQLITE_CANTOPEN] or
** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
**
** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
** must be either NULL or else pointers obtained from a prior
** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
** not yet been released.
**
** The application must not read or write any part of
** a block of memory after it has been released using
** [sqlite3_free()] or [sqlite3_realloc()].
*/
SQLITE_API void *sqlite3_malloc(int);
SQLITE_API void *sqlite3_realloc(void*, int);
SQLITE_API void sqlite3_free(void*);

/*
** CAPI3REF: Memory Allocator Statistics
**
** SQLite provides these two interfaces for reporting on the status
** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
** routines, which form the built-in memory allocation subsystem.
**
** ^The [sqlite3_memory_used()] routine returns the number of bytes
** of memory currently outstanding (malloced but not freed).
** ^The [sqlite3_memory_highwater()] routine returns the maximum
** value of [sqlite3_memory_used()] since the high-water mark
** was last reset.  ^The values returned by [sqlite3_memory_used()] and
** [sqlite3_memory_highwater()] include any overhead
** added by SQLite in its implementation of [sqlite3_malloc()],
** but not overhead added by the any underlying system library
** routines that [sqlite3_malloc()] may call.
**
** ^The memory high-water mark is reset to the current value of
** [sqlite3_memory_used()] if and only if the parameter to
** [sqlite3_memory_highwater()] is true.  ^The value returned
** by [sqlite3_memory_highwater(1)] is the high-water mark
** prior to the reset.
*/
SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);

/*
** CAPI3REF: Pseudo-Random Number Generator
**
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random [ROWID | ROWIDs] when inserting new records into a table that
** already uses the largest possible [ROWID].  The PRNG is also used for
** the build-in random() and randomblob() SQL functions.  This interface allows
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
**
** ^The first time this routine is invoked (either internally or by
** the application) the PRNG is seeded using randomness obtained
** from the xRandomness method of the default [sqlite3_vfs] object.
** ^On all subsequent invocations, the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
SQLITE_API void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()].  ^At various
** points during the compilation process, as logic is being created
** to perform various actions, the authorizer callback is invoked to
** see if those actions are allowed.  ^The authorizer callback should
** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the
** specific action but allow the SQL statement to continue to be
** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be
** rejected with an error.  ^If the authorizer callback returns
** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
** then the [sqlite3_prepare_v2()] or equivalent call that triggered
** the authorizer will fail with an error message.
**
** When the callback returns [SQLITE_OK], that means the operation
** requested is ok.  ^When the callback returns [SQLITE_DENY], the
** [sqlite3_prepare_v2()] or equivalent call that triggered the
** authorizer will fail with an error message explaining that
** access is denied. 
**
** ^The first parameter to the authorizer callback is a copy of the third
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
** to the callback are zero-terminated strings that contain additional
** details about the action to be authorized.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
** [prepared statement] statement is constructed to substitute
** a NULL value in place of the table column that would have
** been read if [SQLITE_OK] had been returned.  The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
**
** An authorizer is used when [sqlite3_prepare | preparing]
** SQL statements from an untrusted source, to ensure that the SQL statements
** do not try to access data they are not allowed to see, or that they do not
** try to execute malicious statements that damage the database.  For
** example, an application may allow a user to enter arbitrary
** SQL queries for evaluation by a database.  But the application does
** not want the user to be able to make arbitrary changes to the
** database.  An authorizer could then be put in place while the
** user-entered SQL is being [sqlite3_prepare | prepared] that
** disallows everything except [SELECT] statements.
**
** Applications that need to process SQL from untrusted sources
** might also consider lowering resource limits using [sqlite3_limit()]
** and limiting database size using the [max_page_count] [PRAGMA]
** in addition to using an authorizer.
**
** ^(Only a single authorizer can be in place on a database connection
** at a time.  Each call to sqlite3_set_authorizer overrides the
** previous call.)^  ^Disable the authorizer by installing a NULL callback.
** The authorizer is disabled by default.
**
** The authorizer callback must not do anything that will modify
** the database connection that invoked the authorizer callback.
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the
** statement might be re-prepared during [sqlite3_step()] due to a 
** schema change.  Hence, the application should ensure that the
** correct authorizer callback remains in place during the [sqlite3_step()].
**
** ^Note that the authorizer callback is invoked only during
** [sqlite3_prepare()] or its variants.  Authorization is not
** performed during statement evaluation in [sqlite3_step()], unless
** as stated in the previous paragraph, sqlite3_step() invokes
** sqlite3_prepare_v2() to reprepare a statement after a schema change.
*/
SQLITE_API int sqlite3_set_authorizer(
  sqlite3*,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pUserData
);

/*
** CAPI3REF: Authorizer Return Codes
**
** The [sqlite3_set_authorizer | authorizer callback function] must
** return either [SQLITE_OK] or one of these two constants in order
** to signal SQLite whether or not the action is permitted.  See the
** [sqlite3_set_authorizer | authorizer documentation] for additional
** information.
**
** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code]
** from the [sqlite3_vtab_on_conflict()] interface.
*/
#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */

/*
** CAPI3REF: Authorizer Action Codes
**
** The [sqlite3_set_authorizer()] interface registers a callback function
** that is invoked to authorize certain SQL statement actions.  The
** second parameter to the callback is an integer code that specifies
** what action is being authorized.  These are the integer action codes that
** the authorizer callback may be passed.
**
** These action code values signify what kind of operation is to be
** authorized.  The 3rd and 4th parameters to the authorization
** callback function will be parameters or NULL depending on which of these
** codes is used as the second parameter.  ^(The 5th parameter to the
** authorizer callback is the name of the database ("main", "temp",
** etc.) if applicable.)^  ^The 6th parameter to the authorizer callback
** is the name of the inner-most trigger or view that is responsible for
** the access attempt or NULL if this access attempt is directly from
** top-level SQL code.
*/
/******************************************* 3rd ************ 4th ***********/
#define SQLITE_CREATE_INDEX          1   /* Index Name      Table Name      */
#define SQLITE_CREATE_TABLE          2   /* Table Name      NULL            */
#define SQLITE_CREATE_TEMP_INDEX     3   /* Index Name      Table Name      */
#define SQLITE_CREATE_TEMP_TABLE     4   /* Table Name      NULL            */
#define SQLITE_CREATE_TEMP_TRIGGER   5   /* Trigger Name    Table Name      */
#define SQLITE_CREATE_TEMP_VIEW      6   /* View Name       NULL            */
#define SQLITE_CREATE_TRIGGER        7   /* Trigger Name    Table Name      */
#define SQLITE_CREATE_VIEW           8   /* View Name       NULL            */
#define SQLITE_DELETE                9   /* Table Name      NULL            */
#define SQLITE_DROP_INDEX           10   /* Index Name      Table Name      */
#define SQLITE_DROP_TABLE           11   /* Table Name      NULL            */
#define SQLITE_DROP_TEMP_INDEX      12   /* Index Name      Table Name      */
#define SQLITE_DROP_TEMP_TABLE      13   /* Table Name      NULL            */
#define SQLITE_DROP_TEMP_TRIGGER    14   /* Trigger Name    Table Name      */
#define SQLITE_DROP_TEMP_VIEW       15   /* View Name       NULL            */
#define SQLITE_DROP_TRIGGER         16   /* Trigger Name    Table Name      */
#define SQLITE_DROP_VIEW            17   /* View Name       NULL            */
#define SQLITE_INSERT               18   /* Table Name      NULL            */
#define SQLITE_PRAGMA               19   /* Pragma Name     1st arg or NULL */
#define SQLITE_READ                 20   /* Table Name      Column Name     */
#define SQLITE_SELECT               21   /* NULL            NULL            */
#define SQLITE_TRANSACTION          22   /* Operation       NULL            */
#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
#define SQLITE_ATTACH               24   /* Filename        NULL            */
#define SQLITE_DETACH               25   /* Database Name   NULL            */
#define SQLITE_ALTER_TABLE          26   /* Database Name   Table Name      */
#define SQLITE_REINDEX              27   /* Index Name      NULL            */
#define SQLITE_ANALYZE              28   /* Table Name      NULL            */
#define SQLITE_CREATE_VTABLE        29   /* Table Name      Module Name     */
#define SQLITE_DROP_VTABLE          30   /* Table Name      Module Name     */
#define SQLITE_FUNCTION             31   /* NULL            Function Name   */
#define SQLITE_SAVEPOINT            32   /* Operation       Savepoint Name  */
#define SQLITE_COPY                  0   /* No longer used */

/*
** CAPI3REF: Tracing And Profiling Functions
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
**
** ^The callback function registered by sqlite3_trace() is invoked at
** various times when an SQL statement is being run by [sqlite3_step()].
** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the
** SQL statement text as the statement first begins executing.
** ^(Additional sqlite3_trace() callbacks might occur
** as each triggered subprogram is entered.  The callbacks for triggers
** contain a UTF-8 SQL comment that identifies the trigger.)^
**
** ^The callback function registered by sqlite3_profile() is invoked
** as each SQL statement finishes.  ^The profile callback contains
** the original statement text and an estimate of wall-clock time
** of how long that statement took to run.  ^The profile callback
** time is in units of nanoseconds, however the current implementation
** is only capable of millisecond resolution so the six least significant
** digits in the time are meaningless.  Future versions of SQLite
** might provide greater resolution on the profiler callback.  The
** sqlite3_profile() function is considered experimental and is
** subject to change in future versions of SQLite.
*/
SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
   void(*xProfile)(void*,const char*,sqlite3_uint64), void*);

/*
** CAPI3REF: Query Progress Callbacks
**
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
** database connection D.  An example use for this
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the 
** callback function X.  ^The parameter N is the number of 
** [virtual machine instructions] that are evaluated between successive
** invocations of the callback X.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
** old one.  ^Setting parameter X to NULL disables the progress handler.
** ^The progress handler is also disabled by setting N to a value less
** than 1.
**
** ^If the progress callback returns non-zero, the operation is
** interrupted.  This feature can be used to implement a
** "Cancel" button on a GUI progress dialog box.
**
** The progress handler callback must not do anything that will modify
** the database connection that invoked the progress handler.
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
*/
SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);

/*
** CAPI3REF: Opening A New Database Connection
**
** ^These routines open an SQLite database file as specified by the 
** filename argument. ^The filename argument is interpreted as UTF-8 for
** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
** order for sqlite3_open16(). ^(A [database connection] handle is usually
** returned in *ppDb, even if an error occurs.  The only exception is that
** if SQLite is unable to allocate memory to hold the [sqlite3] object,
** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
** object.)^ ^(If the database is opened (and/or created) successfully, then
** [SQLITE_OK] is returned.  Otherwise an [error code] is returned.)^ ^The
** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
** an English language description of the error following a failure of any
** of the sqlite3_open() routines.
**
** ^The default encoding for the database will be UTF-8 if
** sqlite3_open() or sqlite3_open_v2() is called and
** UTF-16 in the native byte order if sqlite3_open16() is used.
**
** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
** passing it to [sqlite3_close()] when it is no longer required.
**
** The sqlite3_open_v2() interface works like sqlite3_open()
** except that it accepts two additional parameters for additional control
** over the new database connection.  ^(The flags parameter to
** sqlite3_open_v2() can take one of
** the following three values, optionally combined with the 
** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^
**
** <dl>
** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
** <dd>The database is opened in read-only mode.  If the database does not
** already exist, an error is returned.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
** <dd>The database is opened for reading and writing if possible, or reading
** only if the file is write protected by the operating system.  In either
** case the database must already exist, otherwise an error is returned.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
** <dd>The database is opened for reading and writing, and is created if
** it does not already exist. This is the behavior that is always used for
** sqlite3_open() and sqlite3_open16().</dd>)^
** </dl>
**
** If the 3rd parameter to sqlite3_open_v2() is not one of the
** combinations shown above optionally combined with other
** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
** then the behavior is undefined.
**
** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
** opens in the multi-thread [threading mode] as long as the single-thread
** mode has not been set at compile-time or start-time.  ^If the
** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
** in the serialized [threading mode] unless single-thread was
** previously selected at compile-time or start-time.
** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
** eligible to use [shared cache mode], regardless of whether or not shared
** cache is enabled using [sqlite3_enable_shared_cache()].  ^The
** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
** participate in [shared cache mode] even if it is enabled.
**
** ^The fourth parameter to sqlite3_open_v2() is the name of the
** [sqlite3_vfs] object that defines the operating system interface that
** the new database connection should use.  ^If the fourth parameter is
** a NULL pointer then the default [sqlite3_vfs] object is used.
**
** ^If the filename is ":memory:", then a private, temporary in-memory database
** is created for the connection.  ^This in-memory database will vanish when
** the database connection is closed.  Future versions of SQLite might
** make use of additional special filenames that begin with the ":" character.
** It is recommended that when a database filename actually does begin with
** a ":" character you should prefix the filename with a pathname such as
** "./" to avoid ambiguity.
**
** ^If the filename is an empty string, then a private, temporary
** on-disk database will be created.  ^This private database will be
** automatically deleted as soon as the database connection is closed.
**
** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3>
**
** ^If [URI filename] interpretation is enabled, and the filename argument
** begins with "file:", then the filename is interpreted as a URI. ^URI
** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
** set in the fourth argument to sqlite3_open_v2(), or if it has
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
** As of SQLite version 3.7.7, URI filename interpretation is turned off
** by default, but future releases of SQLite might enable URI filename
** interpretation by default.  See "[URI filenames]" for additional
** information.
**
** URI filenames are parsed according to RFC 3986. ^If the URI contains an
** authority, then it must be either an empty string or the string 
** "localhost". ^If the authority is not an empty string or "localhost", an 
** error is returned to the caller. ^The fragment component of a URI, if 
** present, is ignored.
**
** ^SQLite uses the path component of the URI as the name of the disk file
** which contains the database. ^If the path begins with a '/' character, 
** then it is interpreted as an absolute path. ^If the path does not begin 
** with a '/' (meaning that the authority section is omitted from the URI)
** then the path is interpreted as a relative path. 
** ^On windows, the first component of an absolute path 
** is a drive specification (e.g. "C:").
**
** [[core URI query parameters]]
** The query component of a URI may contain parameters that are interpreted
** either by SQLite itself, or by a [VFS | custom VFS implementation].
** SQLite interprets the following three query parameters:
**
** <ul>
**   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
**     a VFS object that provides the operating system interface that should
**     be used to access the database file on disk. ^If this option is set to
**     an empty string the default VFS object is used. ^Specifying an unknown
**     VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is
**     present, then the VFS specified by the option takes precedence over
**     the value passed as the fourth parameter to sqlite3_open_v2().
**
**   <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw" or
**     "rwc". Attempting to set it to any other value is an error)^. 
**     ^If "ro" is specified, then the database is opened for read-only 
**     access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the 
**     third argument to sqlite3_prepare_v2(). ^If the mode option is set to 
**     "rw", then the database is opened for read-write (but not create) 
**     access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had 
**     been set. ^Value "rwc" is equivalent to setting both 
**     SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is 
**     used, it is an error to specify a value for the mode parameter that is 
**     less restrictive than that specified by the flags passed as the third 
**     parameter.
**
**   <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
**     "private". ^Setting it to "shared" is equivalent to setting the
**     SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
**     sqlite3_open_v2(). ^Setting the cache parameter to "private" is 
**     equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
**     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
**     a URI filename, its value overrides any behaviour requested by setting
**     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
** </ul>
**
** ^Specifying an unknown parameter in the query component of a URI is not an
** error.  Future versions of SQLite might understand additional query
** parameters.  See "[query parameters with special meaning to SQLite]" for
** additional information.
**
** [[URI filename examples]] <h3>URI filename examples</h3>
**
** <table border="1" align=center cellpadding=5>
** <tr><th> URI filenames <th> Results
** <tr><td> file:data.db <td> 
**          Open the file "data.db" in the current directory.
** <tr><td> file:/home/fred/data.db<br>
**          file:///home/fred/data.db <br> 
**          file://localhost/home/fred/data.db <br> <td> 
**          Open the database file "/home/fred/data.db".
** <tr><td> file://darkstar/home/fred/data.db <td> 
**          An error. "darkstar" is not a recognized authority.
** <tr><td style="white-space:nowrap"> 
**          file:///C:/Documents%20and%20Settings/fred/Desktop/data.db
**     <td> Windows only: Open the file "data.db" on fred's desktop on drive
**          C:. Note that the %20 escaping in this example is not strictly 
**          necessary - space characters can be used literally
**          in URI filenames.
** <tr><td> file:data.db?mode=ro&cache=private <td> 
**          Open file "data.db" in the current directory for read-only access.
**          Regardless of whether or not shared-cache mode is enabled by
**          default, use a private cache.
** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td>
**          Open file "/home/fred/data.db". Use the special VFS "unix-nolock".
** <tr><td> file:data.db?mode=readonly <td> 
**          An error. "readonly" is not a valid option for the "mode" parameter.
** </table>
**
** ^URI hexadecimal escape sequences (%HH) are supported within the path and
** query components of a URI. A hexadecimal escape sequence consists of a
** percent sign - "%" - followed by exactly two hexadecimal digits 
** specifying an octet value. ^Before the path or query components of a
** URI filename are interpreted, they are encoded using UTF-8 and all 
** hexadecimal escape sequences replaced by a single byte containing the
** corresponding octet. If this process generates an invalid UTF-8 encoding,
** the results are undefined.
**
** <b>Note to Windows users:</b>  The encoding used for the filename argument
** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
** codepage is currently defined.  Filenames containing international
** characters must be converted to UTF-8 prior to passing them into
** sqlite3_open() or sqlite3_open_v2().
*/
SQLITE_API int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
SQLITE_API int sqlite3_open16(
  const void *filename,   /* Database filename (UTF-16) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
SQLITE_API int sqlite3_open_v2(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb,         /* OUT: SQLite db handle */
  int flags,              /* Flags */
  const char *zVfs        /* Name of VFS module to use */
);

/*
** CAPI3REF: Obtain Values For URI Parameters
**
** This is a utility routine, useful to VFS implementations, that checks
** to see if a database file was a URI that contained a specific query 
** parameter, and if so obtains the value of the query parameter.
**
** The zFilename argument is the filename pointer passed into the xOpen()
** method of a VFS implementation.  The zParam argument is the name of the
** query parameter we seek.  This routine returns the value of the zParam
** parameter if it exists.  If the parameter does not exist, this routine
** returns a NULL pointer.
**
** If the zFilename argument to this function is not a pointer that SQLite
** passed into the xOpen VFS method, then the behavior of this routine
** is undefined and probably undesirable.
*/
SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);


/*
** CAPI3REF: Error Codes And Messages
**
** ^The sqlite3_errcode() interface returns the numeric [result code] or
** [extended result code] for the most recent failed sqlite3_* API call
** associated with a [database connection]. If a prior API call failed
** but the most recent API call succeeded, the return value from
** sqlite3_errcode() is undefined.  ^The sqlite3_extended_errcode()
** interface is the same except that it always returns the 
** [extended result code] even when extended result codes are
** disabled.
**
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
** text that describes the error, as either UTF-8 or UTF-16 respectively.
** ^(Memory to hold the error message string is managed internally.
** The application does not need to worry about freeing the result.
** However, the error string might be overwritten or deallocated by
** subsequent calls to other SQLite interface functions.)^
**
** When the serialized [threading mode] is in use, it might be the
** case that a second error occurs on a separate thread in between
** the time of the first error and the call to these interfaces.
** When that happens, the second error will be reported since these
** interfaces always report the most recent result.  To avoid
** this, each thread can obtain exclusive use of the [database connection] D
** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
** all calls to the interfaces listed here are completed.
**
** If an interface fails with SQLITE_MISUSE, that means the interface
** was invoked incorrectly by the application.  In that case, the
** error code and message may or may not be set.
*/
SQLITE_API int sqlite3_errcode(sqlite3 *db);
SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
SQLITE_API const char *sqlite3_errmsg(sqlite3*);
SQLITE_API const void *sqlite3_errmsg16(sqlite3*);

/*
** CAPI3REF: SQL Statement Object
** KEYWORDS: {prepared statement} {prepared statements}
**
** An instance of this object represents a single SQL statement.
** This object is variously known as a "prepared statement" or a
** "compiled SQL statement" or simply as a "statement".
**
** The life of a statement object goes something like this:
**
** <ol>
** <li> Create the object using [sqlite3_prepare_v2()] or a related
**      function.
** <li> Bind values to [host parameters] using the sqlite3_bind_*()
**      interfaces.
** <li> Run the SQL by calling [sqlite3_step()] one or more times.
** <li> Reset the statement using [sqlite3_reset()] then go back
**      to step 2.  Do this zero or more times.
** <li> Destroy the object using [sqlite3_finalize()].
** </ol>
**
** Refer to documentation on individual methods above for additional
** information.
*/
typedef struct sqlite3_stmt sqlite3_stmt;

/*
** CAPI3REF: Run-time Limits
**
** ^(This interface allows the size of various constructs to be limited
** on a connection by connection basis.  The first parameter is the
** [database connection] whose limit is to be set or queried.  The
** second parameter is one of the [limit categories] that define a
** class of constructs to be size limited.  The third parameter is the
** new limit for that construct.)^
**
** ^If the new limit is a negative number, the limit is unchanged.
** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a 
** [limits | hard upper bound]
** set at compile-time by a C preprocessor macro called
** [limits | SQLITE_MAX_<i>NAME</i>].
** (The "_LIMIT_" in the name is changed to "_MAX_".))^
** ^Attempts to increase a limit above its hard upper bound are
** silently truncated to the hard upper bound.
**
** ^Regardless of whether or not the limit was changed, the 
** [sqlite3_limit()] interface returns the prior value of the limit.
** ^Hence, to find the current value of a limit without changing it,
** simply invoke this interface with the third parameter set to -1.
**
** Run-time limits are intended for use in applications that manage
** both their own internal database and also databases that are controlled
** by untrusted external sources.  An example application might be a
** web browser that has its own databases for storing history and
** separate databases controlled by JavaScript applications downloaded
** off the Internet.  The internal databases can be given the
** large, default limits.  Databases managed by external sources can
** be given much smaller limits designed to prevent a denial of service
** attack.  Developers might also want to use the [sqlite3_set_authorizer()]
** interface to further control untrusted SQL.  The size of the database
** created by an untrusted script can be contained using the
** [max_page_count] [PRAGMA].
**
** New run-time limit categories may be added in future releases.
*/
SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);

/*
** CAPI3REF: Run-Time Limit Categories
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite3_limit()].
** The synopsis of the meanings of the various limits is shown below.
** Additional information is available at [limits | Limits in SQLite].
**
** <dl>
** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt>
** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
**
** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
**
** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt>
** <dd>The maximum number of columns in a table definition or in the
** result set of a [SELECT] or the maximum number of columns in an index
** or in an ORDER BY or GROUP BY clause.</dd>)^
**
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
** <dd>The maximum depth of the parse tree on any expression.</dd>)^
**
** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
**
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** <dd>The maximum number of instructions in a virtual machine program
** used to implement an SQL statement.  This limit is not currently
** enforced, though that might be added in some future release of
** SQLite.</dd>)^
**
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
**
** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
**
** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]]
** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
** <dd>The maximum length of the pattern argument to the [LIKE] or
** [GLOB] operators.</dd>)^
**
** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH                    0
#define SQLITE_LIMIT_SQL_LENGTH                1
#define SQLITE_LIMIT_COLUMN                    2
#define SQLITE_LIMIT_EXPR_DEPTH                3
#define SQLITE_LIMIT_COMPOUND_SELECT           4
#define SQLITE_LIMIT_VDBE_OP                   5
#define SQLITE_LIMIT_FUNCTION_ARG              6
#define SQLITE_LIMIT_ATTACHED                  7
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
#define SQLITE_LIMIT_VARIABLE_NUMBER           9
#define SQLITE_LIMIT_TRIGGER_DEPTH            10

/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
**
** The first argument, "db", is a [database connection] obtained from a
** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
** [sqlite3_open16()].  The database connection must not have been closed.
**
** The second argument, "zSql", is the statement to be compiled, encoded
** as either UTF-8 or UTF-16.  The sqlite3_prepare() and sqlite3_prepare_v2()
** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
** use UTF-16.
**
** ^If the nByte argument is less than zero, then zSql is read up to the
** first zero terminator. ^If nByte is non-negative, then it is the maximum
** number of  bytes read from zSql.  ^When nByte is non-negative, the
** zSql string ends at either the first '\000' or '\u0000' character or
** the nByte-th byte, whichever comes first. If the caller knows
** that the supplied string is nul-terminated, then there is a small
** performance advantage to be gained by passing an nByte parameter that
** is equal to the number of bytes in the input string <i>including</i>
** the nul-terminator bytes as this saves SQLite from having to
** make a copy of the input string.
**
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
** past the end of the first SQL statement in zSql.  These routines only
** compile the first statement in zSql, so *pzTail is left pointing to
** what remains uncompiled.
**
** ^*ppStmt is left pointing to a compiled [prepared statement] that can be
** executed using [sqlite3_step()].  ^If there is an error, *ppStmt is set
** to NULL.  ^If the input text contains no SQL (if the input is an empty
** string or a comment) then *ppStmt is set to NULL.
** The calling procedure is responsible for deleting the compiled
** SQL statement using [sqlite3_finalize()] after it has finished with it.
** ppStmt may not be NULL.
**
** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
** otherwise an [error code] is returned.
**
** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
** recommended for all new programs. The two older interfaces are retained
** for backwards compatibility, but their use is discouraged.
** ^In the "v2" interfaces, the prepared statement
** that is returned (the [sqlite3_stmt] object) contains a copy of the
** original SQL text. This causes the [sqlite3_step()] interface to
** behave differently in three ways:
**
** <ol>
** <li>
** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
** always used to do, [sqlite3_step()] will automatically recompile the SQL
** statement and try to run it again.
** </li>
**
** <li>
** ^When an error occurs, [sqlite3_step()] will return one of the detailed
** [error codes] or [extended error codes].  ^The legacy behavior was that
** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
** and the application would have to make a second call to [sqlite3_reset()]
** in order to find the underlying cause of the problem. With the "v2" prepare
** interfaces, the underlying reason for the error is returned immediately.
** </li>
**
** <li>
** ^If the specific value bound to [parameter | host parameter] in the 
** WHERE clause might influence the choice of query plan for a statement,
** then the statement will be automatically recompiled, as if there had been 
** a schema change, on the first  [sqlite3_step()] call following any change
** to the [sqlite3_bind_text | bindings] of that [parameter]. 
** ^The specific value of WHERE-clause [parameter] might influence the 
** choice of query plan if the parameter is the left-hand side of a [LIKE]
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
** the 
** </li>
** </ol>
*/
SQLITE_API int sqlite3_prepare(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
SQLITE_API int sqlite3_prepare_v2(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
SQLITE_API int sqlite3_prepare16(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);
SQLITE_API int sqlite3_prepare16_v2(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);

/*
** CAPI3REF: Retrieving Statement SQL
**
** ^This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
*/
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
**
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** and only if the [prepared statement] X makes no direct changes to
** the content of the database file.
**
** Note that [application-defined SQL functions] or
** [virtual tables] might change the database indirectly as a side effect.  
** ^(For example, if an application defines a function "eval()" that 
** calls [sqlite3_exec()], then the following SQL statement would
** change the database file through side-effects:
**
** <blockquote><pre>
**    SELECT eval('DELETE FROM t1') FROM t2;
** </pre></blockquote>
**
** But because the [SELECT] statement does not change the database file
** directly, sqlite3_stmt_readonly() would still return true.)^
**
** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK],
** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true,
** since the statements themselves do not actually modify the database but
** rather they control the timing of when other statements modify the 
** database.  ^The [ATTACH] and [DETACH] statements also cause
** sqlite3_stmt_readonly() to return true since, while those statements
** change the configuration of a database connection, they do not make 
** changes to the content of the database files on disk.
*/
SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Dynamically Typed Value Object
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
**
** SQLite uses the sqlite3_value object to represent all values
** that can be stored in a database table. SQLite uses dynamic typing
** for the values it stores.  ^Values stored in sqlite3_value objects
** can be integers, floating point values, strings, BLOBs, or NULL.
**
** An sqlite3_value object may be either "protected" or "unprotected".
** Some interfaces require a protected sqlite3_value.  Other interfaces
** will accept either a protected or an unprotected sqlite3_value.
** Every interface that accepts sqlite3_value arguments specifies
** whether or not it requires a protected sqlite3_value.
**
** The terms "protected" and "unprotected" refer to whether or not
** a mutex is held.  An internal mutex is held for a protected
** sqlite3_value object but no mutex is held for an unprotected
** sqlite3_value object.  If SQLite is compiled to be single-threaded
** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
** or if SQLite is run in one of reduced mutex modes 
** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
** then there is no distinction between protected and unprotected
** sqlite3_value objects and they can be used interchangeably.  However,
** for maximum code portability it is recommended that applications
** still make the distinction between protected and unprotected
** sqlite3_value objects even when not strictly required.
**
** ^The sqlite3_value objects that are passed as parameters into the
** implementation of [application-defined SQL functions] are protected.
** ^The sqlite3_value object returned by
** [sqlite3_column_value()] is unprotected.
** Unprotected sqlite3_value objects may only be used with
** [sqlite3_result_value()] and [sqlite3_bind_value()].
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
typedef struct Mem sqlite3_value;

/*
** CAPI3REF: SQL Function Context Object
**
** The context in which an SQL function executes is stored in an
** sqlite3_context object.  ^A pointer to an sqlite3_context object
** is always first parameter to [application-defined SQL functions].
** The application-defined SQL function implementation will pass this
** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
** [sqlite3_aggregate_context()], [sqlite3_user_data()],
** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
** and/or [sqlite3_set_auxdata()].
*/
typedef struct sqlite3_context sqlite3_context;

/*
** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
**
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following
** templates:
**
** <ul>
** <li>  ?
** <li>  ?NNN
** <li>  :VVV
** <li>  @VVV
** <li>  $VVV
** </ul>
**
** In the templates above, NNN represents an integer literal,
** and VVV represents an alphanumeric identifier.)^  ^The values of these
** parameters (also called "host parameter names" or "SQL parameters")
** can be set using the sqlite3_bind_*() routines defined here.
**
** ^The first argument to the sqlite3_bind_*() routines is always
** a pointer to the [sqlite3_stmt] object returned from
** [sqlite3_prepare_v2()] or its variants.
**
** ^The second argument is the index of the SQL parameter to be set.
** ^The leftmost SQL parameter has an index of 1.  ^When the same named
** SQL parameter is used more than once, second and subsequent
** occurrences have the same index as the first occurrence.
** ^The index for named parameters can be looked up using the
** [sqlite3_bind_parameter_index()] API if desired.  ^The index
** for "?NNN" parameters is the value of NNN.
** ^The NNN value must be between 1 and the [sqlite3_limit()]
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
**
** ^The third argument is the value to bind to the parameter.
**
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter.  To be clear: the value is the
** number of <u>bytes</u> in the value, not the number of characters.)^
** ^If the fourth parameter is negative, the length of the string is
** the number of bytes up to the first zero terminator.
** If a non-negative fourth parameter is provided to sqlite3_bind_text()
** or sqlite3_bind_text16() then that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated.  If any NUL characters occur at byte offsets less than 
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs.  The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it.  ^The destructor is called
** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
** sqlite3_bind_text(), or sqlite3_bind_text16() fails.  
** ^If the fifth argument is
** the special value [SQLITE_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
**
** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
** (just an integer to hold its size) while it is being processed.
** Zeroblobs are intended to serve as placeholders for BLOBs whose
** content is later written using
** [sqlite3_blob_open | incremental BLOB I/O] routines.
** ^A negative value for the zeroblob results in a zero-length BLOB.
**
** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
** for the [prepared statement] or with a prepared statement for which
** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
** then the call will return [SQLITE_MISUSE].  If any sqlite3_bind_()
** routine is passed a [prepared statement] that has been finalized, the
** result is undefined and probably harmful.
**
** ^Bindings are not cleared by the [sqlite3_reset()] routine.
** ^Unbound parameters are interpreted as NULL.
**
** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
** [error code] if anything goes wrong.
** ^[SQLITE_RANGE] is returned if the parameter
** index is out of range.  ^[SQLITE_NOMEM] is returned if malloc() fails.
**
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
*/
SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);

/*
** CAPI3REF: Number Of SQL Parameters
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement].  SQL parameters are tokens of the
** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
** placeholders for values that are [sqlite3_bind_blob | bound]
** to the parameters at a later time.
**
** ^(This routine actually returns the index of the largest (rightmost)
** parameter. For all forms except ?NNN, this will correspond to the
** number of unique parameters.  If parameters of the ?NNN form are used,
** there may be gaps in the list.)^
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);

/*
** CAPI3REF: Name Of A Host Parameter
**
** ^The sqlite3_bind_parameter_name(P,N) interface returns
** the name of the N-th [SQL parameter] in the [prepared statement] P.
** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
** respectively.
** In other words, the initial ":" or "$" or "@" or "?"
** is included as part of the name.)^
** ^Parameters of the form "?" without a following integer have no name
** and are referred to as "nameless" or "anonymous parameters".
**
** ^The first host parameter has an index of 1, not 0.
**
** ^If the value N is out of range or if the N-th parameter is
** nameless, then NULL is returned.  ^The returned string is
** always in UTF-8 encoding even if the named parameter was
** originally specified as UTF-16 in [sqlite3_prepare16()] or
** [sqlite3_prepare16_v2()].
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);

/*
** CAPI3REF: Index Of A Parameter With A Given Name
**
** ^Return the index of an SQL parameter given its name.  ^The
** index value returned is suitable for use as the second
** parameter to [sqlite3_bind_blob|sqlite3_bind()].  ^A zero
** is returned if no matching parameter is found.  ^The parameter
** name must be given in UTF-8 even if the original statement
** was prepared from UTF-16 text using [sqlite3_prepare16_v2()].
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);

/*
** CAPI3REF: Reset All Bindings On A Prepared Statement
**
** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
** the [sqlite3_bind_blob | bindings] on a [prepared statement].
** ^Use this routine to reset all host parameters to NULL.
*/
SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);

/*
** CAPI3REF: Number Of Columns In A Result Set
**
** ^Return the number of columns in the result set returned by the
** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
** statement that does not return data (for example an [UPDATE]).
**
** See also: [sqlite3_data_count()]
*/
SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Column Names In A Result Set
**
** ^These routines return the name assigned to a particular column
** in the result set of a [SELECT] statement.  ^The sqlite3_column_name()
** interface returns a pointer to a zero-terminated UTF-8 string
** and sqlite3_column_name16() returns a pointer to a zero-terminated
** UTF-16 string.  ^The first parameter is the [prepared statement]
** that implements the [SELECT] statement. ^The second parameter is the
** column number.  ^The leftmost column is number 0.
**
** ^The returned string pointer is valid until either the [prepared statement]
** is destroyed by [sqlite3_finalize()] or until the statement is automatically
** reprepared by the first call to [sqlite3_step()] for a particular run
** or until the next call to
** sqlite3_column_name() or sqlite3_column_name16() on the same column.
**
** ^If sqlite3_malloc() fails during the processing of either routine
** (for example during a conversion from UTF-8 to UTF-16) then a
** NULL pointer is returned.
**
** ^The name of a result column is the value of the "AS" clause for
** that column, if there is an AS clause.  If there is no AS clause
** then the name of the column is unspecified and may change from
** one release of SQLite to the next.
*/
SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);

/*
** CAPI3REF: Source Of Data In A Query Result
**
** ^These routines provide a means to determine the database, table, and
** table column that is the origin of a particular result column in
** [SELECT] statement.
** ^The name of the database or table or column can be returned as
** either a UTF-8 or UTF-16 string.  ^The _database_ routines return
** the database name, the _table_ routines return the table name, and
** the origin_ routines return the column name.
** ^The returned string is valid until the [prepared statement] is destroyed
** using [sqlite3_finalize()] or until the statement is automatically
** reprepared by the first call to [sqlite3_step()] for a particular run
** or until the same information is requested
** again in a different encoding.
**
** ^The names returned are the original un-aliased names of the
** database, table, and column.
**
** ^The first argument to these interfaces is a [prepared statement].
** ^These functions return information about the Nth result column returned by
** the statement, where N is the second function argument.
** ^The left-most column is column 0 for these routines.
**
** ^If the Nth column returned by the statement is an expression or
** subquery and is not a column value, then all of these functions return
** NULL.  ^These routine might also return NULL if a memory allocation error
** occurs.  ^Otherwise, they return the name of the attached database, table,
** or column that query result column was extracted from.
**
** ^As with all other SQLite APIs, those whose names end with "16" return
** UTF-16 encoded strings and the other functions return UTF-8.
**
** ^These APIs are only available if the library was compiled with the
** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol.
**
** If two or more threads call one or more of these routines against the same
** prepared statement and column at the same time then the results are
** undefined.
**
** If two or more threads call one or more
** [sqlite3_column_database_name | column metadata interfaces]
** for the same [prepared statement] and result column
** at the same time then the results are undefined.
*/
SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);

/*
** CAPI3REF: Declared Datatype Of A Query Result
**
** ^(The first parameter is a [prepared statement].
** If this statement is a [SELECT] statement and the Nth column of the
** returned result set of that [SELECT] is a table column (not an
** expression or subquery) then the declared type of the table
** column is returned.)^  ^If the Nth column of the result set is an
** expression or subquery, then a NULL pointer is returned.
** ^The returned string is always UTF-8 encoded.
**
** ^(For example, given the database schema:
**
** CREATE TABLE t1(c1 VARIANT);
**
** and the following statement to be compiled:
**
** SELECT c1 + 1, c1 FROM t1;
**
** this routine would return the string "VARIANT" for the second result
** column (i==1), and a NULL pointer for the first result column (i==0).)^
**
** ^SQLite uses dynamic run-time typing.  ^So just because a column
** is declared to contain a particular type does not mean that the
** data stored in that column is of the declared type.  SQLite is
** strongly typed, but the typing is dynamic not static.  ^Type
** is associated with individual values, not with the containers
** used to hold those values.
*/
SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);

/*
** CAPI3REF: Evaluate An SQL Statement
**
** After a [prepared statement] has been prepared using either
** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
** must be called one or more times to evaluate the statement.
**
** The details of the behavior of the sqlite3_step() interface depend
** on whether the statement was prepared using the newer "v2" interface
** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
** interface [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
** new "v2" interface is recommended for new applications but the legacy
** interface will continue to be supported.
**
** ^In the legacy interface, the return value will be either [SQLITE_BUSY],
** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
** ^With the "v2" interface, any of the other [result codes] or
** [extended result codes] might be returned as well.
**
** ^[SQLITE_BUSY] means that the database engine was unable to acquire the
** database locks it needs to do its job.  ^If the statement is a [COMMIT]
** or occurs outside of an explicit transaction, then you can retry the
** statement.  If the statement is not a [COMMIT] and occurs within an
** explicit transaction then you should rollback the transaction before
** continuing.
**
** ^[SQLITE_DONE] means that the statement has finished executing
** successfully.  sqlite3_step() should not be called again on this virtual
** machine without first calling [sqlite3_reset()] to reset the virtual
** machine back to its initial state.
**
** ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
** is returned each time a new row of data is ready for processing by the
** caller. The values may be accessed using the [column access functions].
** sqlite3_step() is called again to retrieve the next row of data.
**
** ^[SQLITE_ERROR] means that a run-time error (such as a constraint
** violation) has occurred.  sqlite3_step() should not be called again on
** the VM. More information may be found by calling [sqlite3_errmsg()].
** ^With the legacy interface, a more specific error code (for example,
** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
** can be obtained by calling [sqlite3_reset()] on the
** [prepared statement].  ^In the "v2" interface,
** the more specific error code is returned directly by sqlite3_step().
**
** [SQLITE_MISUSE] means that the this routine was called inappropriately.
** Perhaps it was called on a [prepared statement] that has
** already been [sqlite3_finalize | finalized] or on one that had
** previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
** be the case that the same database connection is being used by two or
** more threads at the same moment in time.
**
** For all versions of SQLite up to and including 3.6.23.1, a call to
** [sqlite3_reset()] was required after sqlite3_step() returned anything
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step().  Failure to reset the prepared statement using 
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
** sqlite3_step().  But after version 3.6.23.1, sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE].  This is not considered a compatibility
** break because any application that ever receives an SQLITE_MISUSE error
** is broken by definition.  The [SQLITE_OMIT_AUTORESET] compile-time option
** can be used to restore the legacy behavior.
**
** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
** API always returns a generic error code, [SQLITE_ERROR], following any
** error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
** specific [error codes] that better describes the error.
** We admit that this is a goofy design.  The problem has been fixed
** with the "v2" interface.  If you prepare all of your SQL statements
** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
** then the more specific [error codes] are returned directly
** by sqlite3_step().  The use of the "v2" interface is recommended.
*/
SQLITE_API int sqlite3_step(sqlite3_stmt*);

/*
** CAPI3REF: Number of columns in a result set
**
** ^The sqlite3_data_count(P) interface returns the number of columns in the
** current row of the result set of [prepared statement] P.
** ^If prepared statement P does not have results ready to return
** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
** interfaces) then sqlite3_data_count(P) returns 0.
** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
** [sqlite3_step](P) returned [SQLITE_DONE].  ^The sqlite3_data_count(P)
** will return non-zero if previous call to [sqlite3_step](P) returned
** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
** where it always returns zero since each step of that multi-step
** pragma returns 0 columns of data.
**
** See also: [sqlite3_column_count()]
*/
SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Fundamental Datatypes
** KEYWORDS: SQLITE_TEXT
**
** ^(Every value in SQLite has one of five fundamental datatypes:
**
** <ul>
** <li> 64-bit signed integer
** <li> 64-bit IEEE floating point number
** <li> string
** <li> BLOB
** <li> NULL
** </ul>)^
**
** These constants are codes for each of those types.
**
** Note that the SQLITE_TEXT constant was also used in SQLite version 2
** for a completely different meaning.  Software that links against both
** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
** SQLITE_TEXT.
*/
#define SQLITE_INTEGER  1
#define SQLITE_FLOAT    2
#define SQLITE_BLOB     4
#define SQLITE_NULL     5
#ifdef SQLITE_TEXT
# undef SQLITE_TEXT
#else
# define SQLITE_TEXT     3
#endif
#define SQLITE3_TEXT     3

/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
**
** These routines form the "result set" interface.
**
** ^These routines return information about a single column of the current
** result row of a query.  ^In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
** and the second argument is the index of the column for which information
** should be returned. ^The leftmost column of the result set has the index 0.
** ^The number of columns in the result can be determined using
** [sqlite3_column_count()].
**
** If the SQL statement does not currently point to a valid row, or if the
** column index is out of range, the result is undefined.
** These routines may only be called when the most recent call to
** [sqlite3_step()] has returned [SQLITE_ROW] and neither
** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
** If any of these routines are called after [sqlite3_reset()] or
** [sqlite3_finalize()] or after [sqlite3_step()] has returned
** something other than [SQLITE_ROW], the results are undefined.
** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
** are called from a different thread while any of these routines
** are pending, then the results are undefined.
**
** ^The sqlite3_column_type() routine returns the
** [SQLITE_INTEGER | datatype code] for the initial data type
** of the result column.  ^The returned value is one of [SQLITE_INTEGER],
** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].  The value
** returned by sqlite3_column_type() is only meaningful if no type
** conversions have occurred as described below.  After a type conversion,
** the value returned by sqlite3_column_type() is undefined.  Future
** versions of SQLite may change the behavior of sqlite3_column_type()
** following a type conversion.
**
** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
** routine returns the number of bytes in that BLOB or string.
** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
** the string to UTF-8 and then returns the number of bytes.
** ^If the result is a numeric value then sqlite3_column_bytes() uses
** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
** the number of bytes in that string.
** ^If the result is NULL, then sqlite3_column_bytes() returns zero.
**
** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16()
** routine returns the number of bytes in that BLOB or string.
** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts
** the string to UTF-16 and then returns the number of bytes.
** ^If the result is a numeric value then sqlite3_column_bytes16() uses
** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns
** the number of bytes in that string.
** ^If the result is NULL, then sqlite3_column_bytes16() returns zero.
**
** ^The values returned by [sqlite3_column_bytes()] and 
** [sqlite3_column_bytes16()] do not include the zero terminators at the end
** of the string.  ^For clarity: the values returned by
** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
** bytes in the string, not the number of characters.
**
** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
** even empty strings, are always zero terminated.  ^The return
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
**
** ^The object returned by [sqlite3_column_value()] is an
** [unprotected sqlite3_value] object.  An unprotected sqlite3_value object
** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
** If the [unprotected sqlite3_value] object returned by
** [sqlite3_column_value()] is used in any other way, including calls
** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
** or [sqlite3_value_bytes()], then the behavior is undefined.
**
** These routines attempt to convert the value where appropriate.  ^For
** example, if the internal representation is FLOAT and a text result
** is requested, [sqlite3_snprintf()] is used internally to perform the
** conversion automatically.  ^(The following table details the conversions
** that are applied:
**
** <blockquote>
** <table border="1">
** <tr><th> Internal<br>Type <th> Requested<br>Type <th>  Conversion
**
** <tr><td>  NULL    <td> INTEGER   <td> Result is 0
** <tr><td>  NULL    <td>  FLOAT    <td> Result is 0.0
** <tr><td>  NULL    <td>   TEXT    <td> Result is NULL pointer
** <tr><td>  NULL    <td>   BLOB    <td> Result is NULL pointer
** <tr><td> INTEGER  <td>  FLOAT    <td> Convert from integer to float
** <tr><td> INTEGER  <td>   TEXT    <td> ASCII rendering of the integer
** <tr><td> INTEGER  <td>   BLOB    <td> Same as INTEGER->TEXT
** <tr><td>  FLOAT   <td> INTEGER   <td> Convert from float to integer
** <tr><td>  FLOAT   <td>   TEXT    <td> ASCII rendering of the float
** <tr><td>  FLOAT   <td>   BLOB    <td> Same as FLOAT->TEXT
** <tr><td>  TEXT    <td> INTEGER   <td> Use atoi()
** <tr><td>  TEXT    <td>  FLOAT    <td> Use atof()
** <tr><td>  TEXT    <td>   BLOB    <td> No change
** <tr><td>  BLOB    <td> INTEGER   <td> Convert to TEXT then use atoi()
** <tr><td>  BLOB    <td>  FLOAT    <td> Convert to TEXT then use atof()
** <tr><td>  BLOB    <td>   TEXT    <td> Add a zero terminator if needed
** </table>
** </blockquote>)^
**
** The table above makes reference to standard C library functions atoi()
** and atof().  SQLite does not really use these functions.  It has its
** own equivalent internal routines.  The atoi() and atof() names are
** used in the table for brevity and because they are familiar to most
** C programmers.
**
** Note that when type conversions occur, pointers returned by prior
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
** sqlite3_column_text16() may be invalidated.
** Type conversions and pointer invalidations might occur
** in the following cases:
**
** <ul>
** <li> The initial content is a BLOB and sqlite3_column_text() or
**      sqlite3_column_text16() is called.  A zero-terminator might
**      need to be added to the string.</li>
** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
**      sqlite3_column_text16() is called.  The content must be converted
**      to UTF-16.</li>
** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
**      sqlite3_column_text() is called.  The content must be converted
**      to UTF-8.</li>
** </ul>
**
** ^Conversions between UTF-16be and UTF-16le are always done in place and do
** not invalidate a prior pointer, though of course the content of the buffer
** that the prior pointer references will have been modified.  Other kinds
** of conversion are done in place when it is possible, but sometimes they
** are not possible and in those cases prior pointers are invalidated.
**
** The safest and easiest to remember policy is to invoke these routines
** in one of the following ways:
**
** <ul>
**  <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
**  <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
**  <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
** </ul>
**
** In other words, you should call sqlite3_column_text(),
** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
** into the desired format, then invoke sqlite3_column_bytes() or
** sqlite3_column_bytes16() to find the size of the result.  Do not mix calls
** to sqlite3_column_text() or sqlite3_column_blob() with calls to
** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
** with calls to sqlite3_column_bytes().
**
** ^The pointers returned are valid until a type conversion occurs as
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
** [sqlite3_finalize()] is called.  ^The memory space used to hold strings
** and BLOBs is freed automatically.  Do <b>not</b> pass the pointers returned
** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
** ^(If a memory allocation error occurs during the evaluation of any
** of these routines, a default value is returned.  The default value
** is either the integer 0, the floating point number 0.0, or a NULL
** pointer.  Subsequent calls to [sqlite3_errcode()] will return
** [SQLITE_NOMEM].)^
*/
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);

/*
** CAPI3REF: Destroy A Prepared Statement Object
**
** ^The sqlite3_finalize() function is called to delete a [prepared statement].
** ^If the most recent evaluation of the statement encountered no errors
** or if the statement is never been evaluated, then sqlite3_finalize() returns
** SQLITE_OK.  ^If the most recent evaluation of statement S failed, then
** sqlite3_finalize(S) returns the appropriate [error code] or
** [extended error code].
**
** ^The sqlite3_finalize(S) routine can be called at any point during
** the life cycle of [prepared statement] S:
** before statement S is ever evaluated, after
** one or more calls to [sqlite3_reset()], or after any call
** to [sqlite3_step()] regardless of whether or not the statement has
** completed execution.
**
** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
**
** The application must finalize every [prepared statement] in order to avoid
** resource leaks.  It is a grievous error for the application to try to use
** a prepared statement after it has been finalized.  Any use of a prepared
** statement after it has been finalized can result in undefined and
** undesirable behavior such as segfaults and heap corruption.
*/
SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Reset A Prepared Statement Object
**
** The sqlite3_reset() function is called to reset a [prepared statement]
** object back to its initial state, ready to be re-executed.
** ^Any SQL statement variables that had values bound to them using
** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
** Use [sqlite3_clear_bindings()] to reset the bindings.
**
** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S
** back to the beginning of its program.
**
** ^If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
** or if [sqlite3_step(S)] has never before been called on S,
** then [sqlite3_reset(S)] returns [SQLITE_OK].
**
** ^If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S indicated an error, then
** [sqlite3_reset(S)] returns an appropriate [error code].
**
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Create Or Redefine SQL Functions
** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
** of existing SQL functions or aggregates.  The only differences between
** these routines are the text encoding expected for
** the second parameter (the name of the function being created)
** and the presence or absence of a destructor callback for
** the application data pointer.
**
** ^The first parameter is the [database connection] to which the SQL
** function is to be added.  ^If an application uses more than one database
** connection then application-defined SQL functions must be added
** to each database connection separately.
**
** ^The second parameter is the name of the SQL function to be created or
** redefined.  ^The length of the name is limited to 255 bytes in a UTF-8
** representation, exclusive of the zero-terminator.  ^Note that the name
** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.  
** ^Any attempt to create a function with a longer name
** will result in [SQLITE_MISUSE] being returned.
**
** ^The third parameter (nArg)
** is the number of arguments that the SQL function or
** aggregate takes. ^If this parameter is -1, then the SQL function or
** aggregate may take any number of arguments between 0 and the limit
** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]).  If the third
** parameter is less than -1 or greater than 127 then the behavior is
** undefined.
**
** ^The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
** its parameters.  Every SQL function implementation must be able to work
** with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
** more efficient with one encoding than another.  ^An application may
** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
** times with the same function but with different values of eTextRep.
** ^When multiple implementations of the same function are available, SQLite
** will pick the one that involves the least amount of data conversion.
** If there is only a single implementation which does not care what text
** encoding is used, then the fourth argument should be [SQLITE_ANY].
**
** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
**
** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
** pointers to C-language functions that implement the SQL function or
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
** callback only; NULL pointers must be passed as the xStep and xFinal
** parameters. ^An aggregate SQL function requires an implementation of xStep
** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
** SQL function or aggregate, pass NULL pointers for all three function
** callbacks.
**
** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
** then it is destructor for the application data pointer. 
** The destructor is invoked when the function is deleted, either by being
** overloaded or when the database connection closes.)^
** ^The destructor is also invoked if the call to
** sqlite3_create_function_v2() fails.
** ^When the destructor callback of the tenth parameter is invoked, it
** is passed a single argument which is a copy of the application data 
** pointer which was the fifth parameter to sqlite3_create_function_v2().
**
** ^It is permitted to register multiple implementations of the same
** functions with the same name but with either differing numbers of
** arguments or differing preferred text encodings.  ^SQLite will use
** the implementation that most closely matches the way in which the
** SQL function is used.  ^A function implementation with a non-negative
** nArg parameter is a better match than a function implementation with
** a negative nArg.  ^A function where the preferred text encoding
** matches the database encoding is a better
** match than a function where the encoding is different.  
** ^A function where the encoding difference is between UTF16le and UTF16be
** is a closer match than a function where the encoding difference is
** between UTF8 and UTF16.
**
** ^Built-in functions may be overloaded by new application-defined functions.
**
** ^An application-defined function is permitted to call other
** SQLite interfaces.  However, such calls must not
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
SQLITE_API int sqlite3_create_function(
  sqlite3 *db,
  const char *zFunctionName,
  int nArg,
  int eTextRep,
  void *pApp,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
);
SQLITE_API int sqlite3_create_function16(
  sqlite3 *db,
  const void *zFunctionName,
  int nArg,
  int eTextRep,
  void *pApp,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
);
SQLITE_API int sqlite3_create_function_v2(
  sqlite3 *db,
  const char *zFunctionName,
  int nArg,
  int eTextRep,
  void *pApp,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*),
  void(*xDestroy)(void*)
);

/*
** CAPI3REF: Text Encodings
**
** These constant define integer codes that represent the various
** text encodings supported by SQLite.
*/
#define SQLITE_UTF8           1
#define SQLITE_UTF16LE        2
#define SQLITE_UTF16BE        3
#define SQLITE_UTF16          4    /* Use native byte order */
#define SQLITE_ANY            5    /* sqlite3_create_function only */
#define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */

/*
** CAPI3REF: Deprecated Functions
** DEPRECATED
**
** These functions are [deprecated].  In order to maintain
** backwards compatibility with older code, these functions continue 
** to be supported.  However, new applications should avoid
** the use of these functions.  To help encourage people to avoid
** using these functions, we are not going to tell you what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
#endif

/*
** CAPI3REF: Obtaining SQL Function Parameter Values
**
** The C-language implementation of SQL functions and aggregates uses
** this set of interface routines to access the parameter values on
** the function or aggregate.
**
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
** define callbacks that implement the SQL functions and aggregates.
** The 3rd parameter to these callbacks is an array of pointers to
** [protected sqlite3_value] objects.  There is one [sqlite3_value] object for
** each parameter to the SQL function.  These routines are used to
** extract values from the [sqlite3_value] objects.
**
** These routines work only with [protected sqlite3_value] objects.
** Any attempt to use these routines on an [unprotected sqlite3_value]
** object results in undefined behavior.
**
** ^These routines work just like the corresponding [column access functions]
** except that  these routines take a single [protected sqlite3_value] object
** pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
**
** ^The sqlite3_value_text16() interface extracts a UTF-16 string
** in the native byte-order of the host machine.  ^The
** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
** extract UTF-16 strings as big-endian and little-endian respectively.
**
** ^(The sqlite3_value_numeric_type() interface attempts to apply
** numeric affinity to the value.  This means that an attempt is
** made to convert the value to an integer or floating point.  If
** such a conversion is possible without loss of information (in other
** words, if the value is a string that looks like a number)
** then the conversion is performed.  Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
** or [sqlite3_value_text16()].
**
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
*/
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
SQLITE_API double sqlite3_value_double(sqlite3_value*);
SQLITE_API int sqlite3_value_int(sqlite3_value*);
SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);

/*
** CAPI3REF: Obtain Aggregate Function Context
**
** Implementations of aggregate SQL functions use this
** routine to allocate memory for storing their state.
**
** ^The first time the sqlite3_aggregate_context(C,N) routine is called 
** for a particular aggregate function, SQLite
** allocates N of memory, zeroes out that memory, and returns a pointer
** to the new memory. ^On second and subsequent calls to
** sqlite3_aggregate_context() for the same aggregate function instance,
** the same buffer is returned.  Sqlite3_aggregate_context() is normally
** called once for each invocation of the xStep callback and then one
** last time when the xFinal callback is invoked.  ^(When no rows match
** an aggregate query, the xStep() callback of the aggregate function
** implementation is never called and xFinal() is called exactly once.
** In those cases, sqlite3_aggregate_context() might be called for the
** first time from within xFinal().)^
**
** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is
** less than or equal to zero or if a memory allocate error occurs.
**
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call.  Changing the
** value of N in subsequent call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory
** allocation.)^
**
** ^SQLite automatically frees the memory allocated by 
** sqlite3_aggregate_context() when the aggregate query concludes.
**
** The first parameter must be a copy of the
** [sqlite3_context | SQL function context] that is the first parameter
** to the xStep or xFinal callback routine that implements the aggregate
** function.
**
** This routine must be called from the same thread in which
** the aggregate SQL function is running.
*/
SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);

/*
** CAPI3REF: User Data For Functions
**
** ^The sqlite3_user_data() interface returns a copy of
** the pointer that was the pUserData parameter (the 5th parameter)
** of the [sqlite3_create_function()]
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
**
** This routine must be called from the same thread in which
** the application-defined function is running.
*/
SQLITE_API void *sqlite3_user_data(sqlite3_context*);

/*
** CAPI3REF: Database Connection For Functions
**
** ^The sqlite3_context_db_handle() interface returns a copy of
** the pointer to the [database connection] (the 1st parameter)
** of the [sqlite3_create_function()]
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
*/
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);

/*
** CAPI3REF: Function Auxiliary Data
**
** The following two functions may be used by scalar SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. This may
** be used, for example, to add a regular-expression matching scalar
** function. The compiled version of the regular expression is stored as
** metadata associated with the SQL value passed as the regular expression
** pattern.  The compiled regular expression can be reused on multiple
** invocations of the same function so that the original pattern string
** does not need to be recompiled on each invocation.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If no metadata has been ever
** been set for the Nth argument of the function, or if the corresponding
** function parameter has changed since the meta-data was set,
** then sqlite3_get_auxdata() returns a NULL pointer.
**
** ^The sqlite3_set_auxdata() interface saves the metadata
** pointed to by its 3rd parameter as the metadata for the N-th
** argument of the application-defined function.  Subsequent
** calls to sqlite3_get_auxdata() might return this data, if it has
** not been destroyed.
** ^If it is not NULL, SQLite will invoke the destructor
** function given by the 4th parameter to sqlite3_set_auxdata() on
** the metadata when the corresponding function parameter changes
** or when the SQL statement completes, whichever comes first.
**
** SQLite is free to call the destructor and drop metadata on any
** parameter of any function at any time.  ^The only guarantee is that
** the destructor will be called before the metadata is dropped.
**
** ^(In practice, metadata is preserved between function calls for
** expressions that are constant at compile time. This includes literal
** values and [parameters].)^
**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));


/*
** CAPI3REF: Constants Defining Special Destructor Behavior
**
** These are special values for the destructor that is passed in as the
** final argument to routines like [sqlite3_result_blob()].  ^If the destructor
** argument is SQLITE_STATIC, it means that the content pointer is constant
** and will never change.  It does not need to be destroyed.  ^The
** SQLITE_TRANSIENT value means that the content will likely change in
** the near future and that SQLite should make its own private copy of
** the content before returning.
**
** The typedef is necessary to work around problems in certain
** C++ compilers.  See ticket #2191.
*/
typedef void (*sqlite3_destructor_type)(void*);
#define SQLITE_STATIC      ((sqlite3_destructor_type)0)
#define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)

/*
** CAPI3REF: Setting The Result Of An SQL Function
**
** These routines are used by the xFunc or xFinal callbacks that
** implement SQL functions and aggregates.  See
** [sqlite3_create_function()] and [sqlite3_create_function16()]
** for additional information.
**
** These functions work very much like the [parameter binding] family of
** functions used to bind values to host parameters in prepared statements.
** Refer to the [SQL parameter] documentation for additional information.
**
** ^The sqlite3_result_blob() interface sets the result from
** an application-defined function to be the BLOB whose content is pointed
** to by the second parameter and which is N bytes long where N is the
** third parameter.
**
** ^The sqlite3_result_zeroblob() interfaces set the result of
** the application-defined function to be a BLOB containing all zero
** bytes and N bytes in size, where N is the value of the 2nd parameter.
**
** ^The sqlite3_result_double() interface sets the result from
** an application-defined function to be a floating point value specified
** by its 2nd argument.
**
** ^The sqlite3_result_error() and sqlite3_result_error16() functions
** cause the implemented SQL function to throw an exception.
** ^SQLite uses the string pointed to by the
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
** as the text of an error message.  ^SQLite interprets the error
** message string from sqlite3_result_error() as UTF-8. ^SQLite
** interprets the string from sqlite3_result_error16() as UTF-16 in native
** byte order.  ^If the third parameter to sqlite3_result_error()
** or sqlite3_result_error16() is negative then SQLite takes as the error
** message all text up through the first zero character.
** ^If the third parameter to sqlite3_result_error() or
** sqlite3_result_error16() is non-negative then SQLite takes that many
** bytes (not characters) from the 2nd parameter as the error message.
** ^The sqlite3_result_error() and sqlite3_result_error16()
** routines make a private copy of the error message text before
** they return.  Hence, the calling function can deallocate or
** modify the text after they return without harm.
** ^The sqlite3_result_error_code() function changes the error code
** returned by SQLite as a result of an error in a function.  ^By default,
** the error code is SQLITE_ERROR.  ^A subsequent call to sqlite3_result_error()
** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
**
** ^The sqlite3_result_toobig() interface causes SQLite to throw an error
** indicating that a string or BLOB is too long to represent.
**
** ^The sqlite3_result_nomem() interface causes SQLite to throw an error
** indicating that a memory allocation failed.
**
** ^The sqlite3_result_int() interface sets the return value
** of the application-defined function to be the 32-bit signed integer
** value given in the 2nd argument.
** ^The sqlite3_result_int64() interface sets the return value
** of the application-defined function to be the 64-bit signed integer
** value given in the 2nd argument.
**
** ^The sqlite3_result_null() interface sets the return value
** of the application-defined function to be NULL.
**
** ^The sqlite3_result_text(), sqlite3_result_text16(),
** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
** set the return value of the application-defined function to be
** a text string which is represented as UTF-8, UTF-16 native byte order,
** UTF-16 little endian, or UTF-16 big endian, respectively.
** ^SQLite takes the text result from the application from
** the 2nd parameter of the sqlite3_result_text* interfaces.
** ^If the 3rd parameter to the sqlite3_result_text* interfaces
** is negative, then SQLite takes result text from the 2nd parameter
** through the first zero character.
** ^If the 3rd parameter to the sqlite3_result_text* interfaces
** is non-negative, then as many bytes (not characters) of the text
** pointed to by the 2nd parameter are taken as the application-defined
** function result.  If the 3rd parameter is non-negative, then it
** must be the byte offset into the string where the NUL terminator would
** appear if the string where NUL terminated.  If any NUL characters occur
** in the string at a byte offset that is less than the value of the 3rd
** parameter, then the resulting string will contain embedded NULs and the
** result of expressions operating on strings with embedded NULs is undefined.
** ^If the 4th parameter to the sqlite3_result_text* interfaces
** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
** function as the destructor on the text or BLOB result when it has
** finished using that result.
** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
** assumes that the text or BLOB result is in constant space and does not
** copy the content of the parameter nor call a destructor on the content
** when it has finished using that result.
** ^If the 4th parameter to the sqlite3_result_text* interfaces
** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
** then SQLite makes a copy of the result into space obtained from
** from [sqlite3_malloc()] before it returns.
**
** ^The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy the
** [unprotected sqlite3_value] object specified by the 2nd parameter.  ^The
** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
** so that the [sqlite3_value] specified in the parameter may change or
** be deallocated after sqlite3_result_value() returns without harm.
** ^A [protected sqlite3_value] object may always be used where an
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.
**
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
SQLITE_API void sqlite3_result_null(sqlite3_context*);
SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);

/*
** CAPI3REF: Define New Collating Sequences
**
** ^These functions add, remove, or modify a [collation] associated
** with the [database connection] specified as the first argument.
**
** ^The name of the collation is a UTF-8 string
** for sqlite3_create_collation() and sqlite3_create_collation_v2()
** and a UTF-16 string in native byte order for sqlite3_create_collation16().
** ^Collation names that compare equal according to [sqlite3_strnicmp()] are
** considered to be the same name.
**
** ^(The third argument (eTextRep) must be one of the constants:
** <ul>
** <li> [SQLITE_UTF8],
** <li> [SQLITE_UTF16LE],
** <li> [SQLITE_UTF16BE],
** <li> [SQLITE_UTF16], or
** <li> [SQLITE_UTF16_ALIGNED].
** </ul>)^
** ^The eTextRep argument determines the encoding of strings passed
** to the collating function callback, xCallback.
** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
** force strings to be UTF16 with native byte order.
** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
** on an even byte address.
**
** ^The fourth argument, pArg, is an application data pointer that is passed
** through as the first argument to the collating function callback.
**
** ^The fifth argument, xCallback, is a pointer to the collating function.
** ^Multiple collating functions can be registered using the same name but
** with different eTextRep parameters and SQLite will use whichever
** function requires the least amount of data transformation.
** ^If the xCallback argument is NULL then the collating function is
** deleted.  ^When all collating functions having the same name are deleted,
** that collation is no longer usable.
**
** ^The collating function callback is invoked with a copy of the pArg 
** application data pointer and with two strings in the encoding specified
** by the eTextRep argument.  The collating function must return an
** integer that is negative, zero, or positive
** if the first string is less than, equal to, or greater than the second,
** respectively.  A collating function must always return the same answer
** given the same inputs.  If two or more collating functions are registered
** to the same collation name (using different eTextRep values) then all
** must give an equivalent answer when invoked with equivalent strings.
** The collating function must obey the following properties for all
** strings A, B, and C:
**
** <ol>
** <li> If A==B then B==A.
** <li> If A==B and B==C then A==C.
** <li> If A&lt;B THEN B&gt;A.
** <li> If A&lt;B and B&lt;C then A&lt;C.
** </ol>
**
** If a collating function fails any of the above constraints and that
** collating function is  registered and used, then the behavior of SQLite
** is undefined.
**
** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
** with the addition that the xDestroy callback is invoked on pArg when
** the collating function is deleted.
** ^Collating functions are deleted when they are overridden by later
** calls to the collation creation functions or when the
** [database connection] is closed using [sqlite3_close()].
**
** ^The xDestroy callback is <u>not</u> called if the 
** sqlite3_create_collation_v2() function fails.  Applications that invoke
** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should 
** check the return code and dispose of the application data pointer
** themselves rather than expecting SQLite to deal with it for them.
** This is different from every other SQLite interface.  The inconsistency 
** is unfortunate but cannot be changed without breaking backwards 
** compatibility.
**
** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
*/
SQLITE_API int sqlite3_create_collation(
  sqlite3*, 
  const char *zName, 
  int eTextRep, 
  void *pArg,
  int(*xCompare)(void*,int,const void*,int,const void*)
);
SQLITE_API int sqlite3_create_collation_v2(
  sqlite3*, 
  const char *zName, 
  int eTextRep, 
  void *pArg,
  int(*xCompare)(void*,int,const void*,int,const void*),
  void(*xDestroy)(void*)
);
SQLITE_API int sqlite3_create_collation16(
  sqlite3*, 
  const void *zName,
  int eTextRep, 
  void *pArg,
  int(*xCompare)(void*,int,const void*,int,const void*)
);

/*
** CAPI3REF: Collation Needed Callbacks
**
** ^To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
** [database connection] to be invoked whenever an undefined collation
** sequence is required.
**
** ^If the function is registered using the sqlite3_collation_needed() API,
** then it is passed the names of undefined collation sequences as strings
** encoded in UTF-8. ^If sqlite3_collation_needed16() is used,
** the names are passed as UTF-16 in machine native byte order.
** ^A call to either function replaces the existing collation-needed callback.
**
** ^(When the callback is invoked, the first argument passed is a copy
** of the second argument to sqlite3_collation_needed() or
** sqlite3_collation_needed16().  The second argument is the database
** connection.  The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE],
** or [SQLITE_UTF16LE], indicating the most desirable form of the collation
** sequence function required.  The fourth parameter is the name of the
** required collation sequence.)^
**
** The callback function should register the desired collation using
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
*/
SQLITE_API int sqlite3_collation_needed(
  sqlite3*, 
  void*, 
  void(*)(void*,sqlite3*,int eTextRep,const char*)
);
SQLITE_API int sqlite3_collation_needed16(
  sqlite3*, 
  void*,
  void(*)(void*,sqlite3*,int eTextRep,const void*)
);

#ifdef SQLITE_HAS_CODEC
/*
** Specify the key for an encrypted database.  This routine should be
** called right after sqlite3_open().
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
SQLITE_API int sqlite3_key(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The key */
);

/*
** Change the key on an open database.  If the current database is not
** encrypted, this routine will encrypt it.  If pNew==0 or nNew==0, the
** database is decrypted.
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
SQLITE_API int sqlite3_rekey(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The new key */
);

/*
** Specify the activation key for a SEE database.  Unless 
** activated, none of the SEE routines will work.
*/
SQLITE_API void sqlite3_activate_see(
  const char *zPassPhrase        /* Activation phrase */
);
#endif

#ifdef SQLITE_ENABLE_CEROD
/*
** Specify the activation key for a CEROD database.  Unless 
** activated, none of the CEROD routines will work.
*/
SQLITE_API void sqlite3_activate_cerod(
  const char *zPassPhrase        /* Activation phrase */
);
#endif

/*
** CAPI3REF: Suspend Execution For A Short Time
**
** The sqlite3_sleep() function causes the current thread to suspend execution
** for at least a number of milliseconds specified in its parameter.
**
** If the operating system does not support sleep requests with
** millisecond time resolution, then the time will be rounded up to
** the nearest second. The number of milliseconds of sleep actually
** requested from the operating system is returned.
**
** ^SQLite implements this interface by calling the xSleep()
** method of the default [sqlite3_vfs] object.  If the xSleep() method
** of the default VFS is not implemented correctly, or not implemented at
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
*/
SQLITE_API int sqlite3_sleep(int);

/*
** CAPI3REF: Name Of The Folder Holding Temporary Files
**
** ^(If this global variable is made to point to a string which is
** the name of a folder (a.k.a. directory), then all temporary files
** created by SQLite when using a built-in [sqlite3_vfs | VFS]
** will be placed in that directory.)^  ^If this variable
** is a NULL pointer, then SQLite performs a search for an appropriate
** temporary file directory.
**
** It is not safe to read or modify this variable in more than one
** thread at a time.  It is not safe to read or modify this variable
** if a [database connection] is being used at the same time in a separate
** thread.
** It is intended that this variable be set once
** as part of process initialization and before any SQLite interface
** routines have been called and that this variable remain unchanged
** thereafter.
**
** ^The [temp_store_directory pragma] may modify this variable and cause
** it to point to memory obtained from [sqlite3_malloc].  ^Furthermore,
** the [temp_store_directory pragma] always assumes that any string
** that this variable points to is held in memory obtained from 
** [sqlite3_malloc] and the pragma may attempt to free that memory
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;

/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively.  ^Autocommit mode is on by default.
** ^Autocommit mode is disabled by a [BEGIN] statement.
** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
**
** If certain kinds of errors occur on a statement within a multi-statement
** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
** transaction might be rolled back automatically.  The only way to
** find out whether SQLite automatically rolled back the transaction after
** an error is to use this function.
**
** If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
** is undefined.
*/
SQLITE_API int sqlite3_get_autocommit(sqlite3*);

/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
**
** ^The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs.  ^The [database connection]
** returned by sqlite3_db_handle is the same [database connection]
** that was the first argument
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

/*
** CAPI3REF: Find the next prepared statement
**
** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb.  ^If pStmt is NULL
** then this interface returns a pointer to the first prepared statement
** associated with the database connection pDb.  ^If no prepared statement
** satisfies the conditions of this routine, it returns NULL.
**
** The [database connection] pointer D in a call to
** [sqlite3_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);

/*
** CAPI3REF: Commit And Rollback Notification Callbacks
**
** ^The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is [COMMIT | committed].
** ^Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** ^The sqlite3_rollback_hook() interface registers a callback
** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
** ^Any callback set by a previous call to sqlite3_rollback_hook()
** for the same database connection is overridden.
** ^The pArg argument is passed through to the callback.
** ^If the callback on a commit hook function returns non-zero,
** then the commit is converted into a rollback.
**
** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions
** return the P argument from the previous call of the same function
** on the same [database connection] D, or NULL for
** the first call for each function on D.
**
** The callback implementation must not do anything that will modify
** the database connection that invoked the callback.  Any actions
** to modify the database connection must be deferred until after the
** completion of the [sqlite3_step()] call that triggered the commit
** or rollback hook in the first place.
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
** ^Registering a NULL function disables the callback.
**
** ^When the commit hook callback routine returns zero, the [COMMIT]
** operation is allowed to continue normally.  ^If the commit hook
** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
** ^The rollback hook is invoked on a rollback that results from a commit
** hook returning non-zero, just as it would be with any other rollback.
**
** ^For the purposes of this API, a transaction is said to have been
** rolled back if an explicit "ROLLBACK" statement is executed, or
** an error or constraint causes an implicit rollback to occur.
** ^The rollback callback is not invoked if a transaction is
** automatically rolled back because the database connection is closed.
**
** See also the [sqlite3_update_hook()] interface.
*/
SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
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.
** ^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.
** ^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).)^
**
** ^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.
**
** The update hook implementation must not do anything that will modify
** the database connection that invoked the update hook.  Any actions
** to modify the database connection must be deferred until after the
** completion of the [sqlite3_step()] call that triggered the update hook.
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
** ^The sqlite3_update_hook(D,C,P) function
** returns the P argument from the previous call
** on the same [database connection] D, or NULL for
** the first call on D.
**
** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
** interfaces.
*/
SQLITE_API void *sqlite3_update_hook(
  sqlite3*, 
  void(*)(void *,int ,char const *,char const *,sqlite3_int64),
  void*
);

/*
** CAPI3REF: Enable Or Disable Shared Pager Cache
** KEYWORDS: {shared cache}
**
** ^(This routine enables or disables the sharing of the database cache
** and schema data structures between [database connection | connections]
** to the same database. Sharing is enabled if the argument is true
** and disabled if the argument is false.)^
**
** ^Cache sharing is enabled and disabled for an entire process.
** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
** sharing was enabled or disabled for each thread separately.
**
** ^(The cache sharing mode set by this interface effects all subsequent
** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
** Existing database connections continue use the sharing mode
** that was in effect at the time they were opened.)^
**
** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
** successfully.  An [error code] is returned otherwise.)^
**
** ^Shared cache is disabled by default. But this might change in
** future releases of SQLite.  Applications that care about shared
** cache setting should set it explicitly.
**
** See Also:  [SQLite Shared-Cache Mode]
*/
SQLITE_API int sqlite3_enable_shared_cache(int);

/*
** CAPI3REF: Attempt To Free Heap Memory
**
** ^The sqlite3_release_memory() interface 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.
** ^sqlite3_release_memory() returns the number of bytes actually freed,
** which might be more or less than the amount requested.
** ^The sqlite3_release_memory() routine is a no-op returning zero
** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
*/
SQLITE_API int sqlite3_release_memory(int);

/*
** CAPI3REF: Impose A Limit On Heap Size
**
** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
** soft limit on the amount of heap memory that may be allocated by SQLite.
** ^SQLite strives to keep heap memory utilization below the soft heap
** limit by reducing the number of pages held in the page cache
** as heap memory usages approaches the limit.
** ^The soft heap limit is "soft" because even though SQLite strives to stay
** below the limit, it will exceed the limit rather than generate
** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
** is advisory only.
**
** ^The return value from sqlite3_soft_heap_limit64() is the size of
** the soft heap limit prior to the call.  ^If the argument N is negative
** then no change is made to the soft heap limit.  Hence, the current
** size of the soft heap limit can be determined by invoking
** sqlite3_soft_heap_limit64() with a negative argument.
**
** ^If the argument N is zero then the soft heap limit is disabled.
**
** ^(The soft heap limit is not enforced in the current implementation
** if one or more of following conditions are true:
**
** <ul>
** <li> The soft heap limit is set to zero.
** <li> Memory accounting is disabled using a combination of the
**      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
**      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
** <li> An alternative page cache implementation is specified using
**      [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
** <li> The page cache allocates from its own memory pool supplied
**      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
**      from the heap.
** </ul>)^
**
** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
** compile-time option is invoked.  With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
** the soft heap limit is enforced on every memory allocation.  Without
** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced
** when memory is allocated by the page cache.  Testing suggests that because
** the page cache is the predominate memory user in SQLite, most
** applications will achieve adequate soft heap limit enforcement without
** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT].
**
** The circumstances under which SQLite will enforce the soft heap limit may
** changes in future releases of SQLite.
*/
SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);

/*
** CAPI3REF: Deprecated Soft Heap Limit Interface
** DEPRECATED
**
** This is a deprecated version of the [sqlite3_soft_heap_limit64()]
** interface.  This routine is provided for historical compatibility
** only.  All new applications should use the
** [sqlite3_soft_heap_limit64()] interface rather than this one.
*/
SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);


/*
** CAPI3REF: Extract Metadata About A Column Of A Table
**
** ^This routine returns metadata about a specific column of a specific
** database table accessible using the [database connection] handle
** passed as the first function argument.
**
** ^The column is identified by the second, third and fourth parameters to
** this function. ^The second parameter is either the name of the database
** (i.e. "main", "temp", or an attached database) containing the specified
** table or NULL. ^If it is NULL, then all attached databases are searched
** for the table using the same algorithm used by the database engine to
** resolve unqualified table references.
**
** ^The third and fourth parameters to this function are the table and column
** name of the desired column, respectively. Neither of these parameters
** may be NULL.
**
** ^Metadata is returned by writing to the memory locations passed as the 5th
** and subsequent parameters to this function. ^Any of these arguments may be
** NULL, in which case the corresponding element of metadata is omitted.
**
** ^(<blockquote>
** <table border="1">
** <tr><th> Parameter <th> Output<br>Type <th>  Description
**
** <tr><td> 5th <td> const char* <td> Data type
** <tr><td> 6th <td> const char* <td> Name of default collation sequence
** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
** <tr><td> 9th <td> int         <td> True if column is [AUTOINCREMENT]
** </table>
** </blockquote>)^
**
** ^The memory pointed to by the character pointers returned for the
** declaration type and collation sequence is valid only until the next
** call to any SQLite API function.
**
** ^If the specified table is actually a view, an [error code] is returned.
**
** ^If the specified column is "rowid", "oid" or "_rowid_" and an
** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
** parameters are set for the explicitly declared column. ^(If there is no
** explicitly declared [INTEGER PRIMARY KEY] column, then the output
** parameters are set as follows:
**
** <pre>
**     data type: "INTEGER"
**     collation sequence: "BINARY"
**     not null: 0
**     primary key: 1
**     auto increment: 0
** </pre>)^
**
** ^(This function may load one or more schemas from database files. If an
** error occurs during this process, or if the requested table or column
** cannot be found, an [error code] is returned and an error message left
** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
**
** ^This API is only available if the library was compiled with the
** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
*/
SQLITE_API int sqlite3_table_column_metadata(
  sqlite3 *db,                /* Connection handle */
  const char *zDbName,        /* Database name or NULL */
  const char *zTableName,     /* Table name */
  const char *zColumnName,    /* Column name */
  char const **pzDataType,    /* OUTPUT: Declared data type */
  char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
  int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
  int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
  int *pAutoinc               /* OUTPUT: True if column is auto-increment */
);

/*
** CAPI3REF: Load An Extension
**
** ^This interface loads an SQLite extension library from the named file.
**
** ^The sqlite3_load_extension() interface attempts to load an
** SQLite extension library contained in the file zFile.
**
** ^The entry point is zProc.
** ^zProc may be 0, in which case the name of the entry point
** defaults to "sqlite3_extension_init".
** ^The sqlite3_load_extension() interface returns
** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
** ^If an error occurs and pzErrMsg is not 0, then the
** [sqlite3_load_extension()] interface shall attempt to
** fill *pzErrMsg with error message text stored in memory
** obtained from [sqlite3_malloc()]. The calling function
** should free this memory by calling [sqlite3_free()].
**
** ^Extension loading must be enabled using
** [sqlite3_enable_load_extension()] prior to calling this API,
** otherwise an error will be returned.
**
** See also the [load_extension() SQL function].
*/
SQLITE_API int sqlite3_load_extension(
  sqlite3 *db,          /* Load the extension into this database connection */
  const char *zFile,    /* Name of the shared library containing extension */
  const char *zProc,    /* Entry point.  Derived from zFile if 0 */
  char **pzErrMsg       /* Put error message here if not 0 */
);

/*
** CAPI3REF: Enable Or Disable Extension Loading
**
** ^So as not to open security holes in older applications that are
** unprepared to deal with extension loading, and as a means of disabling
** extension loading while evaluating user-entered SQL, the following API
** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
**
** ^Extension loading is off by default. See ticket #1863.
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
*/
SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);

/*
** CAPI3REF: Automatically Load Statically Linked Extensions
**
** ^This interface causes the xEntryPoint() function to be invoked for
** each new [database connection] that is created.  The idea here is that
** xEntryPoint() is the entry point for a statically linked SQLite extension
** that is to be automatically loaded into all new database connections.
**
** ^(Even though the function prototype shows that xEntryPoint() takes
** no arguments and returns void, SQLite invokes xEntryPoint() with three
** arguments and expects and integer result as if the signature of the
** entry point where as follows:
**
** <blockquote><pre>
** &nbsp;  int xEntryPoint(
** &nbsp;    sqlite3 *db,
** &nbsp;    const char **pzErrMsg,
** &nbsp;    const struct sqlite3_api_routines *pThunk
** &nbsp;  );
** </pre></blockquote>)^
**
** If the xEntryPoint routine encounters an error, it should make *pzErrMsg
** point to an appropriate error message (obtained from [sqlite3_mprintf()])
** and return an appropriate [error code].  ^SQLite ensures that *pzErrMsg
** is NULL before calling the xEntryPoint().  ^SQLite will invoke
** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns.  ^If any
** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()],
** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail.
**
** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
** on the list of automatic extensions is a harmless no-op. ^No entry point
** will be called more than once for each database connection that is opened.
**
** See also: [sqlite3_reset_auto_extension()].
*/
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));

/*
** CAPI3REF: Reset Automatic Extension Loading
**
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
SQLITE_API void sqlite3_reset_auto_extension(void);

/*
** The interface to the virtual-table mechanism is currently considered
** to be experimental.  The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.
**
** When the virtual-table mechanism stabilizes, we will declare the
** interface fixed, support it indefinitely, and remove this comment.
*/

/*
** Structures used by the virtual table interface
*/
typedef struct sqlite3_vtab sqlite3_vtab;
typedef struct sqlite3_index_info sqlite3_index_info;
typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
typedef struct sqlite3_module sqlite3_module;

/*
** CAPI3REF: Virtual Table Object
** KEYWORDS: sqlite3_module {virtual table module}
**
** This structure, sometimes called a "virtual table module", 
** defines the implementation of a [virtual tables].  
** This structure consists mostly of methods for the module.
**
** ^A virtual table module is created by filling in a persistent
** instance of this structure and passing a pointer to that instance
** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
** ^The registration remains valid until it is replaced by a different
** module or until the [database connection] closes.  The content
** of this structure must not change while it is registered with
** any database connection.
*/
struct sqlite3_module {
  int iVersion;
  int (*xCreate)(sqlite3*, void *pAux,
               int argc, const char *const*argv,
               sqlite3_vtab **ppVTab, char**);
  int (*xConnect)(sqlite3*, void *pAux,
               int argc, const char *const*argv,
               sqlite3_vtab **ppVTab, char**);
  int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
  int (*xDisconnect)(sqlite3_vtab *pVTab);
  int (*xDestroy)(sqlite3_vtab *pVTab);
  int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
  int (*xClose)(sqlite3_vtab_cursor*);
  int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
                int argc, sqlite3_value **argv);
  int (*xNext)(sqlite3_vtab_cursor*);
  int (*xEof)(sqlite3_vtab_cursor*);
  int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
  int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid);
  int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
  int (*xBegin)(sqlite3_vtab *pVTab);
  int (*xSync)(sqlite3_vtab *pVTab);
  int (*xCommit)(sqlite3_vtab *pVTab);
  int (*xRollback)(sqlite3_vtab *pVTab);
  int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
                       void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
                       void **ppArg);
  int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
  /* The methods above are in version 1 of the sqlite_module object. Those 
  ** below are for version 2 and greater. */
  int (*xSavepoint)(sqlite3_vtab *pVTab, int);
  int (*xRelease)(sqlite3_vtab *pVTab, int);
  int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
};

/*
** CAPI3REF: Virtual Table Indexing Information
** KEYWORDS: sqlite3_index_info
**
** The sqlite3_index_info structure and its substructures is used as part
** of the [virtual table] interface to
** pass information into and receive the reply from the [xBestIndex]
** method of a [virtual table module].  The fields under **Inputs** are the
** inputs to xBestIndex and are read-only.  xBestIndex inserts its
** results into the **Outputs** fields.
**
** ^(The aConstraint[] array records WHERE clause constraints of the form:
**
** <blockquote>column OP expr</blockquote>
**
** where OP is =, &lt;, &lt;=, &gt;, or &gt;=.)^  ^(The particular operator is
** stored in aConstraint[].op using one of the
** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^
** ^(The index of the column is stored in
** aConstraint[].iColumn.)^  ^(aConstraint[].usable is TRUE if the
** expr on the right-hand side can be evaluated (and thus the constraint
** is usable) and false if it cannot.)^
**
** ^The optimizer automatically inverts terms of the form "expr OP column"
** and makes other simplifications to the WHERE clause in an attempt to
** get as many WHERE clause terms into the form shown above as possible.
** ^The aConstraint[] array only reports WHERE clause terms that are
** relevant to the particular virtual table being queried.
**
** ^Information about the ORDER BY clause is stored in aOrderBy[].
** ^Each term of aOrderBy records a column of the ORDER BY clause.
**
** The [xBestIndex] method must fill aConstraintUsage[] with information
** about what parameters to pass to xFilter.  ^If argvIndex>0 then
** the right-hand side of the corresponding aConstraint[] is evaluated
** and becomes the argvIndex-th entry in argv.  ^(If aConstraintUsage[].omit
** is true, then the constraint is assumed to be fully handled by the
** virtual table and is not checked again by SQLite.)^
**
** ^The idxNum and idxPtr values are recorded and passed into the
** [xFilter] method.
** ^[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).
*/
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 */
     unsigned char usable;     /* True if this constraint is usable */
     int iTermOffset;          /* Used internally - xBestIndex should ignore */
  } *aConstraint;            /* Table of WHERE clause constraints */
  int nOrderBy;              /* Number of terms in the ORDER BY clause */
  struct sqlite3_index_orderby {
     int iColumn;              /* Column number */
     unsigned char desc;       /* True for DESC.  False for ASC. */
  } *aOrderBy;               /* The ORDER BY clause */
  /* Outputs */
  struct sqlite3_index_constraint_usage {
    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 */
};

/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
** [sqlite3_index_info].aConstraint[].op field.  Each value represents
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
#define SQLITE_INDEX_CONSTRAINT_EQ    2
#define SQLITE_INDEX_CONSTRAINT_GT    4
#define SQLITE_INDEX_CONSTRAINT_LE    8
#define SQLITE_INDEX_CONSTRAINT_LT    16
#define SQLITE_INDEX_CONSTRAINT_GE    32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64

/*
** CAPI3REF: Register A Virtual Table Implementation
**
** ^These routines are used to register a new [virtual table module] name.
** ^Module names must be registered before
** creating a new [virtual table] using the module and before using a
** preexisting [virtual table] for the module.
**
** ^The module name is registered on the [database connection] specified
** by the first parameter.  ^The name of the module is given by the 
** second parameter.  ^The third parameter is a pointer to
** the implementation of the [virtual table module].   ^The fourth
** parameter is an arbitrary client data pointer that is passed through
** into the [xCreate] and [xConnect] methods of the virtual table module
** when a new virtual table is be being created or reinitialized.
**
** ^The sqlite3_create_module_v2() interface has a fifth parameter which
** is a pointer to a destructor for the pClientData.  ^SQLite will
** invoke the destructor function (if it is not NULL) when SQLite
** no longer needs the pClientData pointer.  ^The destructor will also
** be invoked if the call to sqlite3_create_module_v2() fails.
** ^The sqlite3_create_module()
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
*/
SQLITE_API int sqlite3_create_module(
  sqlite3 *db,               /* SQLite connection to register module with */
  const char *zName,         /* Name of the module */
  const sqlite3_module *p,   /* Methods for the module */
  void *pClientData          /* Client data for xCreate/xConnect */
);
SQLITE_API int sqlite3_create_module_v2(
  sqlite3 *db,               /* SQLite connection to register module with */
  const char *zName,         /* Name of the module */
  const sqlite3_module *p,   /* Methods for the module */
  void *pClientData,         /* Client data for xCreate/xConnect */
  void(*xDestroy)(void*)     /* Module destructor function */
);

/*
** CAPI3REF: Virtual Table Instance Object
** KEYWORDS: sqlite3_vtab
**
** Every [virtual table module] implementation uses a subclass
** of this object to describe a particular instance
** of the [virtual table].  Each subclass will
** be tailored to the specific needs of the module implementation.
** The purpose of this superclass is to define certain fields that are
** common to all module implementations.
**
** ^Virtual tables methods can set an error message by assigning a
** string obtained from [sqlite3_mprintf()] to zErrMsg.  The method should
** take care that any prior string is freed by a call to [sqlite3_free()]
** prior to assigning a new string to zErrMsg.  ^After the error message
** is delivered up to the client application, the string will be automatically
** freed by sqlite3_free() and the zErrMsg field will be zeroed.
*/
struct sqlite3_vtab {
  const sqlite3_module *pModule;  /* The module for this virtual table */
  int nRef;                       /* NO LONGER USED */
  char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
  /* Virtual table implementations will typically add additional fields */
};

/*
** CAPI3REF: Virtual Table Cursor Object
** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
**
** Every [virtual table module] implementation uses a subclass of the
** following structure to describe cursors that point into the
** [virtual table] and are used
** to loop through the virtual table.  Cursors are created using the
** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
** by the [sqlite3_module.xClose | xClose] method.  Cursors are used
** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
** of the module.  Each module implementation will define
** the content of a cursor structure to suit its own needs.
**
** This superclass exists in order to define fields of the cursor that
** are common to all implementations.
*/
struct sqlite3_vtab_cursor {
  sqlite3_vtab *pVtab;      /* Virtual table of this cursor */
  /* Virtual table implementations will typically add additional fields */
};

/*
** CAPI3REF: Declare The Schema Of A Virtual Table
**
** ^The [xCreate] and [xConnect] methods of a
** [virtual table module] call this interface
** to declare the format (the names and datatypes of the columns) of
** the virtual tables they implement.
*/
SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);

/*
** CAPI3REF: Overload A Function For A Virtual Table
**
** ^(Virtual tables can provide alternative implementations of functions
** using the [xFindFunction] method of the [virtual table module].  
** But global versions of those functions
** must exist in order to be overloaded.)^
**
** ^(This API makes sure a global version of a function with a particular
** name and number of parameters exists.  If no such function exists
** before this API is called, a new function is created.)^  ^The implementation
** of the new function always causes an exception to be thrown.  So
** the new function is not good for anything by itself.  Its only
** purpose is to be a placeholder function that can be overloaded
** by a [virtual table].
*/
SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);

/*
** The interface to the virtual-table mechanism defined above (back up
** to a comment remarkably similar to this one) is currently considered
** to be experimental.  The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.
**
** When the virtual-table mechanism stabilizes, we will declare the
** interface fixed, support it indefinitely, and remove this comment.
*/

/*
** CAPI3REF: A Handle To An Open BLOB
** KEYWORDS: {BLOB handle} {BLOB handles}
**
** An instance of this object represents an open BLOB on which
** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
** ^Objects of this type are created by [sqlite3_blob_open()]
** and destroyed by [sqlite3_blob_close()].
** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
** can be used to read or write small subsections of the BLOB.
** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
*/
typedef struct sqlite3_blob sqlite3_blob;

/*
** CAPI3REF: Open A BLOB For Incremental I/O
**
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
** in other words, the same BLOB that would be selected by:
**
** <pre>
**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre>)^
**
** ^If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. ^If it is zero, the BLOB is opened for read access.
** ^It is not possible to open a column that is part of an index or primary 
** key for writing. ^If [foreign key constraints] are enabled, it is 
** not possible to open a column that is part of a [child key] for writing.
**
** ^Note that the database name is not the filename that contains
** the database but rather the symbolic name of the database that
** appears after the AS keyword when the database is connected using [ATTACH].
** ^For the main database file, the database name is "main".
** ^For TEMP tables, the database name is "temp".
**
** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
** to be a null pointer.)^
** ^This function sets the [database connection] error code and message
** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
** functions. ^Note that the *ppBlob variable is always initialized in a
** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
** regardless of the success or failure of this routine.
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
** then the BLOB handle is marked as "expired".
** This is true if any column of the row is changed, even a column
** other than the one the BLOB handle is open on.)^
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
** ^(Changes written into a BLOB prior to the BLOB expiring are not
** rolled back by the expiration of the BLOB.  Such changes will eventually
** 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_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()].
*/
SQLITE_API int sqlite3_blob_open(
  sqlite3*,
  const char *zDb,
  const char *zTable,
  const char *zColumn,
  sqlite3_int64 iRow,
  int flags,
  sqlite3_blob **ppBlob
);

/*
** CAPI3REF: Move a BLOB Handle to a New Row
**
** ^This function is used to move an existing blob handle so that it points
** to a different row of the same database table. ^The new row is identified
** by the rowid value passed as the second argument. Only the row can be
** changed. ^The database, table and column on which the blob handle is open
** remain the same. Moving an existing blob handle to a new row can be
** faster than closing the existing handle and opening a new one.
**
** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
** it must exist and there must be either a blob or text value stored in
** the nominated column.)^ ^If the new row is not present in the table, or if
** it does not contain a blob or text value, or if another error occurs, an
** SQLite error code is returned and the blob handle is considered aborted.
** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
** [sqlite3_blob_reopen()] on an aborted blob handle immediately return
** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
** always returns zero.
**
** ^This function sets the database handle error code and message.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);

/*
** CAPI3REF: Close A BLOB Handle
**
** ^Closes an open [BLOB handle].
**
** ^Closing a BLOB shall cause the current transaction to commit
** if there are no other BLOBs, no pending prepared statements, and the
** database connection is in [autocommit mode].
** ^If any writes were made to the BLOB, they might be held in cache
** until the close operation if they will fit.
**
** ^(Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
** at the time when the BLOB is closed.  Any errors that occur during
** closing are reported as a non-zero return value.)^
**
** ^(The BLOB is closed unconditionally.  Even if this routine returns
** an error code, the BLOB is still closed.)^
**
** ^Calling this routine with a null pointer (such as would be returned
** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.
*/
SQLITE_API int sqlite3_blob_close(sqlite3_blob *);

/*
** CAPI3REF: Return The Size Of An Open BLOB
**
** ^Returns the size in bytes of the BLOB accessible via the 
** successfully opened [BLOB handle] in its only argument.  ^The
** incremental blob I/O routines can only read or overwriting existing
** blob content; they cannot change the size of a blob.
**
** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()].  Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
*/
SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);

/*
** CAPI3REF: Read Data From A BLOB Incrementally
**
** ^(This function is used to read data from an open [BLOB handle] into a
** caller-supplied buffer. N bytes of data are copied into buffer Z
** from the open BLOB, starting at offset iOffset.)^
**
** ^If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is read.  ^If N or iOffset is
** less than zero, [SQLITE_ERROR] is returned and no data is read.
** ^The size of the blob (and hence the maximum value of N+iOffset)
** can be determined using the [sqlite3_blob_bytes()] interface.
**
** ^An attempt to read from an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].
**
** ^(On success, sqlite3_blob_read() returns SQLITE_OK.
** Otherwise, an [error code] or an [extended error code] is returned.)^
**
** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()].  Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
**
** See also: [sqlite3_blob_write()].
*/
SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);

/*
** CAPI3REF: Write Data Into A BLOB Incrementally
**
** ^This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. ^N bytes of data are copied from the buffer Z
** into the open BLOB, starting at offset iOffset.
**
** ^If the [BLOB handle] passed as the first argument was not opened for
** writing (the flags parameter to [sqlite3_blob_open()] was zero),
** this function returns [SQLITE_READONLY].
**
** ^This function may only modify the contents of the BLOB; it is
** not possible to increase the size of a BLOB using this API.
** ^If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written.  ^If N is
** less than zero [SQLITE_ERROR] is returned and no data is written.
** The size of the BLOB (and hence the maximum value of N+iOffset)
** can be determined using the [sqlite3_blob_bytes()] interface.
**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
** before the [BLOB handle] expired are not rolled back by the
** expiration of the handle, though of course those changes might
** have been overwritten by the statement that expired the BLOB handle
** or by other independent statements.
**
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
** Otherwise, an  [error code] or an [extended error code] is returned.)^
**
** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()].  Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
**
** See also: [sqlite3_blob_read()].
*/
SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);

/*
** CAPI3REF: Virtual File System Objects
**
** A virtual filesystem (VFS) is an [sqlite3_vfs] object
** that SQLite uses to interact
** with the underlying operating system.  Most SQLite builds come with a
** single default VFS that is appropriate for the host computer.
** New VFSes can be registered and existing VFSes can be unregistered.
** The following interfaces are provided.
**
** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
** ^Names are case sensitive.
** ^Names are zero-terminated UTF-8 strings.
** ^If there is no match, a NULL pointer is returned.
** ^If zVfsName is NULL then the default VFS is returned.
**
** ^New VFSes are registered with sqlite3_vfs_register().
** ^Each new VFS becomes the default VFS if the makeDflt flag is set.
** ^The same VFS can be registered multiple times without injury.
** ^To make an existing VFS into the default VFS, register it again
** with the makeDflt flag set.  If two different VFSes with the
** same name are registered, the behavior is undefined.  If a
** VFS is registered with a name that is NULL or an empty string,
** then the behavior is undefined.
**
** ^Unregister a VFS with the sqlite3_vfs_unregister() interface.
** ^(If the default VFS is unregistered, another VFS is chosen as
** the default.  The choice for the new VFS is arbitrary.)^
*/
SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);

/*
** CAPI3REF: Mutexes
**
** The SQLite core uses these routines for thread
** synchronization. Though they are intended for internal
** use by SQLite, code that links against SQLite is
** permitted to use any of these routines.
**
** The SQLite source code contains multiple implementations
** of these mutex routines.  An appropriate implementation
** is selected automatically at compile-time.  ^(The following
** implementations are available in the SQLite core:
**
** <ul>
** <li>   SQLITE_MUTEX_OS2
** <li>   SQLITE_MUTEX_PTHREAD
** <li>   SQLITE_MUTEX_W32
** <li>   SQLITE_MUTEX_NOOP
** </ul>)^
**
** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
** a single-threaded application.  ^The SQLITE_MUTEX_OS2,
** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations
** are appropriate for use on OS/2, Unix, and Windows.
**
** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
** implementation is included with the library. In this case the
** application must supply a custom mutex implementation using the
** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().)^
**
** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^If it returns NULL
** that means that a mutex could not be allocated.  ^SQLite
** will unwind its stack and return an error.  ^(The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_MEM2
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_LRU2
** </ul>)^
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
** cause sqlite3_mutex_alloc() to create
** a new mutex.  ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  ^SQLite will only request a recursive mutex in
** cases where it really needs one.  ^If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
** a pointer to a static preexisting mutex.  ^Six static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  ^But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
**
** ^The sqlite3_mutex_free() routine deallocates a previously
** allocated dynamic mutex.  ^SQLite is careful to deallocate every
** dynamic mutex that it allocates.  The dynamic mutexes must not be in
** use when they are deallocated.  Attempting to deallocate a static
** mutex results in undefined behavior.  ^SQLite never deallocates
** a static mutex.
**
** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  ^If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
** upon successful entry.  ^(Mutexes created using
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
** In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.)^  ^(If the same thread tries to enter any other
** kind of mutex more than once, the behavior is undefined.
** SQLite will never exhibit
** such behavior in its own use of mutexes.)^
**
** ^(Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
** will always return SQLITE_BUSY.  The SQLite core only ever uses
** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^
**
** ^The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread.   ^(The behavior
** is undefined if the mutex is not currently entered by the
** calling thread or is not currently allocated.  SQLite will
** never do either.)^
**
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
** behave as no-ops.
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);

/*
** CAPI3REF: Mutex Methods Object
**
** An instance of this structure defines the low-level routines
** used to allocate and use mutexes.
**
** Usually, the default mutex implementations provided by SQLite are
** sufficient, however the user has the option of substituting a custom
** implementation for specialized deployments or systems for which SQLite
** does not provide a suitable implementation. In this case, the user
** creates and populates an instance of this structure to pass
** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
** Additionally, an instance of this structure can be used as an
** output variable when querying the system for the current mutex
** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
**
** ^The xMutexInit method defined by this structure is invoked as
** part of system initialization by the sqlite3_initialize() function.
** ^The xMutexInit routine is called by SQLite exactly once for each
** effective call to [sqlite3_initialize()].
**
** ^The xMutexEnd method defined by this structure is invoked as
** part of system shutdown by the sqlite3_shutdown() function. The
** implementation of this method is expected to release all outstanding
** resources obtained by the mutex methods implementation, especially
** those obtained by the xMutexInit method.  ^The xMutexEnd()
** interface is invoked exactly once for each call to [sqlite3_shutdown()].
**
** ^(The remaining seven methods defined by this structure (xMutexAlloc,
** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
** xMutexNotheld) implement the following interfaces (respectively):
**
** <ul>
**   <li>  [sqlite3_mutex_alloc()] </li>
**   <li>  [sqlite3_mutex_free()] </li>
**   <li>  [sqlite3_mutex_enter()] </li>
**   <li>  [sqlite3_mutex_try()] </li>
**   <li>  [sqlite3_mutex_leave()] </li>
**   <li>  [sqlite3_mutex_held()] </li>
**   <li>  [sqlite3_mutex_notheld()] </li>
** </ul>)^
**
** The only difference is that the public sqlite3_XXX functions enumerated
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
** by this structure are not required to handle this case, the results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
**
** The xMutexInit() method must be threadsafe.  ^It must be harmless to
** invoke xMutexInit() multiple times within the same process and without
** intervening calls to xMutexEnd().  Second and subsequent calls to
** xMutexInit() must be no-ops.
**
** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
** and its associates).  ^Similarly, xMutexAlloc() must not use SQLite memory
** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
** memory allocation for a fast or recursive mutex.
**
** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
** called, but only if the prior call to xMutexInit returned SQLITE_OK.
** If xMutexInit fails in any way, it is expected to clean up after itself
** prior to returning.
*/
typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
struct sqlite3_mutex_methods {
  int (*xMutexInit)(void);
  int (*xMutexEnd)(void);
  sqlite3_mutex *(*xMutexAlloc)(int);
  void (*xMutexFree)(sqlite3_mutex *);
  void (*xMutexEnter)(sqlite3_mutex *);
  int (*xMutexTry)(sqlite3_mutex *);
  void (*xMutexLeave)(sqlite3_mutex *);
  int (*xMutexHeld)(sqlite3_mutex *);
  int (*xMutexNotheld)(sqlite3_mutex *);
};

/*
** CAPI3REF: Mutex Verification Routines
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
** are intended for use inside assert() statements.  ^The SQLite core
** never uses these routines except inside an assert() and applications
** are advised to follow the lead of the core.  ^The SQLite core only
** provides implementations for these routines when it is compiled
** with the SQLITE_DEBUG flag.  ^External mutex implementations
** are only required to provide these routines if SQLITE_DEBUG is
** defined and if NDEBUG is not defined.
**
** ^These routines should return true if the mutex in their argument
** is held or not held, respectively, by the calling thread.
**
** ^The implementation is not required to provided versions of these
** routines that actually work. If the implementation does not provide working
** versions of these routines, it should at least provide stubs that always
** return true so that one does not get spurious assertion failures.
**
** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
** the routine should return 1.   This seems counter-intuitive since
** clearly the mutex cannot be held if it does not exist.  But
** the reason the mutex does not exist is because the build is not
** using mutexes.  And we do not want the assert() containing the
** call to sqlite3_mutex_held() to fail, so a non-zero return is
** the appropriate thing to do.  ^The sqlite3_mutex_notheld()
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif

/*
** CAPI3REF: Mutex Types
**
** The [sqlite3_mutex_alloc()] interface takes a single argument
** which is one of these integer constants.
**
** The set of static mutexes may change from one SQLite release to the
** next.  Applications that override the built-in mutex logic must be
** prepared to accommodate additional static mutexes.
*/
#define SQLITE_MUTEX_FAST             0
#define SQLITE_MUTEX_RECURSIVE        1
#define SQLITE_MUTEX_STATIC_MASTER    2
#define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2      4  /* NOT USED */
#define SQLITE_MUTEX_STATIC_OPEN      4  /* sqlite3BtreeOpen() */
#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_random() */
#define SQLITE_MUTEX_STATIC_LRU       6  /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2      7  /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM      7  /* sqlite3PageMalloc() */

/*
** CAPI3REF: Retrieve the mutex for a database connection
**
** ^This interface returns a pointer the [sqlite3_mutex] object that 
** serializes access to the [database connection] given in the argument
** when the [threading mode] is Serialized.
** ^If the [threading mode] is Single-thread or Multi-thread then this
** routine returns a NULL pointer.
*/
SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);

/*
** CAPI3REF: Low-Level Control Of Database Files
**
** ^The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
** with a particular database identified by the second argument. ^The
** name of the database is "main" for the main database or "temp" for the
** TEMP database, or the name that appears after the AS keyword for
** databases that are added using the [ATTACH] SQL command.
** ^A NULL pointer can be used in place of "main" to refer to the
** main database file.
** ^The third and fourth parameters to this routine
** are passed directly through to the second and third parameters of
** the xFileControl method.  ^The return value of the xFileControl
** method becomes the return value of this routine.
**
** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
** a pointer to the underlying [sqlite3_file] object to be written into
** the space pointed to by the 4th parameter.  ^The SQLITE_FCNTL_FILE_POINTER
** case is a short-circuit path which does not actually invoke the
** underlying sqlite3_io_methods.xFileControl method.
**
** ^If the second parameter (zDbName) does not match the name of any
** open database file, then SQLITE_ERROR is returned.  ^This error
** code is not remembered and will not be recalled by [sqlite3_errcode()]
** or [sqlite3_errmsg()].  The underlying xFileControl method might
** also return SQLITE_ERROR.  There is no way to distinguish between
** an incorrect zDbName and an SQLITE_ERROR return from the underlying
** xFileControl method.
**
** See also: [SQLITE_FCNTL_LOCKSTATE]
*/
SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);

/*
** CAPI3REF: Testing Interface
**
** ^The sqlite3_test_control() interface is used to read out internal
** state of SQLite and to inject faults into SQLite for testing
** purposes.  ^The first parameter is an operation code that determines
** the number, meaning, and operation of all subsequent parameters.
**
** This interface is not for use by applications.  It exists solely
** for verifying the correct operation of the SQLite library.  Depending
** on how the SQLite library is compiled, this interface might not exist.
**
** The details of the operation codes, their meanings, the parameters
** they take, and what they do are all subject to change without notice.
** Unlike most of the SQLite API, this function is not guaranteed to
** operate consistently from one release to the next.
*/
SQLITE_API int sqlite3_test_control(int op, ...);

/*
** CAPI3REF: Testing Interface Operation Codes
**
** These constants are the valid operation code parameters used
** as the first argument to [sqlite3_test_control()].
**
** These parameters and their meanings are subject to change
** without notice.  These values are for testing purposes only.
** Applications should not use any of these parameters or the
** [sqlite3_test_control()] interface.
*/
#define SQLITE_TESTCTRL_FIRST                    5
#define SQLITE_TESTCTRL_PRNG_SAVE                5
#define SQLITE_TESTCTRL_PRNG_RESTORE             6
#define SQLITE_TESTCTRL_PRNG_RESET               7
#define SQLITE_TESTCTRL_BITVEC_TEST              8
#define SQLITE_TESTCTRL_FAULT_INSTALL            9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
#define SQLITE_TESTCTRL_PENDING_BYTE            11
#define SQLITE_TESTCTRL_ASSERT                  12
#define SQLITE_TESTCTRL_ALWAYS                  13
#define SQLITE_TESTCTRL_RESERVE                 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS           15
#define SQLITE_TESTCTRL_ISKEYWORD               16
#define SQLITE_TESTCTRL_PGHDRSZ                 17
#define SQLITE_TESTCTRL_SCRATCHMALLOC           18
#define SQLITE_TESTCTRL_LOCALTIME_FAULT         19
#define SQLITE_TESTCTRL_LAST                    19

/*
** CAPI3REF: SQLite Runtime Status
**
** ^This interface is used to retrieve runtime status information
** about the performance of SQLite, and optionally to reset various
** highwater marks.  ^The first argument is an integer code for
** the specific parameter to measure.  ^(Recognized integer codes
** are of the form [status parameters | SQLITE_STATUS_...].)^
** ^The current value of the parameter is returned into *pCurrent.
** ^The highest recorded value is returned in *pHighwater.  ^If the
** resetFlag is true, then the highest record value is reset after
** *pHighwater is written.  ^(Some parameters do not record the highest
** value.  For those parameters
** nothing is written into *pHighwater and the resetFlag is ignored.)^
** ^(Other parameters record only the highwater mark and not the current
** value.  For these latter parameters nothing is written into *pCurrent.)^
**
** ^The sqlite3_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** This routine is threadsafe but is not atomic.  This routine can be
** called while other threads are running the same or different SQLite
** interfaces.  However the values returned in *pCurrent and
** *pHighwater reflect the status of SQLite at different points in time
** and it is possible that another thread might change the parameter
** in between the times when *pCurrent and *pHighwater are written.
**
** See also: [sqlite3_db_status()]
*/
SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);


/*
** CAPI3REF: Status Parameters
** KEYWORDS: {status parameters}
**
** These integer constants designate various run-time status parameters
** that can be returned by [sqlite3_status()].
**
** <dl>
** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt>
** <dd>This parameter is the current amount of memory checked out
** using [sqlite3_malloc()], either directly or indirectly.  The
** figure includes calls made to [sqlite3_malloc()] by the application
** and internal memory usage by the SQLite library.  Scratch memory
** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
** this parameter.  The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
**
** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
** internal equivalents).  Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.  
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
** <dd>This parameter records the number of separate memory allocations
** currently checked out.</dd>)^
**
** [[SQLITE_STATUS_PAGECACHE_USED]] ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt>
** <dd>This parameter returns the number of pages used out of the
** [pagecache memory allocator] that was configured using 
** [SQLITE_CONFIG_PAGECACHE].  The
** value returned is in pages, not in bytes.</dd>)^
**
** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] 
** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of page cache
** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
** buffer and where forced to overflow to [sqlite3_malloc()].  The
** returned value includes allocations that overflowed because they
** where too large (they were larger than the "sz" parameter to
** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
** no space was left in the page cache.</dd>)^
**
** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to [pagecache memory allocator].  Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.  
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
** <dd>This parameter returns the number of allocations used out of the
** [scratch memory allocator] configured using
** [SQLITE_CONFIG_SCRATCH].  The value returned is in allocations, not
** in bytes.  Since a single thread may only have one scratch allocation
** outstanding at time, this parameter also reports the number of threads
** using scratch memory at the same time.</dd>)^
**
** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of scratch memory
** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
** buffer and where forced to overflow to [sqlite3_malloc()].  The values
** returned include overflows because the requested allocation was too
** larger (that is, because the requested allocation was larger than the
** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
** slots were available.
** </dd>)^
**
** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to [scratch memory allocator].  Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.  
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>This parameter records the deepest parser stack.  It is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
**
** New status parameters may be added from time to time.
*/
#define SQLITE_STATUS_MEMORY_USED          0
#define SQLITE_STATUS_PAGECACHE_USED       1
#define SQLITE_STATUS_PAGECACHE_OVERFLOW   2
#define SQLITE_STATUS_SCRATCH_USED         3
#define SQLITE_STATUS_SCRATCH_OVERFLOW     4
#define SQLITE_STATUS_MALLOC_SIZE          5
#define SQLITE_STATUS_PARSER_STACK         6
#define SQLITE_STATUS_PAGECACHE_SIZE       7
#define SQLITE_STATUS_SCRATCH_SIZE         8
#define SQLITE_STATUS_MALLOC_COUNT         9

/*
** CAPI3REF: Database Connection Status
**
** ^This interface is used to retrieve runtime status information 
** about a single [database connection].  ^The first argument is the
** database connection object to be interrogated.  ^The second argument
** is an integer constant, taken from the set of
** [SQLITE_DBSTATUS options], that
** determines the parameter to interrogate.  The set of 
** [SQLITE_DBSTATUS options] is likely
** to grow in future releases of SQLite.
**
** ^The current value of the requested parameter is written into *pCur
** and the highest instantaneous value is written into *pHiwtr.  ^If
** the resetFlg is true, then the highest instantaneous value is
** reset back down to the current value.
**
** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);

/*
** CAPI3REF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
**
** New verbs may be added in future releases of SQLite. Existing verbs
** might be discontinued. Applications should check the return code from
** [sqlite3_db_status()] to make sure that the call worked.
** The [sqlite3_db_status()] interface will return a non-zero error code
** if a discontinued or unsupported verb is invoked.
**
** <dl>
** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
** <dd>This parameter returns the number of lookaside memory slots currently
** checked out.</dd>)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
** <dd>This parameter returns the number malloc attempts that were 
** satisfied using lookaside memory. Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
** <dd>This parameter returns the number malloc attempts that might have
** been satisfied using lookaside memory but failed due to the amount of
** memory requested being larger than the lookaside slot size.
** Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
** <dd>This parameter returns the number malloc attempts that might have
** been satisfied using lookaside memory but failed due to all lookaside
** memory already being in use.
** Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** memory used by all pager caches associated with the database connection.)^
** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
**
** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** memory used to store the schema for all databases associated
** with the connection - main, temp, and any [ATTACH]-ed databases.)^ 
** ^The full amount of memory used by the schemas is reported, even if the
** schema memory is shared with other database connections due to
** [shared cache mode] being enabled.
** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
**
** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** and lookaside memory used by all prepared statements associated with
** the database connection.)^
** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
** <dd>This parameter returns the number of pager cache hits that have
** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT 
** is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
** <dd>This parameter returns the number of pager cache misses that have
** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS 
** is always 0.
** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED       0
#define SQLITE_DBSTATUS_CACHE_USED           1
#define SQLITE_DBSTATUS_SCHEMA_USED          2
#define SQLITE_DBSTATUS_STMT_USED            3
#define SQLITE_DBSTATUS_LOOKASIDE_HIT        4
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE  5
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL  6
#define SQLITE_DBSTATUS_CACHE_HIT            7
#define SQLITE_DBSTATUS_CACHE_MISS           8
#define SQLITE_DBSTATUS_MAX                  8   /* Largest defined DBSTATUS */


/*
** CAPI3REF: Prepared Statement Status
**
** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS counters] that measure the number
** of times it has performed specific operations.)^  These counters can
** be used to monitor the performance characteristics of the prepared
** statements.  For example, if the number of table steps greatly exceeds
** the number of table searches or result rows, that would tend to indicate
** that the prepared statement is using a full table scan rather than
** an index.  
**
** ^(This interface is used to retrieve and reset counter values from
** a [prepared statement].  The first argument is the prepared statement
** object to be interrogated.  The second argument
** is an integer code for a specific [SQLITE_STMTSTATUS counter]
** to be interrogated.)^
** ^The current value of the requested counter is returned.
** ^If the resetFlg is true, then the counter is reset to zero after this
** interface call returns.
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);

/*
** CAPI3REF: Status Parameters for prepared statements
** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters}
**
** These preprocessor macros define integer codes that name counter
** values associated with the [sqlite3_stmt_status()] interface.
** The meanings of the various counters are as follows:
**
** <dl>
** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
** <dd>^This is the number of times that SQLite has stepped forward in
** a table as part of a full table scan.  Large numbers for this counter
** may indicate opportunities for performance improvement through 
** careful use of indices.</dd>
**
** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt>
** <dd>^This is the number of sort operations that have occurred.
** A non-zero value in this counter may indicate an opportunity to
** improvement performance through careful use of indices.</dd>
**
** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt>
** <dd>^This is the number of rows inserted into transient indices that
** were created automatically in order to help joins run faster.
** A non-zero value in this counter may indicate an opportunity to
** improvement performance by adding permanent indices that do not
** need to be reinitialized each time the statement is run.</dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
#define SQLITE_STMTSTATUS_SORT              2
#define SQLITE_STMTSTATUS_AUTOINDEX         3

/*
** CAPI3REF: Custom Page Cache Object
**
** The sqlite3_pcache type is opaque.  It is implemented by
** the pluggable module.  The SQLite core has no knowledge of
** its size or internal structure and never deals with the
** sqlite3_pcache object except by holding and passing pointers
** to the object.
**
** See [sqlite3_pcache_methods] for additional information.
*/
typedef struct sqlite3_pcache sqlite3_pcache;

/*
** CAPI3REF: Application Defined Page Cache.
** KEYWORDS: {page cache}
**
** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
** register an alternative page cache implementation by passing in an 
** instance of the sqlite3_pcache_methods structure.)^
** In many applications, most of the heap memory allocated by 
** SQLite is used for the page cache.
** By implementing a 
** custom page cache using this API, an application can better control
** the amount of memory consumed by SQLite, the way in which 
** that memory is allocated and released, and the policies used to 
** determine exactly which parts of a database file are cached and for 
** how long.
**
** The alternative page cache mechanism is an
** extreme measure that is only needed by the most demanding applications.
** The built-in page cache is recommended for most uses.
**
** ^(The contents of the sqlite3_pcache_methods structure are copied to an
** internal buffer by SQLite within the call to [sqlite3_config].  Hence
** the application may discard the parameter after the call to
** [sqlite3_config()] returns.)^
**
** [[the xInit() page cache method]]
** ^(The xInit() method is called once for each effective 
** call to [sqlite3_initialize()])^
** (usually only once during the lifetime of the process). ^(The xInit()
** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^
** The intent of the xInit() method is to set up global data structures 
** required by the custom page cache implementation. 
** ^(If the xInit() method is NULL, then the 
** built-in default page cache is used instead of the application defined
** page cache.)^
**
** [[the xShutdown() page cache method]]
** ^The xShutdown() method is called by [sqlite3_shutdown()].
** It can be used to clean up 
** any outstanding resources before process shutdown, if required.
** ^The xShutdown() method may be NULL.
**
** ^SQLite automatically serializes calls to the xInit method,
** so the xInit method need not be threadsafe.  ^The
** xShutdown method is only called from [sqlite3_shutdown()] so it does
** not need to be threadsafe either.  All other methods must be threadsafe
** in multithreaded applications.
**
** ^SQLite will never invoke xInit() more than once without an intervening
** call to xShutdown().
**
** [[the xCreate() page cache methods]]
** ^SQLite invokes the xCreate() method to construct a new cache instance.
** SQLite will typically create one cache instance for each open database file,
** though this is not guaranteed. ^The
** first parameter, szPage, is the size in bytes of the pages that must
** be allocated by the cache.  ^szPage will not be a power of two.  ^szPage
** will the page size of the database file that is to be cached plus an
** increment (here called "R") of less than 250.  SQLite will use the
** extra R bytes on each page to store metadata about the underlying
** database page on disk.  The value of R depends
** on the SQLite version, the target platform, and how SQLite was compiled.
** ^(R is constant for a particular build of SQLite. Except, there are two
** distinct values of R when SQLite is compiled with the proprietary
** ZIPVFS extension.)^  ^The second argument to
** xCreate(), bPurgeable, is true if the cache being created will
** be used to cache database pages of a file stored on disk, or
** false if it is used for an in-memory database. The cache implementation
** does not have to do anything special based with the value of bPurgeable;
** it is purely advisory.  ^On a cache where bPurgeable is false, SQLite will
** never invoke xUnpin() except to deliberately delete a page.
** ^In other words, calls to xUnpin() on a cache with bPurgeable set to
** false will always have the "discard" flag set to true.  
** ^Hence, a cache created with bPurgeable false will
** never contain any unpinned pages.
**
** [[the xCachesize() page cache method]]
** ^(The xCachesize() method may be called at any time by SQLite to set the
** suggested maximum cache-size (number of pages stored by) the cache
** instance passed as the first argument. This is the value configured using
** the SQLite "[PRAGMA cache_size]" command.)^  As with the bPurgeable
** parameter, the implementation is not required to do anything with this
** value; it is advisory only.
**
** [[the xPagecount() page cache methods]]
** The xPagecount() method must return the number of pages currently
** stored in the cache, both pinned and unpinned.
** 
** [[the xFetch() page cache methods]]
** The xFetch() method locates a page in the cache and returns a pointer to 
** the page, or a NULL pointer.
** A "page", in this context, means a buffer of szPage bytes aligned at an
** 8-byte boundary. The page to be fetched is determined by the key. ^The
** minimum key value is 1.  After it has been retrieved using xFetch, the page 
** is considered to be "pinned".
**
** If the requested page is already in the page cache, then the page cache
** implementation must return a pointer to the page buffer with its content
** intact.  If the requested page is not already in the cache, then the
** cache implementation should use the value of the createFlag
** parameter to help it determined what action to take:
**
** <table border=1 width=85% align=center>
** <tr><th> createFlag <th> Behaviour when page is not already in cache
** <tr><td> 0 <td> Do not allocate a new page.  Return NULL.
** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
**                 Otherwise return NULL.
** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return
**                 NULL if allocating a new page is effectively impossible.
** </table>
**
** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  SQLite
** will only use a createFlag of 2 after a prior call with a createFlag of 1
** failed.)^  In between the to xFetch() calls, SQLite may
** attempt to unpin one or more cache pages by spilling the content of
** pinned pages to disk and synching the operating system disk cache.
**
** [[the xUnpin() page cache method]]
** ^xUnpin() is called by SQLite with a pointer to a currently pinned page
** as its second argument.  If the third parameter, discard, is non-zero,
** then the page must be evicted from the cache.
** ^If the discard parameter is
** zero, then the page may be discarded or retained at the discretion of
** page cache implementation. ^The page cache implementation
** may choose to evict unpinned pages at any time.
**
** The cache must not perform any reference counting. A single 
** call to xUnpin() unpins the page regardless of the number of prior calls 
** to xFetch().
**
** [[the xRekey() page cache methods]]
** The xRekey() method is used to change the key value associated with the
** page passed as the second argument. If the cache
** previously contains an entry associated with newKey, it must be
** discarded. ^Any prior cache entry associated with newKey is guaranteed not
** to be pinned.
**
** When SQLite calls the xTruncate() method, the cache must discard all
** existing cache entries with page numbers (keys) greater than or equal
** to the value of the iLimit parameter passed to xTruncate(). If any
** of these pages are pinned, they are implicitly unpinned, meaning that
** they can be safely discarded.
**
** [[the xDestroy() page cache method]]
** ^The xDestroy() method is used to delete a cache allocated by xCreate().
** All resources associated with the specified cache should be freed. ^After
** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
** handle invalid, and will not use it with any other sqlite3_pcache_methods
** functions.
*/
typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
struct sqlite3_pcache_methods {
  void *pArg;
  int (*xInit)(void*);
  void (*xShutdown)(void*);
  sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
  void (*xCachesize)(sqlite3_pcache*, int nCachesize);
  int (*xPagecount)(sqlite3_pcache*);
  void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
  void (*xUnpin)(sqlite3_pcache*, void*, int discard);
  void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
  void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
  void (*xDestroy)(sqlite3_pcache*);
};

/*
** CAPI3REF: Online Backup Object
**
** The sqlite3_backup object records state information about an ongoing
** online backup operation.  ^The sqlite3_backup object is created by
** a call to [sqlite3_backup_init()] and is destroyed by a call to
** [sqlite3_backup_finish()].
**
** See Also: [Using the SQLite Online Backup API]
*/
typedef struct sqlite3_backup sqlite3_backup;

/*
** CAPI3REF: Online Backup API.
**
** The backup API copies the content of one database into another.
** It is useful either for creating backups of databases or
** for copying in-memory databases to or from persistent files. 
**
** See Also: [Using the SQLite Online Backup API]
**
** ^SQLite holds a write transaction open on the destination database file
** for the duration of the backup operation.
** ^The source database is read-locked only while it is being read;
** it is not locked continuously for the entire backup operation.
** ^Thus, the backup may be performed on a live source database without
** preventing other database connections from
** reading or writing to the source database while the backup is underway.
** 
** ^(To perform a backup operation: 
**   <ol>
**     <li><b>sqlite3_backup_init()</b> is called once to initialize the
**         backup, 
**     <li><b>sqlite3_backup_step()</b> is called one or more times to transfer 
**         the data between the two databases, and finally
**     <li><b>sqlite3_backup_finish()</b> is called to release all resources 
**         associated with the backup operation. 
**   </ol>)^
** There should be exactly one call to sqlite3_backup_finish() for each
** successful call to sqlite3_backup_init().
**
** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
**
** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the 
** [database connection] associated with the destination database 
** and the database name, respectively.
** ^The database name is "main" for the main database, "temp" for the
** temporary database, or the name specified after the AS keyword in
** an [ATTACH] statement for an attached database.
** ^The S and M arguments passed to 
** sqlite3_backup_init(D,N,S,M) identify the [database connection]
** and database name of the source database, respectively.
** ^The source and destination [database connections] (parameters S and D)
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
** returned and an error code and error message are stored in the
** destination [database connection] D.
** ^The error code and message for the failed call to sqlite3_backup_init()
** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
** [sqlite3_errmsg16()] functions.
** ^A successful call to sqlite3_backup_init() returns a pointer to an
** [sqlite3_backup] object.
** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and
** sqlite3_backup_finish() functions to perform the specified backup 
** operation.
**
** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
**
** ^Function sqlite3_backup_step(B,N) will copy up to N pages between 
** the source and destination databases specified by [sqlite3_backup] object B.
** ^If N is negative, all remaining source pages are copied. 
** ^If sqlite3_backup_step(B,N) successfully copies N pages and there
** are still more pages to be copied, then the function returns [SQLITE_OK].
** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
** from source to destination, then it returns [SQLITE_DONE].
** ^If an error occurs while running sqlite3_backup_step(B,N),
** then an [error code] is returned. ^As well as [SQLITE_OK] and
** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
**
** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
** <ol>
** <li> the destination database was opened read-only, or
** <li> the destination database is using write-ahead-log journaling
** and the destination and source page sizes differ, or
** <li> the destination database is an in-memory database and the
** destination and source page sizes differ.
** </ol>)^
**
** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
** the [sqlite3_busy_handler | busy-handler function]
** is invoked (if one is specified). ^If the 
** busy-handler returns non-zero before the lock is available, then 
** [SQLITE_BUSY] is returned to the caller. ^In this case the call to
** sqlite3_backup_step() can be retried later. ^If the source
** [database connection]
** is being used to write to the source database when sqlite3_backup_step()
** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this
** case the call to sqlite3_backup_step() can be retried later on. ^(If
** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
** [SQLITE_READONLY] is returned, then 
** there is no point in retrying the call to sqlite3_backup_step(). These 
** errors are considered fatal.)^  The application must accept 
** that the backup operation has failed and pass the backup operation handle 
** to the sqlite3_backup_finish() to release associated resources.
**
** ^The first call to sqlite3_backup_step() obtains an exclusive lock
** on the destination file. ^The exclusive lock is not released until either 
** sqlite3_backup_finish() is called or the backup operation is complete 
** and sqlite3_backup_step() returns [SQLITE_DONE].  ^Every call to
** sqlite3_backup_step() obtains a [shared lock] on the source database that
** lasts for the duration of the sqlite3_backup_step() call.
** ^Because the source database is not locked between calls to
** sqlite3_backup_step(), the source database may be modified mid-way
** through the backup process.  ^If the source database is modified by an
** external process or via a database connection other than the one being
** used by the backup operation, then the backup will be automatically
** restarted by the next call to sqlite3_backup_step(). ^If the source 
** database is modified by the using the same database connection as is used
** by the backup operation, then the backup database is automatically
** updated at the same time.
**
** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
**
** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the 
** application wishes to abandon the backup operation, the application
** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish().
** ^The sqlite3_backup_finish() interfaces releases all
** resources associated with the [sqlite3_backup] object. 
** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any
** active write-transaction on the destination database is rolled back.
** The [sqlite3_backup] object is invalid
** and may not be used following a call to sqlite3_backup_finish().
**
** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
** sqlite3_backup_step() errors occurred, regardless or whether or not
** sqlite3_backup_step() completed.
** ^If an out-of-memory condition or IO error occurred during any prior
** sqlite3_backup_step() call on the same [sqlite3_backup] object, then
** sqlite3_backup_finish() returns the corresponding [error code].
**
** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step()
** is not a permanent error and does not affect the return value of
** sqlite3_backup_finish().
**
** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
**
** ^Each call to sqlite3_backup_step() sets two values inside
** the [sqlite3_backup] object: the number of pages still to be backed
** up and the total number of pages in the source database file.
** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
** retrieve these two values, respectively.
**
** ^The values returned by these functions are only updated by
** sqlite3_backup_step(). ^If the source database is modified during a backup
** operation, then the values are not updated to account for any extra
** pages that need to be updated or the size of the source database file
** changing.
**
** <b>Concurrent Usage of Database Handles</b>
**
** ^The source [database connection] may be used by the application for other
** purposes while a backup operation is underway or being initialized.
** ^If SQLite is compiled and configured to support threadsafe database
** connections, then the source database connection may be used concurrently
** from within other threads.
**
** However, the application must guarantee that the destination 
** [database connection] is not passed to any other API (by any thread) after 
** sqlite3_backup_init() is called and before the corresponding call to
** sqlite3_backup_finish().  SQLite does not currently check to see
** if the application incorrectly accesses the destination [database connection]
** and so no error code is reported, but the operations may malfunction
** nevertheless.  Use of the destination database connection while a
** backup is in progress might also also cause a mutex deadlock.
**
** If running in [shared cache mode], the application must
** guarantee that the shared cache used by the destination database
** is not accessed while the backup is running. In practice this means
** that the application must guarantee that the disk file being 
** backed up to is not accessed by any connection within the process,
** not just the specific connection that was passed to sqlite3_backup_init().
**
** The [sqlite3_backup] object itself is partially threadsafe. Multiple 
** threads may safely make multiple concurrent calls to sqlite3_backup_step().
** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
** APIs are not strictly speaking threadsafe. If they are invoked at the
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
  sqlite3 *pDest,                        /* Destination database handle */
  const char *zDestName,                 /* Destination database name */
  sqlite3 *pSource,                      /* Source database handle */
  const char *zSourceName                /* Source database name */
);
SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);

/*
** CAPI3REF: Unlock Notification
**
** ^When running in shared-cache mode, a database operation may fail with
** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
** individual tables within the shared-cache cannot be obtained. See
** [SQLite Shared-Cache Mode] for a description of shared-cache locking. 
** ^This API may be used to register a callback that SQLite will invoke 
** when the connection currently holding the required lock relinquishes it.
** ^This API is only available if the library was compiled with the
** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
**
** See Also: [Using the SQLite Unlock Notification Feature].
**
** ^Shared-cache locks are released when a database connection concludes
** its current transaction, either by committing it or rolling it back. 
**
** ^When a connection (known as the blocked connection) fails to obtain a
** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
** identity of the database connection (the blocking connection) that
** has locked the required resource is stored internally. ^After an 
** application receives an SQLITE_LOCKED error, it may call the
** sqlite3_unlock_notify() method with the blocked connection handle as 
** the first argument to register for a callback that will be invoked
** when the blocking connections current transaction is concluded. ^The
** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
** call that concludes the blocking connections transaction.
**
** ^(If sqlite3_unlock_notify() is called in a multi-threaded application,
** there is a chance that the blocking connection will have already
** concluded its transaction by the time sqlite3_unlock_notify() is invoked.
** If this happens, then the specified callback is invoked immediately,
** from within the call to sqlite3_unlock_notify().)^
**
** ^If the blocked connection is attempting to obtain a write-lock on a
** shared-cache table, and more than one other connection currently holds
** a read-lock on the same table, then SQLite arbitrarily selects one of 
** the other connections to use as the blocking connection.
**
** ^(There may be at most one unlock-notify callback registered by a 
** blocked connection. If sqlite3_unlock_notify() is called when the
** blocked connection already has a registered unlock-notify callback,
** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is
** called with a NULL pointer as its second argument, then any existing
** unlock-notify callback is canceled. ^The blocked connections 
** unlock-notify callback may also be canceled by closing the blocked
** connection using [sqlite3_close()].
**
** The unlock-notify callback is not reentrant. If an application invokes
** any sqlite3_xxx API functions from within an unlock-notify callback, a
** crash or deadlock may be the result.
**
** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always
** returns SQLITE_OK.
**
** <b>Callback Invocation Details</b>
**
** When an unlock-notify callback is registered, the application provides a 
** single void* pointer that is passed to the callback when it is invoked.
** However, the signature of the callback function allows SQLite to pass
** it an array of void* context pointers. The first argument passed to
** an unlock-notify callback is a pointer to an array of void* pointers,
** and the second is the number of entries in the array.
**
** When a blocking connections transaction is concluded, there may be
** more than one blocked connection that has registered for an unlock-notify
** callback. ^If two or more such blocked connections have specified the
** same callback function, then instead of invoking the callback function
** multiple times, it is invoked once with the set of void* context pointers
** specified by the blocked connections bundled together into an array.
** This gives the application an opportunity to prioritize any actions 
** related to the set of unblocked database connections.
**
** <b>Deadlock Detection</b>
**
** Assuming that after registering for an unlock-notify callback a 
** database waits for the callback to be issued before taking any further
** action (a reasonable assumption), then using this API may cause the
** application to deadlock. For example, if connection X is waiting for
** connection Y's transaction to be concluded, and similarly connection
** Y is waiting on connection X's transaction, then neither connection
** will proceed and the system may remain deadlocked indefinitely.
**
** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock
** detection. ^If a given call to sqlite3_unlock_notify() would put the
** system in a deadlocked state, then SQLITE_LOCKED is returned and no
** unlock-notify callback is registered. The system is said to be in
** a deadlocked state if connection A has registered for an unlock-notify
** callback on the conclusion of connection B's transaction, and connection
** B has itself registered for an unlock-notify callback when connection
** A's transaction is concluded. ^Indirect deadlock is also detected, so
** the system is also considered to be deadlocked if connection B has
** registered for an unlock-notify callback on the conclusion of connection
** C's transaction, where connection C is waiting on connection A. ^Any
** number of levels of indirection are allowed.
**
** <b>The "DROP TABLE" Exception</b>
**
** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost 
** always appropriate to call sqlite3_unlock_notify(). There is however,
** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
** SQLite checks if there are any currently executing SELECT statements
** that belong to the same connection. If there are, SQLITE_LOCKED is
** returned. In this case there is no "blocking connection", so invoking
** sqlite3_unlock_notify() results in the unlock-notify callback being
** invoked immediately. If the application then re-attempts the "DROP TABLE"
** or "DROP INDEX" query, an infinite loop might be the result.
**
** One way around this problem is to check the extended error code returned
** by an sqlite3_step() call. ^(If there is a blocking connection, then the
** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
** the special "DROP TABLE/INDEX" case, the extended error code is just 
** SQLITE_LOCKED.)^
*/
SQLITE_API int sqlite3_unlock_notify(
  sqlite3 *pBlocked,                          /* Waiting connection */
  void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
  void *pNotifyArg                            /* Argument to pass to xNotify */
);


/*
** CAPI3REF: String Comparison
**
** ^The [sqlite3_strnicmp()] API allows applications and extensions to
** compare the contents of two buffers containing UTF-8 strings in a
** case-independent fashion, using the same definition of case independence 
** that SQLite uses internally when comparing identifiers.
*/
SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);

/*
** CAPI3REF: Error Logging Interface
**
** ^The [sqlite3_log()] interface writes a message into the error log
** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
** ^If logging is enabled, the zFormat string and subsequent arguments are
** used with [sqlite3_snprintf()] to generate the final output string.
**
** The sqlite3_log() interface is intended for use by extensions such as
** virtual tables, collating functions, and SQL functions.  While there is
** nothing to prevent an application from calling sqlite3_log(), doing so
** is considered bad form.
**
** The zFormat string must not be NULL.
**
** To avoid deadlocks and other threading problems, the sqlite3_log() routine
** will not use dynamically allocated memory.  The log message is stored in
** a fixed-length buffer on the stack.  If the log message is longer than
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);

/*
** CAPI3REF: Write-Ahead Log Commit Hook
**
** ^The [sqlite3_wal_hook()] function is used to register a callback that
** will be invoked each time a database connection commits data to a
** [write-ahead log] (i.e. whenever a transaction is committed in
** [journal_mode | journal_mode=WAL mode]). 
**
** ^The callback is invoked by SQLite after the commit has taken place and 
** the associated write-lock on the database released, so the implementation 
** may read, write or [checkpoint] the database as required.
**
** ^The first parameter passed to the callback function when it is invoked
** is a copy of the third parameter passed to sqlite3_wal_hook() when
** registering the callback. ^The second is a copy of the database handle.
** ^The third parameter is the name of the database that was written to -
** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
** is the number of pages currently in the write-ahead log file,
** including those that were just committed.
**
** The callback function should normally return [SQLITE_OK].  ^If an error
** code is returned, that error will propagate back up through the
** SQLite code base to cause the statement that provoked the callback
** to report an error, though the commit will have still occurred. If the
** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
** that does not correspond to any valid SQLite error code, the results
** are undefined.
**
** A single database handle may have at most a single write-ahead log callback 
** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
** previously registered write-ahead log callback. ^Note that the
** [sqlite3_wal_autocheckpoint()] interface and the
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
** those overwrite any prior [sqlite3_wal_hook()] settings.
*/
SQLITE_API void *sqlite3_wal_hook(
  sqlite3*, 
  int(*)(void *,sqlite3*,const char*,int),
  void*
);

/*
** CAPI3REF: Configure an auto-checkpoint
**
** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
** [sqlite3_wal_hook()] that causes any database on [database connection] D
** to automatically [checkpoint]
** after committing a transaction if there are N or
** more frames in the [write-ahead log] file.  ^Passing zero or 
** a negative value as the nFrame parameter disables automatic
** checkpoints entirely.
**
** ^The callback registered by this function replaces any existing callback
** registered using [sqlite3_wal_hook()].  ^Likewise, registering a callback
** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
** configured by this function.
**
** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
** from SQL.
**
** ^Every new [database connection] defaults to having the auto-checkpoint
** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
** pages.  The use of this interface
** is only necessary if the default setting is found to be suboptimal
** for a particular application.
*/
SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);

/*
** CAPI3REF: Checkpoint a database
**
** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X
** on [database connection] D to be [checkpointed].  ^If X is NULL or an
** empty string, then a checkpoint is run on all databases of
** connection D.  ^If the database connection D is not in
** [WAL | write-ahead log mode] then this interface is a harmless no-op.
**
** ^The [wal_checkpoint pragma] can be used to invoke this interface
** from SQL.  ^The [sqlite3_wal_autocheckpoint()] interface and the
** [wal_autocheckpoint pragma] can be used to cause this interface to be
** run whenever the WAL reaches a certain size threshold.
**
** See also: [sqlite3_wal_checkpoint_v2()]
*/
SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);

/*
** CAPI3REF: Checkpoint a database
**
** Run a checkpoint operation on WAL database zDb attached to database 
** handle db. The specific operation is determined by the value of the 
** eMode parameter:
**
** <dl>
** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
**   Checkpoint as many frames as possible without waiting for any database 
**   readers or writers to finish. Sync the db file if all frames in the log
**   are checkpointed. This mode is the same as calling 
**   sqlite3_wal_checkpoint(). The busy-handler callback is never invoked.
**
** <dt>SQLITE_CHECKPOINT_FULL<dd>
**   This mode blocks (calls the busy-handler callback) until there is no
**   database writer and all readers are reading from the most recent database
**   snapshot. It then checkpoints all frames in the log file and syncs the
**   database file. This call blocks database writers while it is running,
**   but not database readers.
**
** <dt>SQLITE_CHECKPOINT_RESTART<dd>
**   This mode works the same way as SQLITE_CHECKPOINT_FULL, except after 
**   checkpointing the log file it blocks (calls the busy-handler callback)
**   until all readers are reading from the database file only. This ensures 
**   that the next client to write to the database file restarts the log file 
**   from the beginning. This call blocks database writers while it is running,
**   but not database readers.
** </dl>
**
** If pnLog is not NULL, then *pnLog is set to the total number of frames in
** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to
** the total number of checkpointed frames (including any that were already
** checkpointed when this function is called). *pnLog and *pnCkpt may be
** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK.
** If no values are available because of an error, they are both set to -1
** before returning to communicate this to the caller.
**
** All calls obtain an exclusive "checkpoint" lock on the database file. If
** any other process is running a checkpoint operation at the same time, the 
** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a 
** busy-handler configured, it will not be invoked in this case.
**
** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive 
** "writer" lock on the database file. If the writer lock cannot be obtained
** immediately, and a busy-handler is configured, it is invoked and the writer
** lock retried until either the busy-handler returns 0 or the lock is
** successfully obtained. The busy-handler is also invoked while waiting for
** database readers as described above. If the busy-handler returns 0 before
** the writer lock is obtained or while waiting for database readers, the
** checkpoint operation proceeds from that point in the same way as 
** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible 
** without blocking any further. SQLITE_BUSY is returned in this case.
**
** If parameter zDb is NULL or points to a zero length string, then the
** specified operation is attempted on all WAL databases. In this case the
** values written to output parameters *pnLog and *pnCkpt are undefined. If 
** an SQLITE_BUSY error is encountered when processing one or more of the 
** attached WAL databases, the operation is still attempted on any remaining 
** attached databases and SQLITE_BUSY is returned to the caller. If any other 
** error occurs while processing an attached database, processing is abandoned 
** and the error code returned to the caller immediately. If no error 
** (SQLITE_BUSY or otherwise) is encountered while processing the attached 
** databases, SQLITE_OK is returned.
**
** If database zDb is the name of an attached database that is not in WAL
** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If
** zDb is not NULL (or a zero length string) and is not the name of any
** attached database, SQLITE_ERROR is returned to the caller.
*/
SQLITE_API int sqlite3_wal_checkpoint_v2(
  sqlite3 *db,                    /* Database handle */
  const char *zDb,                /* Name of attached database (or NULL) */
  int eMode,                      /* SQLITE_CHECKPOINT_* value */
  int *pnLog,                     /* OUT: Size of WAL log in frames */
  int *pnCkpt                     /* OUT: Total number of frames checkpointed */
);

/*
** CAPI3REF: Checkpoint operation parameters
**
** These constants can be used as the 3rd parameter to
** [sqlite3_wal_checkpoint_v2()].  See the [sqlite3_wal_checkpoint_v2()]
** documentation for additional information about the meaning and use of
** each of these values.
*/
#define SQLITE_CHECKPOINT_PASSIVE 0
#define SQLITE_CHECKPOINT_FULL    1
#define SQLITE_CHECKPOINT_RESTART 2

/*
** CAPI3REF: Virtual Table Interface Configuration
**
** This function may be called by either the [xConnect] or [xCreate] method
** of a [virtual table] implementation to configure
** various facets of the virtual table interface.
**
** If this interface is invoked outside the context of an xConnect or
** xCreate virtual table method then the behavior is undefined.
**
** At present, there is only one option that may be configured using
** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].)  Further options
** may be added in the future.
*/
SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);

/*
** CAPI3REF: Virtual Table Configuration Options
**
** These macros define the various options to the
** [sqlite3_vtab_config()] interface that [virtual table] implementations
** can use to customize and optimize their behavior.
**
** <dl>
** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
** <dd>Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
** where X is an integer.  If X is zero, then the [virtual table] whose
** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
** support constraints.  In this configuration (which is the default) if
** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire
** statement is rolled back as if [ON CONFLICT | OR ABORT] had been
** specified as part of the users SQL statement, regardless of the actual
** ON CONFLICT mode specified.
**
** If X is non-zero, then the virtual table implementation guarantees
** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before
** any modifications to internal or persistent data structures have been made.
** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite 
** is able to roll back a statement or database transaction, and abandon
** or continue processing the current SQL statement as appropriate. 
** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns
** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode
** had been ABORT.
**
** Virtual table implementations that are required to handle OR REPLACE
** must do so within the [xUpdate] method. If a call to the 
** [sqlite3_vtab_on_conflict()] function indicates that the current ON 
** CONFLICT policy is REPLACE, the virtual table implementation should 
** silently replace the appropriate rows within the xUpdate callback and
** return SQLITE_OK. Or, if this is not possible, it may return
** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT 
** constraint handling.
** </dl>
*/
#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1

/*
** CAPI3REF: Determine The Virtual Table Conflict Policy
**
** This function may only be called from within a call to the [xUpdate] method
** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);

/*
** CAPI3REF: Conflict resolution modes
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
** inform a [virtual table] implementation what the [ON CONFLICT] mode
** is for the SQL statement being evaluated.
**
** Note that the [SQLITE_IGNORE] constant is also used as a potential
** return value from the [sqlite3_set_authorizer()] callback and that
** [SQLITE_ABORT] is also a [result code].
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
#define SQLITE_FAIL     3
/* #define SQLITE_ABORT 4  // Also an error code */
#define SQLITE_REPLACE  5



/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif

/*
** 2010 August 30
**
** 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.
**
*************************************************************************
*/

#ifndef _SQLITE3RTREE_H_
#define _SQLITE3RTREE_H_


#ifdef __cplusplus
extern "C" {
#endif

typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;

/*
** Register a geometry callback named zGeom that can be used as part of an
** R-Tree geometry query as follows:
**
**   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
SQLITE_API int sqlite3_rtree_geometry_callback(
  sqlite3 *db,
  const char *zGeom,
  int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
  void *pContext
);


/*
** A pointer to a structure of the following type is passed as the first
** argument to callbacks registered using rtree_geometry_callback().
*/
struct sqlite3_rtree_geometry {
  void *pContext;                 /* Copy of pContext passed to s_r_g_c() */
  int nParam;                     /* Size of array aParam[] */
  double *aParam;                 /* Parameters passed to SQL geom function */
  void *pUser;                    /* Callback implementation user data */
  void (*xDelUser)(void *);       /* Called by SQLite to clean up pUser */
};


#ifdef __cplusplus
}  /* end of the 'extern "C"' block */
#endif

#endif  /* ifndef _SQLITE3RTREE_H_ */

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/src/core/sqlite3ext.h.
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
/*
** 2006 June 7
**
** 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 header file defines the SQLite interface for use by
** shared libraries that want to be imported as extensions into
** an SQLite instance.  Shared libraries that intend to be loaded
** as extensions by SQLite should #include this file instead of 
** sqlite3.h.
*/
#ifndef _SQLITE3EXT_H_
#define _SQLITE3EXT_H_
#include "sqlite3.h"

typedef struct sqlite3_api_routines sqlite3_api_routines;

/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING:  In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only.  If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each others' shared
** libraries!
*/
struct sqlite3_api_routines {
  void * (*aggregate_context)(sqlite3_context*,int nBytes);
  int  (*aggregate_count)(sqlite3_context*);
  int  (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
  int  (*bind_double)(sqlite3_stmt*,int,double);
  int  (*bind_int)(sqlite3_stmt*,int,int);
  int  (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
  int  (*bind_null)(sqlite3_stmt*,int);
  int  (*bind_parameter_count)(sqlite3_stmt*);
  int  (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
  const char * (*bind_parameter_name)(sqlite3_stmt*,int);
  int  (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
  int  (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
  int  (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
  int  (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
  int  (*busy_timeout)(sqlite3*,int ms);
  int  (*changes)(sqlite3*);
  int  (*close)(sqlite3*);
  int  (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
                           int eTextRep,const char*));
  int  (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
                             int eTextRep,const void*));
  const void * (*column_blob)(sqlite3_stmt*,int iCol);
  int  (*column_bytes)(sqlite3_stmt*,int iCol);
  int  (*column_bytes16)(sqlite3_stmt*,int iCol);
  int  (*column_count)(sqlite3_stmt*pStmt);
  const char * (*column_database_name)(sqlite3_stmt*,int);
  const void * (*column_database_name16)(sqlite3_stmt*,int);
  const char * (*column_decltype)(sqlite3_stmt*,int i);
  const void * (*column_decltype16)(sqlite3_stmt*,int);
  double  (*column_double)(sqlite3_stmt*,int iCol);
  int  (*column_int)(sqlite3_stmt*,int iCol);
  sqlite_int64  (*column_int64)(sqlite3_stmt*,int iCol);
  const char * (*column_name)(sqlite3_stmt*,int);
  const void * (*column_name16)(sqlite3_stmt*,int);
  const char * (*column_origin_name)(sqlite3_stmt*,int);
  const void * (*column_origin_name16)(sqlite3_stmt*,int);
  const char * (*column_table_name)(sqlite3_stmt*,int);
  const void * (*column_table_name16)(sqlite3_stmt*,int);
  const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
  const void * (*column_text16)(sqlite3_stmt*,int iCol);
  int  (*column_type)(sqlite3_stmt*,int iCol);
  sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
  void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
  int  (*complete)(const char*sql);
  int  (*complete16)(const void*sql);
  int  (*create_collation)(sqlite3*,const char*,int,void*,
                           int(*)(void*,int,const void*,int,const void*));
  int  (*create_collation16)(sqlite3*,const void*,int,void*,
                             int(*)(void*,int,const void*,int,const void*));
  int  (*create_function)(sqlite3*,const char*,int,int,void*,
                          void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
                          void (*xStep)(sqlite3_context*,int,sqlite3_value**),
                          void (*xFinal)(sqlite3_context*));
  int  (*create_function16)(sqlite3*,const void*,int,int,void*,
                            void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
                            void (*xFinal)(sqlite3_context*));
  int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
  int  (*data_count)(sqlite3_stmt*pStmt);
  sqlite3 * (*db_handle)(sqlite3_stmt*);
  int (*declare_vtab)(sqlite3*,const char*);
  int  (*enable_shared_cache)(int);
  int  (*errcode)(sqlite3*db);
  const char * (*errmsg)(sqlite3*);
  const void * (*errmsg16)(sqlite3*);
  int  (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
  int  (*expired)(sqlite3_stmt*);
  int  (*finalize)(sqlite3_stmt*pStmt);
  void  (*free)(void*);
  void  (*free_table)(char**result);
  int  (*get_autocommit)(sqlite3*);
  void * (*get_auxdata)(sqlite3_context*,int);
  int  (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
  int  (*global_recover)(void);
  void  (*interruptx)(sqlite3*);
  sqlite_int64  (*last_insert_rowid)(sqlite3*);
  const char * (*libversion)(void);
  int  (*libversion_number)(void);
  void *(*malloc)(int);
  char * (*mprintf)(const char*,...);
  int  (*open)(const char*,sqlite3**);
  int  (*open16)(const void*,sqlite3**);
  int  (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
  int  (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
  void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
  void  (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
  void *(*realloc)(void*,int);
  int  (*reset)(sqlite3_stmt*pStmt);
  void  (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
  void  (*result_double)(sqlite3_context*,double);
  void  (*result_error)(sqlite3_context*,const char*,int);
  void  (*result_error16)(sqlite3_context*,const void*,int);
  void  (*result_int)(sqlite3_context*,int);
  void  (*result_int64)(sqlite3_context*,sqlite_int64);
  void  (*result_null)(sqlite3_context*);
  void  (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
  void  (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
  void  (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
  void  (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
  void  (*result_value)(sqlite3_context*,sqlite3_value*);
  void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
  int  (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
                         const char*,const char*),void*);
  void  (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
  char * (*snprintf)(int,char*,const char*,...);
  int  (*step)(sqlite3_stmt*);
  int  (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
                                char const**,char const**,int*,int*,int*);
  void  (*thread_cleanup)(void);
  int  (*total_changes)(sqlite3*);
  void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
  int  (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
  void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
                                         sqlite_int64),void*);
  void * (*user_data)(sqlite3_context*);
  const void * (*value_blob)(sqlite3_value*);
  int  (*value_bytes)(sqlite3_value*);
  int  (*value_bytes16)(sqlite3_value*);
  double  (*value_double)(sqlite3_value*);
  int  (*value_int)(sqlite3_value*);
  sqlite_int64  (*value_int64)(sqlite3_value*);
  int  (*value_numeric_type)(sqlite3_value*);
  const unsigned char * (*value_text)(sqlite3_value*);
  const void * (*value_text16)(sqlite3_value*);
  const void * (*value_text16be)(sqlite3_value*);
  const void * (*value_text16le)(sqlite3_value*);
  int  (*value_type)(sqlite3_value*);
  char *(*vmprintf)(const char*,va_list);
  /* Added ??? */
  int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
  /* Added by 3.3.13 */
  int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
  int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
  int (*clear_bindings)(sqlite3_stmt*);
  /* Added by 3.4.1 */
  int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
                          void (*xDestroy)(void *));
  /* Added by 3.5.0 */
  int (*bind_zeroblob)(sqlite3_stmt*,int,int);
  int (*blob_bytes)(sqlite3_blob*);
  int (*blob_close)(sqlite3_blob*);
  int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
                   int,sqlite3_blob**);
  int (*blob_read)(sqlite3_blob*,void*,int,int);
  int (*blob_write)(sqlite3_blob*,const void*,int,int);
  int (*create_collation_v2)(sqlite3*,const char*,int,void*,
                             int(*)(void*,int,const void*,int,const void*),
                             void(*)(void*));
  int (*file_control)(sqlite3*,const char*,int,void*);
  sqlite3_int64 (*memory_highwater)(int);
  sqlite3_int64 (*memory_used)(void);
  sqlite3_mutex *(*mutex_alloc)(int);
  void (*mutex_enter)(sqlite3_mutex*);
  void (*mutex_free)(sqlite3_mutex*);
  void (*mutex_leave)(sqlite3_mutex*);
  int (*mutex_try)(sqlite3_mutex*);
  int (*open_v2)(const char*,sqlite3**,int,const char*);
  int (*release_memory)(int);
  void (*result_error_nomem)(sqlite3_context*);
  void (*result_error_toobig)(sqlite3_context*);
  int (*sleep)(int);
  void (*soft_heap_limit)(int);
  sqlite3_vfs *(*vfs_find)(const char*);
  int (*vfs_register)(sqlite3_vfs*,int);
  int (*vfs_unregister)(sqlite3_vfs*);
  int (*xthreadsafe)(void);
  void (*result_zeroblob)(sqlite3_context*,int);
  void (*result_error_code)(sqlite3_context*,int);
  int (*test_control)(int, ...);
  void (*randomness)(int,void*);
  sqlite3 *(*context_db_handle)(sqlite3_context*);
  int (*extended_result_codes)(sqlite3*,int);
  int (*limit)(sqlite3*,int,int);
  sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
  const char *(*sql)(sqlite3_stmt*);
  int (*status)(int,int*,int*,int);
  int (*backup_finish)(sqlite3_backup*);
  sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
  int (*backup_pagecount)(sqlite3_backup*);
  int (*backup_remaining)(sqlite3_backup*);
  int (*backup_step)(sqlite3_backup*,int);
  const char *(*compileoption_get)(int);
  int (*compileoption_used)(const char*);
  int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
                            void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
                            void (*xFinal)(sqlite3_context*),
                            void(*xDestroy)(void*));
  int (*db_config)(sqlite3*,int,...);
  sqlite3_mutex *(*db_mutex)(sqlite3*);
  int (*db_status)(sqlite3*,int,int*,int*,int);
  int (*extended_errcode)(sqlite3*);
  void (*log)(int,const char*,...);
  sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
  const char *(*sourceid)(void);
  int (*stmt_status)(sqlite3_stmt*,int,int);
  int (*strnicmp)(const char*,const char*,int);
  int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
  int (*wal_autocheckpoint)(sqlite3*,int);
  int (*wal_checkpoint)(sqlite3*,const char*);
  void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
  int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
  int (*vtab_config)(sqlite3*,int op,...);
  int (*vtab_on_conflict)(sqlite3*);
};

/*
** The following macros redefine the API routines so that they are
** redirected throught the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
** (part of the main SQLite library - not an extension) so that
** it can get access to the sqlite3_api_routines structure
** definition.  But the main library does not want to redefine
** the API.  So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
#ifndef SQLITE_CORE
#define sqlite3_aggregate_context      sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count        sqlite3_api->aggregate_count
#endif
#define sqlite3_bind_blob              sqlite3_api->bind_blob
#define sqlite3_bind_double            sqlite3_api->bind_double
#define sqlite3_bind_int               sqlite3_api->bind_int
#define sqlite3_bind_int64             sqlite3_api->bind_int64
#define sqlite3_bind_null              sqlite3_api->bind_null
#define sqlite3_bind_parameter_count   sqlite3_api->bind_parameter_count
#define sqlite3_bind_parameter_index   sqlite3_api->bind_parameter_index
#define sqlite3_bind_parameter_name    sqlite3_api->bind_parameter_name
#define sqlite3_bind_text              sqlite3_api->bind_text
#define sqlite3_bind_text16            sqlite3_api->bind_text16
#define sqlite3_bind_value             sqlite3_api->bind_value
#define sqlite3_busy_handler           sqlite3_api->busy_handler
#define sqlite3_busy_timeout           sqlite3_api->busy_timeout
#define sqlite3_changes                sqlite3_api->changes
#define sqlite3_close                  sqlite3_api->close
#define sqlite3_collation_needed       sqlite3_api->collation_needed
#define sqlite3_collation_needed16     sqlite3_api->collation_needed16
#define sqlite3_column_blob            sqlite3_api->column_blob
#define sqlite3_column_bytes           sqlite3_api->column_bytes
#define sqlite3_column_bytes16         sqlite3_api->column_bytes16
#define sqlite3_column_count           sqlite3_api->column_count
#define sqlite3_column_database_name   sqlite3_api->column_database_name
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
#define sqlite3_column_decltype        sqlite3_api->column_decltype
#define sqlite3_column_decltype16      sqlite3_api->column_decltype16
#define sqlite3_column_double          sqlite3_api->column_double
#define sqlite3_column_int             sqlite3_api->column_int
#define sqlite3_column_int64           sqlite3_api->column_int64
#define sqlite3_column_name            sqlite3_api->column_name
#define sqlite3_column_name16          sqlite3_api->column_name16
#define sqlite3_column_origin_name     sqlite3_api->column_origin_name
#define sqlite3_column_origin_name16   sqlite3_api->column_origin_name16
#define sqlite3_column_table_name      sqlite3_api->column_table_name
#define sqlite3_column_table_name16    sqlite3_api->column_table_name16
#define sqlite3_column_text            sqlite3_api->column_text
#define sqlite3_column_text16          sqlite3_api->column_text16
#define sqlite3_column_type            sqlite3_api->column_type
#define sqlite3_column_value           sqlite3_api->column_value
#define sqlite3_commit_hook            sqlite3_api->commit_hook
#define sqlite3_complete               sqlite3_api->complete
#define sqlite3_complete16             sqlite3_api->complete16
#define sqlite3_create_collation       sqlite3_api->create_collation
#define sqlite3_create_collation16     sqlite3_api->create_collation16
#define sqlite3_create_function        sqlite3_api->create_function
#define sqlite3_create_function16      sqlite3_api->create_function16
#define sqlite3_create_module          sqlite3_api->create_module
#define sqlite3_create_module_v2       sqlite3_api->create_module_v2
#define sqlite3_data_count             sqlite3_api->data_count
#define sqlite3_db_handle              sqlite3_api->db_handle
#define sqlite3_declare_vtab           sqlite3_api->declare_vtab
#define sqlite3_enable_shared_cache    sqlite3_api->enable_shared_cache
#define sqlite3_errcode                sqlite3_api->errcode
#define sqlite3_errmsg                 sqlite3_api->errmsg
#define sqlite3_errmsg16               sqlite3_api->errmsg16
#define sqlite3_exec                   sqlite3_api->exec
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_expired                sqlite3_api->expired
#endif
#define sqlite3_finalize               sqlite3_api->finalize
#define sqlite3_free                   sqlite3_api->free
#define sqlite3_free_table             sqlite3_api->free_table
#define sqlite3_get_autocommit         sqlite3_api->get_autocommit
#define sqlite3_get_auxdata            sqlite3_api->get_auxdata
#define sqlite3_get_table              sqlite3_api->get_table
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_global_recover         sqlite3_api->global_recover
#endif
#define sqlite3_interrupt              sqlite3_api->interruptx
#define sqlite3_last_insert_rowid      sqlite3_api->last_insert_rowid
#define sqlite3_libversion             sqlite3_api->libversion
#define sqlite3_libversion_number      sqlite3_api->libversion_number
#define sqlite3_malloc                 sqlite3_api->malloc
#define sqlite3_mprintf                sqlite3_api->mprintf
#define sqlite3_open                   sqlite3_api->open
#define sqlite3_open16                 sqlite3_api->open16
#define sqlite3_prepare                sqlite3_api->prepare
#define sqlite3_prepare16              sqlite3_api->prepare16
#define sqlite3_prepare_v2             sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
#define sqlite3_profile                sqlite3_api->profile
#define sqlite3_progress_handler       sqlite3_api->progress_handler
#define sqlite3_realloc                sqlite3_api->realloc
#define sqlite3_reset                  sqlite3_api->reset
#define sqlite3_result_blob            sqlite3_api->result_blob
#define sqlite3_result_double          sqlite3_api->result_double
#define sqlite3_result_error           sqlite3_api->result_error
#define sqlite3_result_error16         sqlite3_api->result_error16
#define sqlite3_result_int             sqlite3_api->result_int
#define sqlite3_result_int64           sqlite3_api->result_int64
#define sqlite3_result_null            sqlite3_api->result_null
#define sqlite3_result_text            sqlite3_api->result_text
#define sqlite3_result_text16          sqlite3_api->result_text16
#define sqlite3_result_text16be        sqlite3_api->result_text16be
#define sqlite3_result_text16le        sqlite3_api->result_text16le
#define sqlite3_result_value           sqlite3_api->result_value
#define sqlite3_rollback_hook          sqlite3_api->rollback_hook
#define sqlite3_set_authorizer         sqlite3_api->set_authorizer
#define sqlite3_set_auxdata            sqlite3_api->set_auxdata
#define sqlite3_snprintf               sqlite3_api->snprintf
#define sqlite3_step                   sqlite3_api->step
#define sqlite3_table_column_metadata  sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup         sqlite3_api->thread_cleanup
#define sqlite3_total_changes          sqlite3_api->total_changes
#define sqlite3_trace                  sqlite3_api->trace
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_transfer_bindings      sqlite3_api->transfer_bindings
#endif
#define sqlite3_update_hook            sqlite3_api->update_hook
#define sqlite3_user_data              sqlite3_api->user_data
#define sqlite3_value_blob             sqlite3_api->value_blob
#define sqlite3_value_bytes            sqlite3_api->value_bytes
#define sqlite3_value_bytes16          sqlite3_api->value_bytes16
#define sqlite3_value_double           sqlite3_api->value_double
#define sqlite3_value_int              sqlite3_api->value_int
#define sqlite3_value_int64            sqlite3_api->value_int64
#define sqlite3_value_numeric_type     sqlite3_api->value_numeric_type
#define sqlite3_value_text             sqlite3_api->value_text
#define sqlite3_value_text16           sqlite3_api->value_text16
#define sqlite3_value_text16be         sqlite3_api->value_text16be
#define sqlite3_value_text16le         sqlite3_api->value_text16le
#define sqlite3_value_type             sqlite3_api->value_type
#define sqlite3_vmprintf               sqlite3_api->vmprintf
#define sqlite3_overload_function      sqlite3_api->overload_function
#define sqlite3_prepare_v2             sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings         sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob          sqlite3_api->bind_zeroblob
#define sqlite3_blob_bytes             sqlite3_api->blob_bytes
#define sqlite3_blob_close             sqlite3_api->blob_close
#define sqlite3_blob_open              sqlite3_api->blob_open
#define sqlite3_blob_read              sqlite3_api->blob_read
#define sqlite3_blob_write             sqlite3_api->blob_write
#define sqlite3_create_collation_v2    sqlite3_api->create_collation_v2
#define sqlite3_file_control           sqlite3_api->file_control
#define sqlite3_memory_highwater       sqlite3_api->memory_highwater
#define sqlite3_memory_used            sqlite3_api->memory_used
#define sqlite3_mutex_alloc            sqlite3_api->mutex_alloc
#define sqlite3_mutex_enter            sqlite3_api->mutex_enter
#define sqlite3_mutex_free             sqlite3_api->mutex_free
#define sqlite3_mutex_leave            sqlite3_api->mutex_leave
#define sqlite3_mutex_try              sqlite3_api->mutex_try
#define sqlite3_open_v2                sqlite3_api->open_v2
#define sqlite3_release_memory         sqlite3_api->release_memory
#define sqlite3_result_error_nomem     sqlite3_api->result_error_nomem
#define sqlite3_result_error_toobig    sqlite3_api->result_error_toobig
#define sqlite3_sleep                  sqlite3_api->sleep
#define sqlite3_soft_heap_limit        sqlite3_api->soft_heap_limit
#define sqlite3_vfs_find               sqlite3_api->vfs_find
#define sqlite3_vfs_register           sqlite3_api->vfs_register
#define sqlite3_vfs_unregister         sqlite3_api->vfs_unregister
#define sqlite3_threadsafe             sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob        sqlite3_api->result_zeroblob
#define sqlite3_result_error_code      sqlite3_api->result_error_code
#define sqlite3_test_control           sqlite3_api->test_control
#define sqlite3_randomness             sqlite3_api->randomness
#define sqlite3_context_db_handle      sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes  sqlite3_api->extended_result_codes
#define sqlite3_limit                  sqlite3_api->limit
#define sqlite3_next_stmt              sqlite3_api->next_stmt
#define sqlite3_sql                    sqlite3_api->sql
#define sqlite3_status                 sqlite3_api->status
#define sqlite3_backup_finish          sqlite3_api->backup_finish
#define sqlite3_backup_init            sqlite3_api->backup_init
#define sqlite3_backup_pagecount       sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining       sqlite3_api->backup_remaining
#define sqlite3_backup_step            sqlite3_api->backup_step
#define sqlite3_compileoption_get      sqlite3_api->compileoption_get
#define sqlite3_compileoption_used     sqlite3_api->compileoption_used
#define sqlite3_create_function_v2     sqlite3_api->create_function_v2
#define sqlite3_db_config              sqlite3_api->db_config
#define sqlite3_db_mutex               sqlite3_api->db_mutex
#define sqlite3_db_status              sqlite3_api->db_status
#define sqlite3_extended_errcode       sqlite3_api->extended_errcode
#define sqlite3_log                    sqlite3_api->log
#define sqlite3_soft_heap_limit64      sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid               sqlite3_api->sourceid
#define sqlite3_stmt_status            sqlite3_api->stmt_status
#define sqlite3_strnicmp               sqlite3_api->strnicmp
#define sqlite3_unlock_notify          sqlite3_api->unlock_notify
#define sqlite3_wal_autocheckpoint     sqlite3_api->wal_autocheckpoint
#define sqlite3_wal_checkpoint         sqlite3_api->wal_checkpoint
#define sqlite3_wal_hook               sqlite3_api->wal_hook
#define sqlite3_blob_reopen            sqlite3_api->blob_reopen
#define sqlite3_vtab_config            sqlite3_api->vtab_config
#define sqlite3_vtab_on_conflict       sqlite3_api->vtab_on_conflict
#endif /* SQLITE_CORE */

#define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api = 0;
#define SQLITE_EXTENSION_INIT2(v)  sqlite3_api = v;

#endif /* _SQLITE3EXT_H_ */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































Added SQLite.Interop/src/date.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
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
/*
** 2003 October 31
**
** 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 file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.1 2005/03/01 16:04:28 rmsimpson Exp $
**
** NOTES:
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
**
** 1970-01-01 00:00:00 is JD 2440587.5
** 2000-01-01 00:00:00 is JD 2451544.5
**
** This implemention requires years to be expressed as a 4-digit number
** which means that only dates between 0000-01-01 and 9999-12-31 can
** be represented, even though julian day numbers allow a much wider
** range of dates.
**
** The Gregorian calendar system is used for all dates and times,
** even those that predate the Gregorian calendar.  Historians usually
** use the Julian calendar for dates prior to 1582-10-15 and for some
** dates afterwards, depending on locale.  Beware of this difference.
**
** The conversion algorithms are implemented based on descriptions
** in the following text:
**
**      Jean Meeus
**      Astronomical Algorithms, 2nd Edition, 1998
**      ISBM 0-943396-61-1
**      Willmann-Bell, Inc
**      Richmond, Virginia (USA)
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>

#ifndef SQLITE_OMIT_DATETIME_FUNCS

/*
** A structure for holding a single date and time.
*/
typedef struct DateTime DateTime;
struct DateTime {
  double rJD;      /* The julian day number */
  int Y, M, D;     /* Year, month, and day */
  int h, m;        /* Hour and minutes */
  int tz;          /* Timezone offset in minutes */
  double s;        /* Seconds */
  char validYMD;   /* True if Y,M,D are valid */
  char validHMS;   /* True if h,m,s are valid */
  char validJD;    /* True if rJD is valid */
  char validTZ;    /* True if tz is valid */
};


/*
** Convert zDate into one or more integers.  Additional arguments
** come in groups of 5 as follows:
**
**       N       number of digits in the integer
**       min     minimum allowed value of the integer
**       max     maximum allowed value of the integer
**       nextC   first character after the integer
**       pVal    where to write the integers value.
**
** Conversions continue until one with nextC==0 is encountered.
** The function returns the number of successful conversions.
*/
static int getDigits(const char *zDate, ...){
  va_list ap;
  int val;
  int N;
  int min;
  int max;
  int nextC;
  int *pVal;
  int cnt = 0;
  va_start(ap, zDate);
  do{
    N = va_arg(ap, int);
    min = va_arg(ap, int);
    max = va_arg(ap, int);
    nextC = va_arg(ap, int);
    pVal = va_arg(ap, int*);
    val = 0;
    while( N-- ){
      if( !isdigit(*(u8*)zDate) ){
        return cnt;
      }
      val = val*10 + *zDate - '0';
      zDate++;
    }
    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
      return cnt;
    }
    *pVal = val;
    zDate++;
    cnt++;
  }while( nextC );
  return cnt;
}

/*
** Read text from z[] and convert into a floating point number.  Return
** the number of digits converted.
*/
static int getValue(const char *z, double *pR){
  const char *zEnd;
  *pR = sqlite3AtoF(z, &zEnd);
  return zEnd - z;
}

/*
** Parse a timezone extension on the end of a date-time.
** The extension is of the form:
**
**        (+/-)HH:MM
**
** If the parse is successful, write the number of minutes
** of change in *pnMin and return 0.  If a parser error occurs,
** return 0.
**
** A missing specifier is not considered an error.
*/
static int parseTimezone(const char *zDate, DateTime *p){
  int sgn = 0;
  int nHr, nMn;
  while( isspace(*(u8*)zDate) ){ zDate++; }
  p->tz = 0;
  if( *zDate=='-' ){
    sgn = -1;
  }else if( *zDate=='+' ){
    sgn = +1;
  }else{
    return *zDate!=0;
  }
  zDate++;
  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
    return 1;
  }
  zDate += 5;
  p->tz = sgn*(nMn + nHr*60);
  while( isspace(*(u8*)zDate) ){ zDate++; }
  return *zDate!=0;
}

/*
** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
** The HH, MM, and SS must each be exactly 2 digits.  The
** fractional seconds FFFF can be one or more digits.
**
** Return 1 if there is a parsing error and 0 on success.
*/
static int parseHhMmSs(const char *zDate, DateTime *p){
  int h, m, s;
  double ms = 0.0;
  if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
    return 1;
  }
  zDate += 5;
  if( *zDate==':' ){
    zDate++;
    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
      return 1;
    }
    zDate += 2;
    if( *zDate=='.' && isdigit((u8)zDate[1]) ){
      double rScale = 1.0;
      zDate++;
      while( isdigit(*(u8*)zDate) ){
        ms = ms*10.0 + *zDate - '0';
        rScale *= 10.0;
        zDate++;
      }
      ms /= rScale;
    }
  }else{
    s = 0;
  }
  p->validJD = 0;
  p->validHMS = 1;
  p->h = h;
  p->m = m;
  p->s = s + ms;
  if( parseTimezone(zDate, p) ) return 1;
  p->validTZ = p->tz!=0;
  return 0;
}

/*
** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume
** that the YYYY-MM-DD is according to the Gregorian calendar.
**
** Reference:  Meeus page 61
*/
static void computeJD(DateTime *p){
  int Y, M, D, A, B, X1, X2;

  if( p->validJD ) return;
  if( p->validYMD ){
    Y = p->Y;
    M = p->M;
    D = p->D;
  }else{
    Y = 2000;  /* If no YMD specified, assume 2000-Jan-01 */
    M = 1;
    D = 1;
  }
  if( M<=2 ){
    Y--;
    M += 12;
  }
  A = Y/100;
  B = 2 - A + (A/4);
  X1 = 365.25*(Y+4716);
  X2 = 30.6001*(M+1);
  p->rJD = X1 + X2 + D + B - 1524.5;
  p->validJD = 1;
  p->validYMD = 0;
  if( p->validHMS ){
    p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
    if( p->validTZ ){
      p->rJD += p->tz*60/86400.0;
      p->validHMS = 0;
      p->validTZ = 0;
    }
  }
}

/*
** Parse dates of the form
**
**     YYYY-MM-DD HH:MM:SS.FFF
**     YYYY-MM-DD HH:MM:SS
**     YYYY-MM-DD HH:MM
**     YYYY-MM-DD
**
** Write the result into the DateTime structure and return 0
** on success and 1 if the input string is not a well-formed
** date.
*/
static int parseYyyyMmDd(const char *zDate, DateTime *p){
  int Y, M, D, neg;

  if( zDate[0]=='-' ){
    zDate++;
    neg = 1;
  }else{
    neg = 0;
  }
  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
    return 1;
  }
  zDate += 10;
  while( isspace(*(u8*)zDate) ){ zDate++; }
  if( parseHhMmSs(zDate, p)==0 ){
    /* We got the time */
  }else if( *zDate==0 ){
    p->validHMS = 0;
  }else{
    return 1;
  }
  p->validJD = 0;
  p->validYMD = 1;
  p->Y = neg ? -Y : Y;
  p->M = M;
  p->D = D;
  if( p->validTZ ){
    computeJD(p);
  }
  return 0;
}

/*
** Attempt to parse the given string into a Julian Day Number.  Return
** the number of errors.
**
** The following are acceptable forms for the input string:
**
**      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
**      DDDD.DD 
**      now
**
** In the first form, the +/-HH:MM is always optional.  The fractional
** seconds extension (the ".FFF") is optional.  The seconds portion
** (":SS.FFF") is option.  The year and date can be omitted as long
** as there is a time string.  The time string can be omitted as long
** as there is a year and date.
*/
static int parseDateOrTime(const char *zDate, DateTime *p){
  memset(p, 0, sizeof(*p));
  if( parseYyyyMmDd(zDate,p)==0 ){
    return 0;
  }else if( parseHhMmSs(zDate, p)==0 ){
    return 0;
  }else if( sqlite3StrICmp(zDate,"now")==0){
    double r;
    sqlite3OsCurrentTime(&r);
    p->rJD = r;
    p->validJD = 1;
    return 0;
  }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){
    p->rJD = sqlite3AtoF(zDate, 0);
    p->validJD = 1;
    return 0;
  }
  return 1;
}

/*
** Compute the Year, Month, and Day from the julian day number.
*/
static void computeYMD(DateTime *p){
  int Z, A, B, C, D, E, X1;
  if( p->validYMD ) return;
  if( !p->validJD ){
    p->Y = 2000;
    p->M = 1;
    p->D = 1;
  }else{
    Z = p->rJD + 0.5;
    A = (Z - 1867216.25)/36524.25;
    A = Z + 1 + A - (A/4);
    B = A + 1524;
    C = (B - 122.1)/365.25;
    D = 365.25*C;
    E = (B-D)/30.6001;
    X1 = 30.6001*E;
    p->D = B - D - X1;
    p->M = E<14 ? E-1 : E-13;
    p->Y = p->M>2 ? C - 4716 : C - 4715;
  }
  p->validYMD = 1;
}

/*
** Compute the Hour, Minute, and Seconds from the julian day number.
*/
static void computeHMS(DateTime *p){
  int Z, s;
  if( p->validHMS ) return;
  Z = p->rJD + 0.5;
  s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5;
  p->s = 0.001*s;
  s = p->s;
  p->s -= s;
  p->h = s/3600;
  s -= p->h*3600;
  p->m = s/60;
  p->s += s - p->m*60;
  p->validHMS = 1;
}

/*
** Compute both YMD and HMS
*/
static void computeYMD_HMS(DateTime *p){
  computeYMD(p);
  computeHMS(p);
}

/*
** Clear the YMD and HMS and the TZ
*/
static void clearYMD_HMS_TZ(DateTime *p){
  p->validYMD = 0;
  p->validHMS = 0;
  p->validTZ = 0;
}

/*
** Compute the difference (in days) between localtime and UTC (a.k.a. GMT)
** for the time value p where p is in UTC.
*/
static double localtimeOffset(DateTime *p){
  DateTime x, y;
  time_t t;
  struct tm *pTm;
  x = *p;
  computeYMD_HMS(&x);
  if( x.Y<1971 || x.Y>=2038 ){
    x.Y = 2000;
    x.M = 1;
    x.D = 1;
    x.h = 0;
    x.m = 0;
    x.s = 0.0;
  } else {
    int s = x.s + 0.5;
    x.s = s;
  }
  x.tz = 0;
  x.validJD = 0;
  computeJD(&x);
  t = (x.rJD-2440587.5)*86400.0 + 0.5;
  sqlite3OsEnterMutex();
  pTm = localtime(&t);
  y.Y = pTm->tm_year + 1900;
  y.M = pTm->tm_mon + 1;
  y.D = pTm->tm_mday;
  y.h = pTm->tm_hour;
  y.m = pTm->tm_min;
  y.s = pTm->tm_sec;
  sqlite3OsLeaveMutex();
  y.validYMD = 1;
  y.validHMS = 1;
  y.validJD = 0;
  y.validTZ = 0;
  computeJD(&y);
  return y.rJD - x.rJD;
}

/*
** Process a modifier to a date-time stamp.  The modifiers are
** as follows:
**
**     NNN days
**     NNN hours
**     NNN minutes
**     NNN.NNNN seconds
**     NNN months
**     NNN years
**     start of month
**     start of year
**     start of week
**     start of day
**     weekday N
**     unixepoch
**     localtime
**     utc
**
** Return 0 on success and 1 if there is any kind of error.
*/
static int parseModifier(const char *zMod, DateTime *p){
  int rc = 1;
  int n;
  double r;
  char *z, zBuf[30];
  z = zBuf;
  for(n=0; n<sizeof(zBuf)-1 && zMod[n]; n++){
    z[n] = tolower(zMod[n]);
  }
  z[n] = 0;
  switch( z[0] ){
    case 'l': {
      /*    localtime
      **
      ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
      ** show local time.
      */
      if( strcmp(z, "localtime")==0 ){
        computeJD(p);
        p->rJD += localtimeOffset(p);
        clearYMD_HMS_TZ(p);
        rc = 0;
      }
      break;
    }
    case 'u': {
      /*
      **    unixepoch
      **
      ** Treat the current value of p->rJD as the number of
      ** seconds since 1970.  Convert to a real julian day number.
      */
      if( strcmp(z, "unixepoch")==0 && p->validJD ){
        p->rJD = p->rJD/86400.0 + 2440587.5;
        clearYMD_HMS_TZ(p);
        rc = 0;
      }else if( strcmp(z, "utc")==0 ){
        double c1;
        computeJD(p);
        c1 = localtimeOffset(p);
        p->rJD -= c1;
        clearYMD_HMS_TZ(p);
        p->rJD += c1 - localtimeOffset(p);
        rc = 0;
      }
      break;
    }
    case 'w': {
      /*
      **    weekday N
      **
      ** Move the date to the same time on the next occurrence of
      ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
      ** date is already on the appropriate weekday, this is a no-op.
      */
      if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
                 && (n=r)==r && n>=0 && r<7 ){
        int Z;
        computeYMD_HMS(p);
        p->validTZ = 0;
        p->validJD = 0;
        computeJD(p);
        Z = p->rJD + 1.5;
        Z %= 7;
        if( Z>n ) Z -= 7;
        p->rJD += n - Z;
        clearYMD_HMS_TZ(p);
        rc = 0;
      }
      break;
    }
    case 's': {
      /*
      **    start of TTTTT
      **
      ** Move the date backwards to the beginning of the current day,
      ** or month or year.
      */
      if( strncmp(z, "start of ", 9)!=0 ) break;
      z += 9;
      computeYMD(p);
      p->validHMS = 1;
      p->h = p->m = 0;
      p->s = 0.0;
      p->validTZ = 0;
      p->validJD = 0;
      if( strcmp(z,"month")==0 ){
        p->D = 1;
        rc = 0;
      }else if( strcmp(z,"year")==0 ){
        computeYMD(p);
        p->M = 1;
        p->D = 1;
        rc = 0;
      }else if( strcmp(z,"day")==0 ){
        rc = 0;
      }
      break;
    }
    case '+':
    case '-':
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9': {
      n = getValue(z, &r);
      if( n<=0 ) break;
      if( z[n]==':' ){
        /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
        ** specified number of hours, minutes, seconds, and fractional seconds
        ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
        ** omitted.
        */
        const char *z2 = z;
        DateTime tx;
        int day;
        if( !isdigit(*(u8*)z2) ) z2++;
        memset(&tx, 0, sizeof(tx));
        if( parseHhMmSs(z2, &tx) ) break;
        computeJD(&tx);
        tx.rJD -= 0.5;
        day = (int)tx.rJD;
        tx.rJD -= day;
        if( z[0]=='-' ) tx.rJD = -tx.rJD;
        computeJD(p);
        clearYMD_HMS_TZ(p);
       p->rJD += tx.rJD;
        rc = 0;
        break;
      }
      z += n;
      while( isspace(*(u8*)z) ) z++;
      n = strlen(z);
      if( n>10 || n<3 ) break;
      if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
      computeJD(p);
      rc = 0;
      if( n==3 && strcmp(z,"day")==0 ){
        p->rJD += r;
      }else if( n==4 && strcmp(z,"hour")==0 ){
        p->rJD += r/24.0;
      }else if( n==6 && strcmp(z,"minute")==0 ){
        p->rJD += r/(24.0*60.0);
      }else if( n==6 && strcmp(z,"second")==0 ){
        p->rJD += r/(24.0*60.0*60.0);
      }else if( n==5 && strcmp(z,"month")==0 ){
        int x, y;
        computeYMD_HMS(p);
        p->M += r;
        x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
        p->Y += x;
        p->M -= x*12;
        p->validJD = 0;
        computeJD(p);
        y = r;
        if( y!=r ){
          p->rJD += (r - y)*30.0;
        }
      }else if( n==4 && strcmp(z,"year")==0 ){
        computeYMD_HMS(p);
        p->Y += r;
        p->validJD = 0;
        computeJD(p);
      }else{
        rc = 1;
      }
      clearYMD_HMS_TZ(p);
      break;
    }
    default: {
      break;
    }
  }
  return rc;
}

/*
** Process time function arguments.  argv[0] is a date-time stamp.
** argv[1] and following are modifiers.  Parse them all and write
** the resulting time into the DateTime structure p.  Return 0
** on success and 1 if there are any errors.
*/
static int isDate(int argc, sqlite3_value **argv, DateTime *p){
  int i;
  if( argc==0 ) return 1;
  if( SQLITE_NULL==sqlite3_value_type(argv[0]) || 
      parseDateOrTime(sqlite3_value_text(argv[0]), p) ) return 1;
  for(i=1; i<argc; i++){
    if( SQLITE_NULL==sqlite3_value_type(argv[i]) || 
        parseModifier(sqlite3_value_text(argv[i]), p) ) return 1;
  }
  return 0;
}


/*
** The following routines implement the various date and time functions
** of SQLite.
*/

/*
**    julianday( TIMESTRING, MOD, MOD, ...)
**
** Return the julian day number of the date specified in the arguments
*/
static void juliandayFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  if( isDate(argc, argv, &x)==0 ){
    computeJD(&x);
    sqlite3_result_double(context, x.rJD);
  }
}

/*
**    datetime( TIMESTRING, MOD, MOD, ...)
**
** Return YYYY-MM-DD HH:MM:SS
*/
static void datetimeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  if( isDate(argc, argv, &x)==0 ){
    char zBuf[100];
    computeYMD_HMS(&x);
    sprintf(zBuf, "%04d-%02d-%02d %02d:%02d:%02d",x.Y, x.M, x.D, x.h, x.m,
           (int)(x.s));
    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  }
}

/*
**    time( TIMESTRING, MOD, MOD, ...)
**
** Return HH:MM:SS
*/
static void timeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  if( isDate(argc, argv, &x)==0 ){
    char zBuf[100];
    computeHMS(&x);
    sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  }
}

/*
**    date( TIMESTRING, MOD, MOD, ...)
**
** Return YYYY-MM-DD
*/
static void dateFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  if( isDate(argc, argv, &x)==0 ){
    char zBuf[100];
    computeYMD(&x);
    sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  }
}

/*
**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
**
** Return a string described by FORMAT.  Conversions as follows:
**
**   %d  day of month
**   %f  ** fractional seconds  SS.SSS
**   %H  hour 00-24
**   %j  day of year 000-366
**   %J  ** Julian day number
**   %m  month 01-12
**   %M  minute 00-59
**   %s  seconds since 1970-01-01
**   %S  seconds 00-59
**   %w  day of week 0-6  sunday==0
**   %W  week of year 00-53
**   %Y  year 0000-9999
**   %%  %
*/
static void strftimeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  int n, i, j;
  char *z;
  const char *zFmt = sqlite3_value_text(argv[0]);
  char zBuf[100];
  if( zFmt==0 || isDate(argc-1, argv+1, &x) ) return;
  for(i=0, n=1; zFmt[i]; i++, n++){
    if( zFmt[i]=='%' ){
      switch( zFmt[i+1] ){
        case 'd':
        case 'H':
        case 'm':
        case 'M':
        case 'S':
        case 'W':
          n++;
          /* fall thru */
        case 'w':
        case '%':
          break;
        case 'f':
          n += 8;
          break;
        case 'j':
          n += 3;
          break;
        case 'Y':
          n += 8;
          break;
        case 's':
        case 'J':
          n += 50;
          break;
        default:
          return;  /* ERROR.  return a NULL */
      }
      i++;
    }
  }
  if( n<sizeof(zBuf) ){
    z = zBuf;
  }else{
    z = sqliteMalloc( n );
    if( z==0 ) return;
  }
  computeJD(&x);
  computeYMD_HMS(&x);
  for(i=j=0; zFmt[i]; i++){
    if( zFmt[i]!='%' ){
      z[j++] = zFmt[i];
    }else{
      i++;
      switch( zFmt[i] ){
        case 'd':  sprintf(&z[j],"%02d",x.D); j+=2; break;
        case 'f': {
          int s = x.s;
          int ms = (x.s - s)*1000.0;
          sprintf(&z[j],"%02d.%03d",s,ms);
          j += strlen(&z[j]);
          break;
        }
        case 'H':  sprintf(&z[j],"%02d",x.h); j+=2; break;
        case 'W': /* Fall thru */
        case 'j': {
          int n;             /* Number of days since 1st day of year */
          DateTime y = x;
          y.validJD = 0;
          y.M = 1;
          y.D = 1;
          computeJD(&y);
          n = x.rJD - y.rJD;
          if( zFmt[i]=='W' ){
            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
            wd = ((int)(x.rJD+0.5)) % 7;
            sprintf(&z[j],"%02d",(n+7-wd)/7);
            j += 2;
          }else{
            sprintf(&z[j],"%03d",n+1);
            j += 3;
          }
          break;
        }
        case 'J':  sprintf(&z[j],"%.16g",x.rJD); j+=strlen(&z[j]); break;
        case 'm':  sprintf(&z[j],"%02d",x.M); j+=2; break;
        case 'M':  sprintf(&z[j],"%02d",x.m); j+=2; break;
        case 's': {
          sprintf(&z[j],"%d",(int)((x.rJD-2440587.5)*86400.0 + 0.5));
          j += strlen(&z[j]);
          break;
        }
        case 'S':  sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break;
        case 'w':  z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
        case 'Y':  sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break;
        case '%':  z[j++] = '%'; break;
      }
    }
  }
  z[j] = 0;
  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
  if( z!=zBuf ){
    sqliteFree(z);
  }
}

/*
** current_time()
**
** This function returns the same value as time('now').
*/
static void ctimeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  sqlite3_value *pVal = sqlite3ValueNew();
  if( pVal ){
    sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
    timeFunc(context, 1, &pVal);
    sqlite3ValueFree(pVal);
  }
}

/*
** current_date()
**
** This function returns the same value as date('now').
*/
static void cdateFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  sqlite3_value *pVal = sqlite3ValueNew();
  if( pVal ){
    sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
    dateFunc(context, 1, &pVal);
    sqlite3ValueFree(pVal);
  }
}

/*
** current_timestamp()
**
** This function returns the same value as datetime('now').
*/
static void ctimestampFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  sqlite3_value *pVal = sqlite3ValueNew();
  if( pVal ){
    sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
    datetimeFunc(context, 1, &pVal);
    sqlite3ValueFree(pVal);
  }
}
#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */

#ifdef SQLITE_OMIT_DATETIME_FUNCS
/*
** If the library is compiled to omit the full-scale date and time
** handling (to get a smaller binary), the following minimal version
** of the functions current_time(), current_date() and current_timestamp()
** are included instead. This is to support column declarations that
** include "DEFAULT CURRENT_TIME" etc.
**
** This function uses the C-library functions time(), gmtime()
** and strftime(). The format string to pass to strftime() is supplied
** as the user-data for the function.
*/
static void currentTimeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  time_t t;
  char *zFormat = (char *)sqlite3_user_data(context);
  char zBuf[20];

  time(&t);
#ifdef SQLITE_TEST
  {
    extern int sqlite3_current_time;  /* See os_XXX.c */
    if( sqlite3_current_time ){
      t = sqlite3_current_time;
    }
  }
#endif

  sqlite3OsEnterMutex();
  strftime(zBuf, 20, zFormat, gmtime(&t));
  sqlite3OsLeaveMutex();

  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
#endif

/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
*/
void sqlite3RegisterDateTimeFunctions(sqlite3 *db){
#ifndef SQLITE_OMIT_DATETIME_FUNCS
  static const struct {
     char *zName;
     int nArg;
     void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
  } aFuncs[] = {
    { "julianday", -1, juliandayFunc   },
    { "date",      -1, dateFunc        },
    { "time",      -1, timeFunc        },
    { "datetime",  -1, datetimeFunc    },
    { "strftime",  -1, strftimeFunc    },
    { "current_time",       0, ctimeFunc      },
    { "current_timestamp",  0, ctimestampFunc },
    { "current_date",       0, cdateFunc      },
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
        SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
  }
#else
  static const struct {
     char *zName;
     char *zFormat;
  } aFuncs[] = {
    { "current_time", "%H:%M:%S" },
    { "current_date", "%Y-%m-%d" },
    { "current_timestamp", "%Y-%m-%d %H:%M:%S" }
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
    sqlite3_create_function(db, aFuncs[i].zName, 0, SQLITE_UTF8, 
        aFuncs[i].zFormat, currentTimeFunc, 0, 0);
  }
#endif
}
Added SQLite.Interop/src/delete.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
/*
** 2001 September 15
**
** 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 file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
*/
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  Table *pTab = 0;
  int i;
  struct SrcList_item *pItem;
  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
    pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
    pItem->pTab = pTab;
  }
  return pTab;
}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
  if( pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0
        && pParse->nested==0 ){
    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }
#ifndef SQLITE_OMIT_VIEW
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
#endif
  return 0;
}

/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTableForReading(
  Vdbe *v,        /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
  Table *pTab     /* The table to be opened */
){
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
  VdbeComment((v, "# %s", pTab->zName));
  sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
}


/*
** Generate code for a DELETE FROM statement.
**
**     DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
**                 \________/       \________________/
**                  pTabList              pWhere
*/
void sqlite3DeleteFrom(
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table from which we should delete things */
  Expr *pWhere           /* The WHERE clause.  May be null */
){
  Vdbe *v;               /* The virtual database engine */
  Table *pTab;           /* The table from which records will be deleted */
  const char *zDb;       /* Name of database holding pTab */
  int end, addr = 0;     /* A couple addresses of generated code */
  int i;                 /* Loop counter */
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Index *pIdx;           /* For looping over indices of the table */
  int iCur;              /* VDBE Cursor number for pTab */
  sqlite3 *db;           /* Main database structure */
  AuthContext sContext;  /* Authorization context */
  int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */
  NameContext sNC;       /* Name context to resolve expressions in */

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* True if attempting to delete from a view */
  int triggers_exist = 0;      /* True if any triggers exist */
#endif

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3_malloc_failed ){
    pTabList = 0;
    goto delete_from_cleanup;
  }
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete.  This table has to be
  ** put in an SrcList structure because some of the subroutines we
  ** will be calling are designed to work with multiple tables and expect
  ** an SrcList* parameter instead of just a Table* parameter.
  */
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 )  goto delete_from_cleanup;

  /* Figure out if we have any triggers and if the table being
  ** deleted from is a view
  */
#ifndef SQLITE_OMIT_TRIGGER
  triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0);
  isView = pTab->pSelect!=0;
#else
# define triggers_exist 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
    goto delete_from_cleanup;
  }
  assert( pTab->iDb<db->nDb );
  zDb = db->aDb[pTab->iDb].zName;
  if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
    goto delete_from_cleanup;
  }

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto delete_from_cleanup;
  }

  /* Allocate a cursor used to store the old.* data for a trigger.
  */
  if( triggers_exist ){ 
    oldIdx = pParse->nTab++;
  }

  /* Resolve the column names in the WHERE clause.
  */
  assert( pTabList->nSrc==1 );
  iCur = pTabList->a[0].iCursor = pParse->nTab++;
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pParse;
  sNC.pSrcList = pTabList;
  if( sqlite3ExprResolveNames(&sNC, pWhere) ){
    goto delete_from_cleanup;
  }

  /* Start the view context
  */
  if( isView ){
    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
  }

  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    goto delete_from_cleanup;
  }
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, triggers_exist, pTab->iDb);

  /* If we are trying to delete from a view, construct that view into
  ** a temporary table.
  */
  if( isView ){
    Select *pView = sqlite3SelectDup(pTab->pSelect);
    sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0);
    sqlite3SelectDelete(pView);
  }

  /* Initialize the counter of the number of rows deleted, if
  ** we are counting rows.
  */
  if( db->flags & SQLITE_CountRows ){
    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
  }

  /* Special case: A DELETE without a WHERE clause deletes everything.
  ** It is easier just to erase the whole table.  Note, however, that
  ** this means that the row change count will be incorrect.
  */
  if( pWhere==0 && !triggers_exist ){
    if( db->flags & SQLITE_CountRows ){
      /* If counting rows deleted, just count the total number of
      ** entries in the table. */
      int endOfLoop = sqlite3VdbeMakeLabel(v);
      int addr;
      if( !isView ){
        sqlite3OpenTableForReading(v, iCur, pTab);
      }
      sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
      addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
      sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
      sqlite3VdbeResolveLabel(v, endOfLoop);
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
      }
    }
  }

  /* The usual case: There is a WHERE clause so we have to scan through
  ** the table and pick which records to delete.
  */
  else{
    /* Ensure all required collation sequences are available. */
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
        goto delete_from_cleanup;
      }
    }

    /* Begin the database scan
    */
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0);
    if( pWInfo==0 ) goto delete_from_cleanup;

    /* Remember the rowid of every item to be deleted.
    */
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
    if( db->flags & SQLITE_CountRows ){
      sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
    }

    /* End the database scan loop.
    */
    sqlite3WhereEnd(pWInfo);

    /* Open the pseudo-table used to store OLD if there are triggers.
    */
    if( triggers_exist ){
      sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
    }

    /* Delete every item whose key was written to the list during the
    ** database scan.  We have to delete items after the scan is complete
    ** because deleting an item can change the scan order.
    */
    sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
    end = sqlite3VdbeMakeLabel(v);

    /* This is the beginning of the delete loop when there are
    ** row triggers.
    */
    if( triggers_exist ){
      addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      if( !isView ){
        sqlite3OpenTableForReading(v, iCur, pTab);
      }
      sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
      sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
      }

      (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
          -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
	  addr);
    }

    if( !isView ){
      /* Open cursors for the table we are deleting from and all its
      ** indices.  If there are row triggers, this happens inside the
      ** OP_ListRead loop because the cursor have to all be closed
      ** before the trigger fires.  If there are no row triggers, the
      ** cursors are opened only once on the outside the loop.
      */
      sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);

      /* This is the beginning of the delete loop when there are no
      ** row triggers */
      if( !triggers_exist ){ 
        addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
      }

      /* Delete the row */
      sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);
    }

    /* If there are row triggers, close all cursors then invoke
    ** the AFTER triggers
    */
    if( triggers_exist ){
      if( !isView ){
        for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
          sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
        }
        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
      }
      (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
          oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
	  addr);
    }

    /* End of the delete loop */
    sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
    sqlite3VdbeResolveLabel(v, end);
    sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);

    /* Close the cursors after the loop if there are no row triggers */
    if( !triggers_exist ){
      for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
        sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
      }
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
  }

  /*
  ** Return the number of rows that were deleted. If this routine is 
  ** generating code because of a call to sqlite3NestedParse(), do not
  ** invoke the callback function.
  */
  if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
  }

delete_from_cleanup:
  sqlite3AuthContextPop(&sContext);
  sqlite3SrcListDelete(pTabList);
  sqlite3ExprDelete(pWhere);
  return;
}

/*
** This routine generates VDBE code that causes a single row of a
** single table to be deleted.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
**
**   1.  A read/write cursor pointing to pTab, the table containing the row
**       to be deleted, must be opened as cursor number "base".
**
**   2.  Read/write cursors for all indices of pTab must be open as
**       cursor number base+i for the i-th index.
**
**   3.  The record number of the row to be deleted must be on the top
**       of the stack.
**
** This routine pops the top of the stack to remove the record number
** and then generates code to remove both the table record and all index
** entries that point to that record.
*/
void sqlite3GenerateRowDelete(
  sqlite3 *db,       /* The database containing the index */
  Vdbe *v,           /* Generate code into this VDBE */
  Table *pTab,       /* Table containing the row to be deleted */
  int iCur,          /* Cursor number for the table */
  int count          /* Increment the row change counter */
){
  int addr;
  addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
  sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
  sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
  sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
}

/*
** This routine generates VDBE code that causes the deletion of all
** index entries associated with a single row of a single table.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
**
**   1.  A read/write cursor pointing to pTab, the table containing the row
**       to be deleted, must be opened as cursor number "iCur".
**
**   2.  Read/write cursors for all indices of pTab must be open as
**       cursor number iCur+i for the i-th index.
**
**   3.  The "iCur" cursor must be pointing to the row that is to be
**       deleted.
*/
void sqlite3GenerateRowIndexDelete(
  sqlite3 *db,       /* The database containing the index */
  Vdbe *v,           /* Generate code into this VDBE */
  Table *pTab,       /* Table containing the row to be deleted */
  int iCur,          /* Cursor number for the table */
  char *aIdxUsed     /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */
){
  int i;
  Index *pIdx;

  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
    if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
    sqlite3GenerateIndexKey(v, pIdx, iCur);
    sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
  }
}

/*
** Generate code that will assemble an index key and put it on the top
** of the tack.  The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
** the entry that needs indexing.
*/
void sqlite3GenerateIndexKey(
  Vdbe *v,           /* Generate code into this VDBE */
  Index *pIdx,       /* The index for which to generate a key */
  int iCur           /* Cursor number for the pIdx->pTable table */
){
  int j;
  Table *pTab = pIdx->pTable;

  sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
  for(j=0; j<pIdx->nColumn; j++){
    int idx = pIdx->aiColumn[j];
    if( idx==pTab->iPKey ){
      sqlite3VdbeAddOp(v, OP_Dup, j, 0);
    }else{
      sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
    }
  }
  sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
  sqlite3IndexAffinityStr(v, pIdx);
}
Added SQLite.Interop/src/expr.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
/*
** 2001 September 15
**
** 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 file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
** If pExpr is a column, a reference to a column via an 'AS' alias,
** or a sub-select with a column as the return value, then the 
** affinity of that column is returned. Otherwise, 0x00 is returned,
** indicating no affinity for the expression.
**
** i.e. the WHERE clause expresssions in the following statements all
** have an affinity:
**
** CREATE TABLE t1(a);
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
char sqlite3ExprAffinity(Expr *pExpr){
  if( pExpr->op==TK_AS ){
    return sqlite3ExprAffinity(pExpr->pLeft);
  }
  if( pExpr->op==TK_SELECT ){
    return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
  }
  return pExpr->affinity;
}

/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
*/
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
  CollSeq *pColl = 0;
  if( pExpr ){
    pColl = pExpr->pColl;
    if( pExpr->op==TK_AS && !pColl ){
      return sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    }
  }
  if( sqlite3CheckCollSeq(pParse, pColl) ){ 
    pColl = 0;
  }
  return pColl;
}

/*
** pExpr is an operand of a comparison operator.  aff2 is the
** type affinity of the other operand.  This routine returns the
** type affinity that should be used for the comparison operator.
*/
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
  char aff1 = sqlite3ExprAffinity(pExpr);
  if( aff1 && aff2 ){
    /* Both sides of the comparison are columns. If one has numeric or
    ** integer affinity, use that. Otherwise use no affinity.
    */
    if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){
      return SQLITE_AFF_INTEGER;
    }else if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){
      return SQLITE_AFF_NUMERIC;
    }else{
      return SQLITE_AFF_NONE;
    }
  }else if( !aff1 && !aff2 ){
    /* Neither side of the comparison is a column.  Compare the
    ** results directly.
    */
    /* return SQLITE_AFF_NUMERIC;  // Ticket #805 */
    return SQLITE_AFF_NONE;
  }else{
    /* One side is a column, the other is not. Use the columns affinity. */
    return (aff1 + aff2);
  }
}

/*
** pExpr is a comparison operator.  Return the type affinity that should
** be applied to both operands prior to doing the comparison.
*/
static char comparisonAffinity(Expr *pExpr){
  char aff;
  assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
          pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
          pExpr->op==TK_NE );
  assert( pExpr->pLeft );
  aff = sqlite3ExprAffinity(pExpr->pLeft);
  if( pExpr->pRight ){
    aff = sqlite3CompareAffinity(pExpr->pRight, aff);
  }
  else if( pExpr->pSelect ){
    aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff);
  }
  else if( !aff ){
    aff = SQLITE_AFF_NUMERIC;
  }
  return aff;
}

/*
** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
** idx_affinity is the affinity of an indexed column. Return true
** if the index with affinity idx_affinity may be used to implement
** the comparison in pExpr.
*/
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
  char aff = comparisonAffinity(pExpr);
  return 
    (aff==SQLITE_AFF_NONE) ||
    (aff==SQLITE_AFF_NUMERIC && idx_affinity==SQLITE_AFF_INTEGER) ||
    (aff==SQLITE_AFF_INTEGER && idx_affinity==SQLITE_AFF_NUMERIC) ||
    (aff==idx_affinity);
}

/*
** Return the P1 value that should be used for a binary comparison
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
** If jumpIfNull is true, then set the low byte of the returned
** P1 value to tell the opcode to jump if either expression
** evaluates to NULL.
*/
static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
  char aff = sqlite3ExprAffinity(pExpr2);
  return (((int)sqlite3CompareAffinity(pExpr1, aff))<<8)+(jumpIfNull?1:0);
}

/*
** Return a pointer to the collation sequence that should be used by
** a binary comparison operator comparing pLeft and pRight.
**
** If the left hand expression has a collating sequence type, then it is
** used. Otherwise the collation sequence for the right hand expression
** is used, or the default (BINARY) if neither expression has a collating
** type.
*/
static CollSeq* binaryCompareCollSeq(Parse *pParse, Expr *pLeft, Expr *pRight){
  CollSeq *pColl = sqlite3ExprCollSeq(pParse, pLeft);
  if( !pColl ){
    pColl = sqlite3ExprCollSeq(pParse, pRight);
  }
  return pColl;
}

/*
** Generate code for a comparison operator.
*/
static int codeCompare(
  Parse *pParse,    /* The parsing (and code generating) context */
  Expr *pLeft,      /* The left operand */
  Expr *pRight,     /* The right operand */
  int opcode,       /* The comparison opcode */
  int dest,         /* Jump here if true.  */
  int jumpIfNull    /* If true, jump if either operand is NULL */
){
  int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
  CollSeq *p3 = binaryCompareCollSeq(pParse, pLeft, pRight);
  return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ);
}

/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
** is responsible for making sure the node eventually gets freed.
*/
Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){
  Expr *pNew;
  pNew = sqliteMalloc( sizeof(Expr) );
  if( pNew==0 ){
    /* When malloc fails, we leak memory from pLeft and pRight */
    return 0;
  }
  pNew->op = op;
  pNew->pLeft = pLeft;
  pNew->pRight = pRight;
  pNew->iAgg = -1;
  if( pToken ){
    assert( pToken->dyn==0 );
    pNew->span = pNew->token = *pToken;
  }else if( pLeft && pRight ){
    sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
  }
  return pNew;
}

/*
** When doing a nested parse, you can include terms in an expression
** that look like this:   #0 #1 #2 ...  These terms refer to elements
** on the stack.  "#0" (or just "#") means the top of the stack.
** "#1" means the next down on the stack.  And so forth.  #-1 means
** memory location 0.  #-2 means memory location 1.  And so forth.
**
** This routine is called by the parser to deal with on of those terms.
** It immediately generates code to store the value in a memory location.
** The returns an expression that will code to extract the value from
** that memory location as needed.
*/
Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
  Vdbe *v = pParse->pVdbe;
  Expr *p;
  int depth;
  if( v==0 ) return 0;
  if( pParse->nested==0 ){
    sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);
    return 0;
  }
  p = sqlite3Expr(TK_REGISTER, 0, 0, pToken);
  if( p==0 ){
    return 0;  /* Malloc failed */
  }
  depth = atoi(&pToken->z[1]);
  if( depth>=0 ){
    p->iTable = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
  }else{
    p->iTable = -1-depth;
  }
  return p;
}

/*
** Join two expressions using an AND operator.  If either expression is
** NULL, then just return the other expression.
*/
Expr *sqlite3ExprAnd(Expr *pLeft, Expr *pRight){
  if( pLeft==0 ){
    return pRight;
  }else if( pRight==0 ){
    return pLeft;
  }else{
    return sqlite3Expr(TK_AND, pLeft, pRight, 0);
  }
}

/*
** Set the Expr.span field of the given expression to span all
** text between the two given tokens.
*/
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
  assert( pRight!=0 );
  assert( pLeft!=0 );
  if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){
    assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
    if( pLeft->dyn==0 && pRight->dyn==0 ){
      pExpr->span.z = pLeft->z;
      pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
    }else{
      pExpr->span.z = 0;
    }
  }
}

/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
  Expr *pNew;
  pNew = sqliteMalloc( sizeof(Expr) );
  if( pNew==0 ){
    /* sqlite3ExprListDelete(pList); // Leak pList when malloc fails */
    return 0;
  }
  pNew->op = TK_FUNCTION;
  pNew->pList = pList;
  if( pToken ){
    assert( pToken->dyn==0 );
    pNew->token = *pToken;
  }else{
    pNew->token.z = 0;
  }
  pNew->span = pNew->token;
  return pNew;
}

/*
** Assign a variable number to an expression that encodes a wildcard
** in the original SQL statement.  
**
** Wildcards consisting of a single "?" are assigned the next sequential
** variable number.
**
** Wildcards of the form "?nnn" are assigned the number "nnn".  We make
** sure "nnn" is not too be to avoid a denial of service attack when
** the SQL statement comes from an external source.
**
** Wildcards of the form ":aaa" or "$aaa" are assigned the same number
** as the previous instance of the same wildcard.  Or if this is the first
** instance of the wildcard, the next sequenial variable number is
** assigned.
*/
void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
  Token *pToken;
  if( pExpr==0 ) return;
  pToken = &pExpr->token;
  assert( pToken->n>=1 );
  assert( pToken->z!=0 );
  assert( pToken->z[0]!=0 );
  if( pToken->n==1 ){
    /* Wildcard of the form "?".  Assign the next variable number */
    pExpr->iTable = ++pParse->nVar;
  }else if( pToken->z[0]=='?' ){
    /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
    ** use it as the variable number */
    int i;
    pExpr->iTable = i = atoi(&pToken->z[1]);
    if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){
      sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
          SQLITE_MAX_VARIABLE_NUMBER);
    }
    if( i>pParse->nVar ){
      pParse->nVar = i;
    }
  }else{
    /* Wildcards of the form ":aaa" or "$aaa".  Reuse the same variable
    ** number as the prior appearance of the same name, or if the name
    ** has never appeared before, reuse the same variable number
    */
    int i, n;
    n = pToken->n;
    for(i=0; i<pParse->nVarExpr; i++){
      Expr *pE;
      if( (pE = pParse->apVarExpr[i])!=0
          && pE->token.n==n
          && memcmp(pE->token.z, pToken->z, n)==0 ){
        pExpr->iTable = pE->iTable;
        break;
      }
    }
    if( i>=pParse->nVarExpr ){
      pExpr->iTable = ++pParse->nVar;
      if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
        pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
        pParse->apVarExpr = sqliteRealloc(pParse->apVarExpr,
                       pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
      }
      if( !sqlite3_malloc_failed ){
        assert( pParse->apVarExpr!=0 );
        pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
      }
    }
  } 
}

/*
** Recursively delete an expression tree.
*/
void sqlite3ExprDelete(Expr *p){
  if( p==0 ) return;
  if( p->span.dyn ) sqliteFree((char*)p->span.z);
  if( p->token.dyn ) sqliteFree((char*)p->token.z);
  sqlite3ExprDelete(p->pLeft);
  sqlite3ExprDelete(p->pRight);
  sqlite3ExprListDelete(p->pList);
  sqlite3SelectDelete(p->pSelect);
  sqliteFree(p);
}


/*
** The following group of routines make deep copies of expressions,
** expression lists, ID lists, and select statements.  The copies can
** be deleted (by being passed to their respective ...Delete() routines)
** without effecting the originals.
**
** The expression list, ID, and source lists return by sqlite3ExprListDup(),
** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded 
** by subsequent calls to sqlite*ListAppend() routines.
**
** Any tables that the SrcList might point to are not duplicated.
*/
Expr *sqlite3ExprDup(Expr *p){
  Expr *pNew;
  if( p==0 ) return 0;
  pNew = sqliteMallocRaw( sizeof(*p) );
  if( pNew==0 ) return 0;
  memcpy(pNew, p, sizeof(*pNew));
  if( p->token.z!=0 ){
    pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
    pNew->token.dyn = 1;
  }else{
    assert( pNew->token.z==0 );
  }
  pNew->span.z = 0;
  pNew->pLeft = sqlite3ExprDup(p->pLeft);
  pNew->pRight = sqlite3ExprDup(p->pRight);
  pNew->pList = sqlite3ExprListDup(p->pList);
  pNew->pSelect = sqlite3SelectDup(p->pSelect);
  return pNew;
}
void sqlite3TokenCopy(Token *pTo, Token *pFrom){
  if( pTo->dyn ) sqliteFree((char*)pTo->z);
  if( pFrom->z ){
    pTo->n = pFrom->n;
    pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
    pTo->dyn = 1;
  }else{
    pTo->z = 0;
  }
}
ExprList *sqlite3ExprListDup(ExprList *p){
  ExprList *pNew;
  struct ExprList_item *pItem, *pOldItem;
  int i;
  if( p==0 ) return 0;
  pNew = sqliteMalloc( sizeof(*pNew) );
  if( pNew==0 ) return 0;
  pNew->nExpr = pNew->nAlloc = p->nExpr;
  pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
  if( pItem==0 ){
    sqliteFree(pNew);
    return 0;
  } 
  pOldItem = p->a;
  for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
    Expr *pNewExpr, *pOldExpr;
    pItem->pExpr = pNewExpr = sqlite3ExprDup(pOldExpr = pOldItem->pExpr);
    if( pOldExpr->span.z!=0 && pNewExpr ){
      /* Always make a copy of the span for top-level expressions in the
      ** expression list.  The logic in SELECT processing that determines
      ** the names of columns in the result set needs this information */
      sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
    }
    assert( pNewExpr==0 || pNewExpr->span.z!=0 
            || pOldExpr->span.z==0 || sqlite3_malloc_failed );
    pItem->zName = sqliteStrDup(pOldItem->zName);
    pItem->sortOrder = pOldItem->sortOrder;
    pItem->isAgg = pOldItem->isAgg;
    pItem->done = 0;
  }
  return pNew;
}

/*
** If cursors, triggers, views and subqueries are all omitted from
** the build, then none of the following routines, except for 
** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
** called with a NULL argument.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
 || !defined(SQLITE_OMIT_SUBQUERY)
SrcList *sqlite3SrcListDup(SrcList *p){
  SrcList *pNew;
  int i;
  int nByte;
  if( p==0 ) return 0;
  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
  pNew = sqliteMallocRaw( nByte );
  if( pNew==0 ) return 0;
  pNew->nSrc = pNew->nAlloc = p->nSrc;
  for(i=0; i<p->nSrc; i++){
    struct SrcList_item *pNewItem = &pNew->a[i];
    struct SrcList_item *pOldItem = &p->a[i];
    pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
    pNewItem->zName = sqliteStrDup(pOldItem->zName);
    pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
    pNewItem->jointype = pOldItem->jointype;
    pNewItem->iCursor = pOldItem->iCursor;
    pNewItem->pTab = pOldItem->pTab;
    if( pNewItem->pTab ){
      pNewItem->pTab->isTransient = 0;
    }
    pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect);
    pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn);
    pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing);
    pNewItem->colUsed = pOldItem->colUsed;
  }
  return pNew;
}
IdList *sqlite3IdListDup(IdList *p){
  IdList *pNew;
  int i;
  if( p==0 ) return 0;
  pNew = sqliteMallocRaw( sizeof(*pNew) );
  if( pNew==0 ) return 0;
  pNew->nId = pNew->nAlloc = p->nId;
  pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
  if( pNew->a==0 ) return 0;
  for(i=0; i<p->nId; i++){
    struct IdList_item *pNewItem = &pNew->a[i];
    struct IdList_item *pOldItem = &p->a[i];
    pNewItem->zName = sqliteStrDup(pOldItem->zName);
    pNewItem->idx = pOldItem->idx;
  }
  return pNew;
}
Select *sqlite3SelectDup(Select *p){
  Select *pNew;
  if( p==0 ) return 0;
  pNew = sqliteMallocRaw( sizeof(*p) );
  if( pNew==0 ) return 0;
  pNew->isDistinct = p->isDistinct;
  pNew->pEList = sqlite3ExprListDup(p->pEList);
  pNew->pSrc = sqlite3SrcListDup(p->pSrc);
  pNew->pWhere = sqlite3ExprDup(p->pWhere);
  pNew->pGroupBy = sqlite3ExprListDup(p->pGroupBy);
  pNew->pHaving = sqlite3ExprDup(p->pHaving);
  pNew->pOrderBy = sqlite3ExprListDup(p->pOrderBy);
  pNew->op = p->op;
  pNew->pPrior = sqlite3SelectDup(p->pPrior);
  pNew->pLimit = sqlite3ExprDup(p->pLimit);
  pNew->pOffset = sqlite3ExprDup(p->pOffset);
  pNew->iLimit = -1;
  pNew->iOffset = -1;
  pNew->ppOpenTemp = 0;
  pNew->pFetch = 0;
  pNew->isResolved = p->isResolved;
  pNew->isAgg = p->isAgg;
  return pNew;
}
#else
Select *sqlite3SelectDup(Select *p){
  assert( p==0 );
  return 0;
}
#endif


/*
** Add a new element to the end of an expression list.  If pList is
** initially NULL, then create a new expression list.
*/
ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
  if( pList==0 ){
    pList = sqliteMalloc( sizeof(ExprList) );
    if( pList==0 ){
      /* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */
      return 0;
    }
    assert( pList->nAlloc==0 );
  }
  if( pList->nAlloc<=pList->nExpr ){
    pList->nAlloc = pList->nAlloc*2 + 4;
    pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]));
    if( pList->a==0 ){
      /* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */
      pList->nExpr = pList->nAlloc = 0;
      return pList;
    }
  }
  assert( pList->a!=0 );
  if( pExpr || pName ){
    struct ExprList_item *pItem = &pList->a[pList->nExpr++];
    memset(pItem, 0, sizeof(*pItem));
    pItem->pExpr = pExpr;
    pItem->zName = sqlite3NameFromToken(pName);
  }
  return pList;
}

/*
** Delete an entire expression list.
*/
void sqlite3ExprListDelete(ExprList *pList){
  int i;
  struct ExprList_item *pItem;
  if( pList==0 ) return;
  assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
  assert( pList->nExpr<=pList->nAlloc );
  for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
    sqlite3ExprDelete(pItem->pExpr);
    sqliteFree(pItem->zName);
  }
  sqliteFree(pList->a);
  sqliteFree(pList);
}

/*
** Walk an expression tree.  Call xFunc for each node visited.
**
** The return value from xFunc determines whether the tree walk continues.
** 0 means continue walking the tree.  1 means do not walk children
** of the current node but continue with siblings.  2 means abandon
** the tree walk completely.
**
** The return value from this routine is 1 to abandon the tree walk
** and 0 to continue.
*/
static int walkExprList(ExprList *, int (*)(void *, Expr*), void *);
static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){
  int rc;
  if( pExpr==0 ) return 0;
  rc = (*xFunc)(pArg, pExpr);
  if( rc==0 ){
    if( walkExprTree(pExpr->pLeft, xFunc, pArg) ) return 1;
    if( walkExprTree(pExpr->pRight, xFunc, pArg) ) return 1;
    if( walkExprList(pExpr->pList, xFunc, pArg) ) return 1;
  }
  return rc>1;
}

/*
** Call walkExprTree() for every expression in list p.
*/
static int walkExprList(ExprList *p, int (*xFunc)(void *, Expr*), void *pArg){
  int i;
  struct ExprList_item *pItem;
  if( !p ) return 0;
  for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){
    if( walkExprTree(pItem->pExpr, xFunc, pArg) ) return 1;
  }
  return 0;
}

/*
** Call walkExprTree() for every expression in Select p, not including
** expressions that are part of sub-selects in any FROM clause or the LIMIT
** or OFFSET expressions..
*/
static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){
  walkExprList(p->pEList, xFunc, pArg);
  walkExprTree(p->pWhere, xFunc, pArg);
  walkExprList(p->pGroupBy, xFunc, pArg);
  walkExprTree(p->pHaving, xFunc, pArg);
  walkExprList(p->pOrderBy, xFunc, pArg);
  return 0;
}


/*
** This routine is designed as an xFunc for walkExprTree().
**
** pArg is really a pointer to an integer.  If we can tell by looking
** at pExpr that the expression that contains pExpr is not a constant
** expression, then set *pArg to 0 and return 2 to abandon the tree walk.
** If pExpr does does not disqualify the expression from being a constant
** then do nothing.
**
** After walking the whole tree, if no nodes are found that disqualify
** the expression as constant, then we assume the whole expression
** is constant.  See sqlite3ExprIsConstant() for additional information.
*/
static int exprNodeIsConstant(void *pArg, Expr *pExpr){
  switch( pExpr->op ){
    case TK_ID:
    case TK_COLUMN:
    case TK_DOT:
    case TK_AGG_FUNCTION:
    case TK_FUNCTION:
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_SELECT:
    case TK_EXISTS:
#endif
      *((int*)pArg) = 0;
      return 2;
    default:
      return 0;
  }
}

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
int sqlite3ExprIsConstant(Expr *p){
  int isConst = 1;
  walkExprTree(p, exprNodeIsConstant, &isConst);
  return isConst;
}

/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
  switch( p->op ){
    case TK_INTEGER: {
      if( sqlite3GetInt32(p->token.z, pValue) ){
        return 1;
      }
      break;
    }
    case TK_UPLUS: {
      return sqlite3ExprIsInteger(p->pLeft, pValue);
    }
    case TK_UMINUS: {
      int v;
      if( sqlite3ExprIsInteger(p->pLeft, &v) ){
        *pValue = -v;
        return 1;
      }
      break;
    }
    default: break;
  }
  return 0;
}

/*
** Return TRUE if the given string is a row-id column name.
*/
int sqlite3IsRowid(const char *z){
  if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
  if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
  if( sqlite3StrICmp(z, "OID")==0 ) return 1;
  return 0;
}

/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr 
** expression node refer back to that source column.  The following changes
** are made to pExpr:
**
**    pExpr->iDb           Set the index in db->aDb[] of the database holding
**                         the table.
**    pExpr->iTable        Set to the cursor number for the table obtained
**                         from pSrcList.
**    pExpr->iColumn       Set to the column number within the table.
**    pExpr->op            Set to TK_COLUMN.
**    pExpr->pLeft         Any expression this points to is deleted
**    pExpr->pRight        Any expression this points to is deleted.
**
** The pDbToken is the name of the database (the "X").  This value may be
** NULL meaning that name is of the form Y.Z or Z.  Any available database
** can be used.  The pTableToken is the name of the table (the "Y").  This
** value can be NULL if pDbToken is also NULL.  If pTableToken is NULL it
** means that the form of the name is Z and that columns from any table
** can be used.
**
** If the name cannot be resolved unambiguously, leave an error message
** in pParse and return non-zero.  Return zero on success.
*/
static int lookupName(
  Parse *pParse,      /* The parsing context */
  Token *pDbToken,     /* Name of the database containing table, or NULL */
  Token *pTableToken,  /* Name of table containing column, or NULL */
  Token *pColumnToken, /* Name of the column. */
  NameContext *pNC,    /* The name context used to resolve the name */
  Expr *pExpr          /* Make this EXPR node point to the selected column */
){
  char *zDb = 0;       /* Name of the database.  The "X" in X.Y.Z */
  char *zTab = 0;      /* Name of the table.  The "Y" in X.Y.Z or Y.Z */
  char *zCol = 0;      /* Name of the column.  The "Z" */
  int i, j;            /* Loop counters */
  int cnt = 0;         /* Number of matching column names */
  int cntTab = 0;      /* Number of matching table names */
  sqlite3 *db = pParse->db;  /* The database */
  struct SrcList_item *pItem;       /* Use for looping over pSrcList items */
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */

  assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
  zDb = sqlite3NameFromToken(pDbToken);
  zTab = sqlite3NameFromToken(pTableToken);
  zCol = sqlite3NameFromToken(pColumnToken);
  if( sqlite3_malloc_failed ){
    return 1;  /* Leak memory (zDb and zTab) if malloc fails */
  }

  pExpr->iTable = -1;
  while( pNC && cnt==0 ){
    SrcList *pSrcList = pNC->pSrcList;
    ExprList *pEList = pNC->pEList;

    pNC->nRef++;
    /* assert( zTab==0 || pEList==0 ); */
    if( pSrcList ){
      for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
        Table *pTab = pItem->pTab;
        Column *pCol;
  
        if( pTab==0 ) continue;
        assert( pTab->nCol>0 );
        if( zTab ){
          if( pItem->zAlias ){
            char *zTabName = pItem->zAlias;
            if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
          }else{
            char *zTabName = pTab->zName;
            if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
            if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
              continue;
            }
          }
        }
        if( 0==(cntTab++) ){
          pExpr->iTable = pItem->iCursor;
          pExpr->iDb = pTab->iDb;
          pMatch = pItem;
        }
        for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            cnt++;
            pExpr->iTable = pItem->iCursor;
            pMatch = pItem;
            pExpr->iDb = pTab->iDb;
            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
            pExpr->affinity = pTab->aCol[j].affinity;
            pExpr->pColl = pTab->aCol[j].pColl;
            break;
          }
        }
      }
    }

#ifndef SQLITE_OMIT_TRIGGER
    /* If we have not already resolved the name, then maybe 
    ** it is a new.* or old.* trigger argument reference
    */
    if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){
      TriggerStack *pTriggerStack = pParse->trigStack;
      Table *pTab = 0;
      if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){
        pExpr->iTable = pTriggerStack->newIdx;
        assert( pTriggerStack->pTab );
        pTab = pTriggerStack->pTab;
      }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab)==0 ){
        pExpr->iTable = pTriggerStack->oldIdx;
        assert( pTriggerStack->pTab );
        pTab = pTriggerStack->pTab;
      }

      if( pTab ){ 
        int j;
        Column *pCol = pTab->aCol;

        pExpr->iDb = pTab->iDb;
        cntTab++;
        for(j=0; j < pTab->nCol; j++, pCol++) {
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            cnt++;
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
            pExpr->affinity = pTab->aCol[j].affinity;
            pExpr->pColl = pTab->aCol[j].pColl;
            break;
          }
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */

    /*
    ** Perhaps the name is a reference to the ROWID
    */
    if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
      cnt = 1;
      pExpr->iColumn = -1;
      pExpr->affinity = SQLITE_AFF_INTEGER;
    }

    /*
    ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
    ** might refer to an result-set alias.  This happens, for example, when
    ** we are resolving names in the WHERE clause of the following command:
    **
    **     SELECT a+b AS x FROM table WHERE x<10;
    **
    ** In cases like this, replace pExpr with a copy of the expression that
    ** forms the result set entry ("a+b" in the example) and return immediately.
    ** Note that the expression in the result set should have already been
    ** resolved by the time the WHERE clause is resolved.
    */
    if( cnt==0 && pEList!=0 && zTab==0 ){
      for(j=0; j<pEList->nExpr; j++){
        char *zAs = pEList->a[j].zName;
        if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
          assert( pExpr->pLeft==0 && pExpr->pRight==0 );
          pExpr->op = TK_AS;
          pExpr->iColumn = j;
          pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr);
          sqliteFree(zCol);
          assert( zTab==0 && zDb==0 );
          return 0;
        }
      } 
    }

    /* Advance to the next name context.  The loop will exit when either
    ** we have a match (cnt>0) or when we run out of name contexts.
    */
    if( cnt==0 ){
      pNC = pNC->pNext;
    }
  }

  /*
  ** If X and Y are NULL (in other words if only the column name Z is
  ** supplied) and the value of Z is enclosed in double-quotes, then
  ** Z is a string literal if it doesn't match any column names.  In that
  ** case, we need to return right away and not make any changes to
  ** pExpr.
  */
  if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
    sqliteFree(zCol);
    return 0;
  }

  /*
  ** cnt==0 means there was not match.  cnt>1 means there were two or
  ** more matches.  Either way, we have an error.
  */
  if( cnt!=1 ){
    char *z = 0;
    char *zErr;
    zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
    if( zDb ){
      sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, 0);
    }else if( zTab ){
      sqlite3SetString(&z, zTab, ".", zCol, 0);
    }else{
      z = sqliteStrDup(zCol);
    }
    sqlite3ErrorMsg(pParse, zErr, z);
    sqliteFree(z);
    pTopNC->nErr++;
  }

  /* If a column from a table in pSrcList is referenced, then record
  ** this fact in the pSrcList.a[].colUsed bitmask.  Column 0 causes
  ** bit 0 to be set.  Column 1 sets bit 1.  And so forth.  If the
  ** column number is greater than the number of bits in the bitmask
  ** then set the high-order bit of the bitmask.
  */
  if( pExpr->iColumn>=0 && pMatch!=0 ){
    int n = pExpr->iColumn;
    if( n>=sizeof(Bitmask)*8 ){
      n = sizeof(Bitmask)*8-1;
    }
    assert( pMatch->iCursor==pExpr->iTable );
    pMatch->colUsed |= 1<<n;
  }

  /* Clean up and return
  */
  sqliteFree(zDb);
  sqliteFree(zTab);
  sqliteFree(zCol);
  sqlite3ExprDelete(pExpr->pLeft);
  pExpr->pLeft = 0;
  sqlite3ExprDelete(pExpr->pRight);
  pExpr->pRight = 0;
  pExpr->op = TK_COLUMN;
  if( cnt==1 ){
    assert( pNC!=0 );
    sqlite3AuthRead(pParse, pExpr, pNC->pSrcList);
  }
  return cnt!=1;
}

/*
** pExpr is a node that defines a function of some kind.  It might
** be a syntactic function like "count(x)" or it might be a function
** that implements an operator, like "a LIKE b".  
**
** This routine makes *pzName point to the name of the function and 
** *pnName hold the number of characters in the function name.
*/
static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){
  switch( pExpr->op ){
    case TK_FUNCTION: {
      *pzName = pExpr->token.z;
      *pnName = pExpr->token.n;
      break;
    }
    case TK_LIKE: {
      *pzName = "like";
      *pnName = 4;
      break;
    }
    case TK_GLOB: {
      *pzName = "glob";
      *pnName = 4;
      break;
    }
    case TK_CTIME: {
      *pzName = "current_time";
      *pnName = 12;
      break;
    }
    case TK_CDATE: {
      *pzName = "current_date";
      *pnName = 12;
      break;
    }
    case TK_CTIMESTAMP: {
      *pzName = "current_timestamp";
      *pnName = 17;
      break;
    }
  }
}

/*
** This routine is designed as an xFunc for walkExprTree().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree.  Return 0 to continue the search down
** the tree or 2 to abort the tree walk.
**
** This routine also does error checking and name resolution for
** function names.  The operator for aggregate functions is changed
** to TK_AGG_FUNCTION.
*/
static int nameResolverStep(void *pArg, Expr *pExpr){
  NameContext *pNC = (NameContext*)pArg;
  SrcList *pSrcList;
  Parse *pParse;

  if( pExpr==0 ) return 1;
  assert( pNC!=0 );
  pSrcList = pNC->pSrcList;
  pParse = pNC->pParse;

  if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1;
  ExprSetProperty(pExpr, EP_Resolved);
#ifndef NDEBUG
  if( pSrcList ){
    int i;
    for(i=0; i<pSrcList->nSrc; i++){
      assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
    }
  }
#endif
  switch( pExpr->op ){
    /* Double-quoted strings (ex: "abc") are used as identifiers if
    ** possible.  Otherwise they remain as strings.  Single-quoted
    ** strings (ex: 'abc') are always string literals.
    */
    case TK_STRING: {
      if( pExpr->token.z[0]=='\'' ) break;
      /* Fall thru into the TK_ID case if this is a double-quoted string */
    }
    /* A lone identifier is the name of a column.
    */
    case TK_ID: {
      lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr);
      return 1;
    }
  
    /* A table name and column name:     ID.ID
    ** Or a database, table and column:  ID.ID.ID
    */
    case TK_DOT: {
      Token *pColumn;
      Token *pTable;
      Token *pDb;
      Expr *pRight;

      /* if( pSrcList==0 ) break; */
      pRight = pExpr->pRight;
      if( pRight->op==TK_ID ){
        pDb = 0;
        pTable = &pExpr->pLeft->token;
        pColumn = &pRight->token;
      }else{
        assert( pRight->op==TK_DOT );
        pDb = &pExpr->pLeft->token;
        pTable = &pRight->pLeft->token;
        pColumn = &pRight->pRight->token;
      }
      lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr);
      return 1;
    }

    /* Resolve function names
    */
    case TK_CTIME:
    case TK_CTIMESTAMP:
    case TK_CDATE:
    case TK_GLOB:
    case TK_LIKE:
    case TK_FUNCTION: {
      ExprList *pList = pExpr->pList;    /* The argument list */
      int n = pList ? pList->nExpr : 0;  /* Number of arguments */
      int no_such_func = 0;       /* True if no such function exists */
      int wrong_num_args = 0;     /* True if wrong number of arguments */
      int is_agg = 0;             /* True if is an aggregate function */
      int i;
      int nId;                    /* Number of characters in function name */
      const char *zId;            /* The function name. */
      FuncDef *pDef;              /* Information about the function */
      int enc = pParse->db->enc;  /* The database encoding */

      getFunctionName(pExpr, &zId, &nId);
      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
      if( pDef==0 ){
        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
        if( pDef==0 ){
          no_such_func = 1;
        }else{
          wrong_num_args = 1;
        }
      }else{
        is_agg = pDef->xFunc==0;
      }
      if( is_agg && !pNC->allowAgg ){
        sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
        pNC->nErr++;
        is_agg = 0;
      }else if( no_such_func ){
        sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
        pNC->nErr++;
      }else if( wrong_num_args ){
        sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
             nId, zId);
        pNC->nErr++;
      }
      if( is_agg ){
        pExpr->op = TK_AGG_FUNCTION;
        pNC->hasAgg = 1;
      }
      if( is_agg ) pNC->allowAgg = 0;
      for(i=0; pNC->nErr==0 && i<n; i++){
        walkExprTree(pList->a[i].pExpr, nameResolverStep, pNC);
      }
      if( is_agg ) pNC->allowAgg = 1;
      /* FIX ME:  Compute pExpr->affinity based on the expected return
      ** type of the function 
      */
      return is_agg;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_SELECT:
    case TK_EXISTS:
#endif
    case TK_IN: {
      if( pExpr->pSelect ){
        int nRef = pNC->nRef;
        sqlite3SelectResolve(pParse, pExpr->pSelect, pNC);
        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
        }
      }
    }
  }
  return 0;
}

/*
** This routine walks an expression tree and resolves references to
** table columns.  Nodes of the form ID.ID or ID resolve into an
** index to the table in the table list and a column offset.  The 
** Expr.opcode for such nodes is changed to TK_COLUMN.  The Expr.iTable
** value is changed to the index of the referenced table in pTabList
** plus the "base" value.  The base value will ultimately become the
** VDBE cursor number for a cursor that is pointing into the referenced
** table.  The Expr.iColumn value is changed to the index of the column 
** of the referenced table.  The Expr.iColumn value for the special
** ROWID column is -1.  Any INTEGER PRIMARY KEY column is tried as an
** alias for ROWID.
**
** Also resolve function names and check the functions for proper
** usage.  Make sure all function names are recognized and all functions
** have the correct number of arguments.  Leave an error message
** in pParse->zErrMsg if anything is amiss.  Return the number of errors.
**
** If the expression contains aggregate functions then set the EP_Agg
** property on the expression.
*/
int sqlite3ExprResolveNames(
  NameContext *pNC,       /* Namespace to resolve expressions in. */
  Expr *pExpr             /* The expression to be analyzed. */
){
  if( pExpr==0 ) return 0;
  walkExprTree(pExpr, nameResolverStep, pNC);
  if( pNC->nErr>0 ){
    ExprSetProperty(pExpr, EP_Error);
  }
  return ExprHasProperty(pExpr, EP_Error);
}

/*
** A pointer instance of this structure is used to pass information
** through walkExprTree into codeSubqueryStep().
*/
typedef struct QueryCoder QueryCoder;
struct QueryCoder {
  Parse *pParse;       /* The parsing context */
  NameContext *pNC;    /* Namespace of first enclosing query */
};


/*
** Generate code for subqueries and IN operators.
**
** IN operators comes in two forms:
**
**           expr IN (exprlist)
** and
**           expr IN (SELECT ...)
**
** The first form is handled by creating a set holding the list
** of allowed values.  The second form causes the SELECT to generate 
** a temporary table.
*/
#ifndef SQLITE_OMIT_SUBQUERY
void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  int label = 0;                         /* Address after sub-select code */
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;

  /* If this is not a variable (correlated) select, then execute
  ** it only once. Unless this is part of a trigger program. In
  ** that case re-execute every time (this could be optimized).
  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
    int mem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
    label = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_If, 0, label);
    sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, mem, 1);
  }

  if( pExpr->pSelect ){
    sqlite3VdbeAddOp(v, OP_AggContextPush, 0, 0);
  }

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;
      KeyInfo keyInfo;
      int addr;        /* Address of OP_OpenTemp instruction */

      affinity = sqlite3ExprAffinity(pExpr->pLeft);

      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
      ** expression it is handled the same way. A temporary table is 
      ** filled with single-field index keys representing the results
      ** from the SELECT or the <exprlist>.
      **
      ** If the 'x' expression is a column value, or the SELECT...
      ** statement returns a column value, then the affinity of that
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite3VdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 0);
      memset(&keyInfo, 0, sizeof(keyInfo));
      keyInfo.nField = 1;
      sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1);

      if( pExpr->pSelect ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        int iParm = pExpr->iTable +  (((int)affinity)<<16);
        ExprList *pEList;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0);
        pEList = pExpr->pSelect->pEList;
        if( pEList && pEList->nExpr>0 ){ 
          keyInfo.aColl[0] = binaryCompareCollSeq(pParse, pExpr->pLeft,
              pEList->a[0].pExpr);
        }
      }else if( pExpr->pList ){
        /* Case 2:     expr IN (exprlist)
        **
	** For each expression, build an index key from the evaluation and
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        if( !affinity ){
          affinity = SQLITE_AFF_NUMERIC;
        }
        keyInfo.aColl[0] = pExpr->pLeft->pColl;

        /* Loop through each expression in <exprlist>. */
        for(i=0; i<pExpr->pList->nExpr; i++){
          Expr *pE2 = pExpr->pList->a[i].pExpr;

          /* Check that the expression is constant and valid. */
          if( !sqlite3ExprIsConstant(pE2) ){
            sqlite3ErrorMsg(pParse,
              "right-hand side of IN operator must be constant");
            return;
          }

          /* Evaluate the expression and insert it into the temp table */
          sqlite3ExprCode(pParse, pE2);
          sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
          sqlite3VdbeAddOp(v, OP_String8, 0, 0);
          sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
        }
      }
      sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
      break;
    }

    case TK_EXISTS:
    case TK_SELECT: {
      /* This has to be a scalar SELECT.  Generate code to put the
      ** value of this select in a memory cell and record the number
      ** of the memory cell in iColumn.
      */
      int sop;
      Select *pSel;

      pExpr->iColumn = pParse->nMem++;
      pSel = pExpr->pSelect;
      if( pExpr->op==TK_SELECT ){
        sop = SRT_Mem;
      }else{
        static const Token one = { "1", 0, 1 };
        sop = SRT_Exists;
        sqlite3ExprListDelete(pSel->pEList);
        pSel->pEList = sqlite3ExprListAppend(0, 
                          sqlite3Expr(TK_INTEGER, 0, 0, &one), 0);
      }
      sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0);
      break;
    }
  }

  if( pExpr->pSelect ){
    sqlite3VdbeAddOp(v, OP_AggContextPop, 0, 0);
  }
  if( label<0 ){
    sqlite3VdbeResolveLabel(v, label);
  }
  return;
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
*/
static void codeInteger(Vdbe *v, const char *z, int n){
  int i;
  if( sqlite3GetInt32(z, &i) ){
    sqlite3VdbeAddOp(v, OP_Integer, i, 0);
  }else if( sqlite3FitsIn64Bits(z) ){
    sqlite3VdbeOp3(v, OP_Integer, 0, 0, z, n);
  }else{
    sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);
  }
}

/*
** Generate code into the current Vdbe to evaluate the given
** expression and leave the result on the top of stack.
**
** This code depends on the fact that certain token values (ex: TK_EQ)
** are the same as opcode values (ex: OP_Eq) that implement the corresponding
** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
** the make process cause these values to align.  Assert()s in the code
** below verify that the numbers are aligned correctly.
*/
void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
  Vdbe *v = pParse->pVdbe;
  int op;
  if( v==0 ) return;
  if( pExpr==0 ){
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);  /* Empty expression evals to NULL */
    return;
  }
  op = pExpr->op;
  switch( op ){
    case TK_COLUMN: {
      if( !pParse->fillAgg && pExpr->iAgg>=0 ){
        sqlite3VdbeAddOp(v, OP_AggGet, pExpr->iAggCtx, pExpr->iAgg);
      }else if( pExpr->iColumn>=0 ){
        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
#ifndef NDEBUG
        if( pExpr->span.z && pExpr->span.n>0 && pExpr->span.n<100 ){
          VdbeComment((v, "# %T", &pExpr->span));
        }
#endif
      }else{
        sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, pExpr->token.z, pExpr->token.n);
      break;
    }
    case TK_FLOAT:
    case TK_STRING: {
      assert( TK_FLOAT==OP_Real );
      assert( TK_STRING==OP_String8 );
      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
      sqlite3VdbeDequoteP3(v, -1);
      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case TK_BLOB: {
      assert( TK_BLOB==OP_HexBlob );
      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1);
      sqlite3VdbeDequoteP3(v, -1);
      break;
    }
#endif
    case TK_NULL: {
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      break;
    }
    case TK_VARIABLE: {
      sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
      if( pExpr->token.n>1 ){
        sqlite3VdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
      }
      break;
    }
    case TK_REGISTER: {
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0);
      break;
    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      assert( TK_LT==OP_Lt );
      assert( TK_LE==OP_Le );
      assert( TK_GT==OP_Gt );
      assert( TK_GE==OP_Ge );
      assert( TK_EQ==OP_Eq );
      assert( TK_NE==OP_Ne );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
      break;
    }
    case TK_AND:
    case TK_OR:
    case TK_PLUS:
    case TK_STAR:
    case TK_MINUS:
    case TK_REM:
    case TK_BITAND:
    case TK_BITOR:
    case TK_SLASH:
    case TK_LSHIFT:
    case TK_RSHIFT: 
    case TK_CONCAT: {
      assert( TK_AND==OP_And );
      assert( TK_OR==OP_Or );
      assert( TK_PLUS==OP_Add );
      assert( TK_MINUS==OP_Subtract );
      assert( TK_REM==OP_Remainder );
      assert( TK_BITAND==OP_BitAnd );
      assert( TK_BITOR==OP_BitOr );
      assert( TK_SLASH==OP_Divide );
      assert( TK_LSHIFT==OP_ShiftLeft );
      assert( TK_RSHIFT==OP_ShiftRight );
      assert( TK_CONCAT==OP_Concat );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      sqlite3VdbeAddOp(v, op, 0, 0);
      break;
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        char *z = sqliteMalloc( p->n + 2 );
        sprintf(z, "-%.*s", p->n, p->z);
        if( pLeft->op==TK_FLOAT ){
          sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
        }else{
          codeInteger(v, z, p->n+1);
        }
        sqliteFree(z);
        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );
      assert( TK_NOT==OP_Not );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3VdbeAddOp(v, op, 0, 0);
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      int dest;
      assert( TK_ISNULL==OP_IsNull );
      assert( TK_NOTNULL==OP_NotNull );
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
      sqlite3ExprCode(pParse, pExpr->pLeft);
      dest = sqlite3VdbeCurrentAddr(v) + 2;
      sqlite3VdbeAddOp(v, op, 1, dest);
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
      break;
    }
    case TK_AGG_FUNCTION: {
      sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      break;
    }
    case TK_CDATE:
    case TK_CTIME:
    case TK_CTIMESTAMP:
    case TK_GLOB:
    case TK_LIKE:
    case TK_FUNCTION: {
      ExprList *pList = pExpr->pList;
      int nExpr = pList ? pList->nExpr : 0;
      FuncDef *pDef;
      int nId;
      const char *zId;
      int p2 = 0;
      int i;
      u8 enc = pParse->db->enc;
      CollSeq *pColl = 0;
      getFunctionName(pExpr, &zId, &nId);
      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
      assert( pDef!=0 );
      nExpr = sqlite3ExprCodeExprList(pParse, pList);
      for(i=0; i<nExpr && i<32; i++){
        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
          p2 |= (1<<i);
        }
        if( pDef->needCollSeq && !pColl ){
          pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
        }
      }
      if( pDef->needCollSeq ){
        if( !pColl ) pColl = pParse->db->pDfltColl; 
        sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
      }
      sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      sqlite3CodeSubselect(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
      VdbeComment((v, "# load subquery result"));
      break;
    }
    case TK_IN: {
      int addr;
      char affinity;
      sqlite3CodeSubselect(pParse, pExpr);

      /* Figure out the affinity to use to create a key from the results
      ** of the expression. affinityStr stores a static string suitable for
      ** P3 of OP_MakeRecord.
      */
      affinity = comparisonAffinity(pExpr);

      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);

      /* Code the <expr> from "<expr> IN (...)". The temporary table
      ** pExpr->iTable contains the values that make up the (...) set.
      */
      sqlite3ExprCode(pParse, pExpr->pLeft);
      addr = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4);            /* addr + 0 */
      sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);   /* addr + 4 */
      sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);                  /* addr + 6 */

      break;
    }
#endif
    case TK_BETWEEN: {
      Expr *pLeft = pExpr->pLeft;
      struct ExprList_item *pLItem = pExpr->pList->a;
      Expr *pRight = pLItem->pExpr;
      sqlite3ExprCode(pParse, pLeft);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      sqlite3ExprCode(pParse, pRight);
      codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      pLItem++;
      pRight = pLItem->pExpr;
      sqlite3ExprCode(pParse, pRight);
      codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
      sqlite3VdbeAddOp(v, OP_And, 0, 0);
      break;
    }
    case TK_UPLUS:
    case TK_AS: {
      sqlite3ExprCode(pParse, pExpr->pLeft);
      break;
    }
    case TK_CASE: {
      int expr_end_label;
      int jumpInst;
      int addr;
      int nExpr;
      int i;
      ExprList *pEList;
      struct ExprList_item *aListelem;

      assert(pExpr->pList);
      assert((pExpr->pList->nExpr % 2) == 0);
      assert(pExpr->pList->nExpr > 0);
      pEList = pExpr->pList;
      aListelem = pEList->a;
      nExpr = pEList->nExpr;
      expr_end_label = sqlite3VdbeMakeLabel(v);
      if( pExpr->pLeft ){
        sqlite3ExprCode(pParse, pExpr->pLeft);
      }
      for(i=0; i<nExpr; i=i+2){
        sqlite3ExprCode(pParse, aListelem[i].pExpr);
        if( pExpr->pLeft ){
          sqlite3VdbeAddOp(v, OP_Dup, 1, 1);
          jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
                                 OP_Ne, 0, 1);
          sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
        }else{
          jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0);
        }
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr);
        sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label);
        addr = sqlite3VdbeCurrentAddr(v);
        sqlite3VdbeChangeP2(v, jumpInst, addr);
      }
      if( pExpr->pLeft ){
        sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      }
      if( pExpr->pRight ){
        sqlite3ExprCode(pParse, pExpr->pRight);
      }else{
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      }
      sqlite3VdbeResolveLabel(v, expr_end_label);
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
	return;
      }
      if( pExpr->iColumn!=OE_Ignore ){
         assert( pExpr->iColumn==OE_Rollback ||
                 pExpr->iColumn == OE_Abort ||
                 pExpr->iColumn == OE_Fail );
         sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
                        pExpr->token.z, pExpr->token.n);
         sqlite3VdbeDequoteP3(v, -1);
      } else {
         assert( pExpr->iColumn == OE_Ignore );
         sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
         sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
         VdbeComment((v, "# raise(IGNORE)"));
      }
    }
#endif
    break;
  }
}

#ifndef SQLITE_OMIT_TRIGGER
/*
** Generate code that evalutes the given expression and leaves the result
** on the stack.  See also sqlite3ExprCode().
**
** This routine might also cache the result and modify the pExpr tree
** so that it will make use of the cached result on subsequent evaluations
** rather than evaluate the whole expression again.  Trivial expressions are
** not cached.  If the expression is cached, its result is stored in a 
** memory location.
*/
void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){
  Vdbe *v = pParse->pVdbe;
  int iMem;
  int addr1, addr2;
  if( v==0 ) return;
  addr1 = sqlite3VdbeCurrentAddr(v);
  sqlite3ExprCode(pParse, pExpr);
  addr2 = sqlite3VdbeCurrentAddr(v);
  if( addr2>addr1+1 || sqlite3VdbeGetOp(v, addr1)->opcode==OP_Function ){
    iMem = pExpr->iTable = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
    pExpr->op = TK_REGISTER;
  }
}
#endif

/*
** Generate code that pushes the value of every element of the given
** expression list onto the stack.
**
** Return the number of elements pushed onto the stack.
*/
int sqlite3ExprCodeExprList(
  Parse *pParse,     /* Parsing context */
  ExprList *pList    /* The expression list to be coded */
){
  struct ExprList_item *pItem;
  int i, n;
  Vdbe *v;
  if( pList==0 ) return 0;
  v = sqlite3GetVdbe(pParse);
  n = pList->nExpr;
  for(pItem=pList->a, i=0; i<n; i++, pItem++){
    sqlite3ExprCode(pParse, pItem->pExpr);
  }
  return n;
}

/*
** Generate code for a boolean expression such that a jump is made
** to the label "dest" if the expression is true but execution
** continues straight thru if the expression is false.
**
** If the expression evaluates to NULL (neither true nor false), then
** take the jump if the jumpIfNull flag is true.
**
** This code depends on the fact that certain token values (ex: TK_EQ)
** are the same as opcode values (ex: OP_Eq) that implement the corresponding
** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
** the make process cause these values to align.  Assert()s in the code
** below verify that the numbers are aligned correctly.
*/
void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
  Vdbe *v = pParse->pVdbe;
  int op = 0;
  if( v==0 || pExpr==0 ) return;
  op = pExpr->op;
  switch( op ){
    case TK_AND: {
      int d2 = sqlite3VdbeMakeLabel(v);
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3VdbeResolveLabel(v, d2);
      break;
    }
    case TK_OR: {
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
      break;
    }
    case TK_NOT: {
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
      break;
    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      assert( TK_LT==OP_Lt );
      assert( TK_LE==OP_Le );
      assert( TK_GT==OP_Gt );
      assert( TK_GE==OP_Ge );
      assert( TK_EQ==OP_Eq );
      assert( TK_NE==OP_Ne );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      assert( TK_ISNULL==OP_IsNull );
      assert( TK_NOTNULL==OP_NotNull );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3VdbeAddOp(v, op, 1, dest);
      break;
    }
    case TK_BETWEEN: {
      /* The expression "x BETWEEN y AND z" is implemented as:
      **
      ** 1 IF (x < y) GOTO 3
      ** 2 IF (x <= z) GOTO <dest>
      ** 3 ...
      */
      int addr;
      Expr *pLeft = pExpr->pLeft;
      Expr *pRight = pExpr->pList->a[0].pExpr;
      sqlite3ExprCode(pParse, pLeft);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      sqlite3ExprCode(pParse, pRight);
      addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);

      pRight = pExpr->pList->a[1].pExpr;
      sqlite3ExprCode(pParse, pRight);
      codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);

      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      break;
    }
    default: {
      sqlite3ExprCode(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_If, jumpIfNull, dest);
      break;
    }
  }
}

/*
** Generate code for a boolean expression such that a jump is made
** to the label "dest" if the expression is false but execution
** continues straight thru if the expression is true.
**
** If the expression evaluates to NULL (neither true nor false) then
** jump if jumpIfNull is true or fall through if jumpIfNull is false.
*/
void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
  Vdbe *v = pParse->pVdbe;
  int op = 0;
  if( v==0 || pExpr==0 ) return;

  /* The value of pExpr->op and op are related as follows:
  **
  **       pExpr->op            op
  **       ---------          ----------
  **       TK_ISNULL          OP_NotNull
  **       TK_NOTNULL         OP_IsNull
  **       TK_NE              OP_Eq
  **       TK_EQ              OP_Ne
  **       TK_GT              OP_Le
  **       TK_LE              OP_Gt
  **       TK_GE              OP_Lt
  **       TK_LT              OP_Ge
  **
  ** For other values of pExpr->op, op is undefined and unused.
  ** The value of TK_ and OP_ constants are arranged such that we
  ** can compute the mapping above using the following expression.
  ** Assert()s verify that the computation is correct.
  */
  op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1);

  /* Verify correct alignment of TK_ and OP_ constants
  */
  assert( pExpr->op!=TK_ISNULL || op==OP_NotNull );
  assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull );
  assert( pExpr->op!=TK_NE || op==OP_Eq );
  assert( pExpr->op!=TK_EQ || op==OP_Ne );
  assert( pExpr->op!=TK_LT || op==OP_Ge );
  assert( pExpr->op!=TK_LE || op==OP_Gt );
  assert( pExpr->op!=TK_GT || op==OP_Le );
  assert( pExpr->op!=TK_GE || op==OP_Lt );

  switch( pExpr->op ){
    case TK_AND: {
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      break;
    }
    case TK_OR: {
      int d2 = sqlite3VdbeMakeLabel(v);
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, !jumpIfNull);
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3VdbeResolveLabel(v, d2);
      break;
    }
    case TK_NOT: {
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
      break;
    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3VdbeAddOp(v, op, 1, dest);
      break;
    }
    case TK_BETWEEN: {
      /* The expression is "x BETWEEN y AND z". It is implemented as:
      **
      ** 1 IF (x >= y) GOTO 3
      ** 2 GOTO <dest>
      ** 3 IF (x > z) GOTO <dest>
      */
      int addr;
      Expr *pLeft = pExpr->pLeft;
      Expr *pRight = pExpr->pList->a[0].pExpr;
      sqlite3ExprCode(pParse, pLeft);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      sqlite3ExprCode(pParse, pRight);
      addr = sqlite3VdbeCurrentAddr(v);
      codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);

      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, dest);
      pRight = pExpr->pList->a[1].pExpr;
      sqlite3ExprCode(pParse, pRight);
      codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull);
      break;
    }
    default: {
      sqlite3ExprCode(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
      break;
    }
  }
}

/*
** Do a deep comparison of two expression trees.  Return TRUE (non-zero)
** if they are identical and return FALSE if they differ in any way.
*/
int sqlite3ExprCompare(Expr *pA, Expr *pB){
  int i;
  if( pA==0 ){
    return pB==0;
  }else if( pB==0 ){
    return 0;
  }
  if( pA->op!=pB->op ) return 0;
  if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0;
  if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0;
  if( pA->pList ){
    if( pB->pList==0 ) return 0;
    if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
    for(i=0; i<pA->pList->nExpr; i++){
      if( !sqlite3ExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
        return 0;
      }
    }
  }else if( pB->pList ){
    return 0;
  }
  if( pA->pSelect || pB->pSelect ) return 0;
  if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
  if( pA->token.z ){
    if( pB->token.z==0 ) return 0;
    if( pB->token.n!=pA->token.n ) return 0;
    if( sqlite3StrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;
  }
  return 1;
}

/*
** Add a new element to the pParse->aAgg[] array and return its index.
** The new element is initialized to zero.  The calling function is
** expected to fill it in.
*/
static int appendAggInfo(Parse *pParse){
  if( (pParse->nAgg & 0x7)==0 ){
    int amt = pParse->nAgg + 8;
    AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
    if( aAgg==0 ){
      return -1;
    }
    pParse->aAgg = aAgg;
  }
  memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
  return pParse->nAgg++;
}

/*
** This is an xFunc for walkExprTree() used to implement 
** sqlite3ExprAnalyzeAggregates().  See sqlite3ExprAnalyzeAggregates
** for additional information.
**
** This routine analyzes the aggregate function at pExpr.
*/
static int analyzeAggregate(void *pArg, Expr *pExpr){
  int i;
  AggExpr *aAgg;
  NameContext *pNC = (NameContext *)pArg;
  Parse *pParse = pNC->pParse;
  SrcList *pSrcList = pNC->pSrcList;

  switch( pExpr->op ){
    case TK_COLUMN: {
      for(i=0; pSrcList && i<pSrcList->nSrc; i++){
        if( pExpr->iTable==pSrcList->a[i].iCursor ){
          aAgg = pParse->aAgg;
          for(i=0; i<pParse->nAgg; i++){
            if( aAgg[i].isAgg ) continue;
            if( aAgg[i].pExpr->iTable==pExpr->iTable
             && aAgg[i].pExpr->iColumn==pExpr->iColumn ){
              break;
            }
          }
          if( i>=pParse->nAgg ){
            i = appendAggInfo(pParse);
            if( i<0 ) return 1;
            pParse->aAgg[i].isAgg = 0;
            pParse->aAgg[i].pExpr = pExpr;
          }
          pExpr->iAgg = i;
          pExpr->iAggCtx = pNC->nDepth;
          return 1;
        }
      }
      return 1;
    }
    case TK_AGG_FUNCTION: {
      if( pNC->nDepth==0 ){
        aAgg = pParse->aAgg;
        for(i=0; i<pParse->nAgg; i++){
          if( !aAgg[i].isAgg ) continue;
          if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){
            break;
          }
        }
        if( i>=pParse->nAgg ){
          u8 enc = pParse->db->enc;
          i = appendAggInfo(pParse);
          if( i<0 ) return 1;
          pParse->aAgg[i].isAgg = 1;
          pParse->aAgg[i].pExpr = pExpr;
          pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db,
               pExpr->token.z, pExpr->token.n,
               pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0);
        }
        pExpr->iAgg = i;
        return 1;
      }
    }
  }
  if( pExpr->pSelect ){
    pNC->nDepth++;
    walkSelectExpr(pExpr->pSelect, analyzeAggregate, pNC);
    pNC->nDepth--;
  }
  return 0;
}

/*
** Analyze the given expression looking for aggregate functions and
** for variables that need to be added to the pParse->aAgg[] array.
** Make additional entries to the pParse->aAgg[] array as necessary.
**
** This routine should only be called after the expression has been
** analyzed by sqlite3ExprResolveNames().
**
** If errors are seen, leave an error message in zErrMsg and return
** the number of errors.
*/
int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
  int nErr = pNC->pParse->nErr;
  walkExprTree(pExpr, analyzeAggregate, pNC);
  return pNC->pParse->nErr - nErr;
}

/*
** Locate a user function given a name, a number of arguments and a flag
** indicating whether the function prefers UTF-16 over UTF-8.  Return a
** pointer to the FuncDef structure that defines that function, or return
** NULL if the function does not exist.
**
** If the createFlag argument is true, then a new (blank) FuncDef
** structure is created and liked into the "db" structure if a
** no matching function previously existed.  When createFlag is true
** and the nArg parameter is -1, then only a function that accepts
** any number of arguments will be returned.
**
** If createFlag is false and nArg is -1, then the first valid
** function found is returned.  A function is valid if either xFunc
** or xStep is non-zero.
**
** If createFlag is false, then a function with the required name and
** number of arguments may be returned even if the eTextRep flag does not
** match that requested.
*/
FuncDef *sqlite3FindFunction(
  sqlite3 *db,       /* An open database */
  const char *zName, /* Name of the function.  Not null-terminated */
  int nName,         /* Number of characters in the name */
  int nArg,          /* Number of arguments.  -1 means any number */
  u8 enc,            /* Preferred text encoding */
  int createFlag     /* Create new entry if true and does not otherwise exist */
){
  FuncDef *p;         /* Iterator variable */
  FuncDef *pFirst;    /* First function with this name */
  FuncDef *pBest = 0; /* Best match found so far */
  int bestmatch = 0;  


  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
  if( nArg<-1 ) nArg = -1;

  pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
  for(p=pFirst; p; p=p->pNext){
    /* During the search for the best function definition, bestmatch is set
    ** as follows to indicate the quality of the match with the definition
    ** pointed to by pBest:
    **
    ** 0: pBest is NULL. No match has been found.
    ** 1: A variable arguments function that prefers UTF-8 when a UTF-16
    **    encoding is requested, or vice versa.
    ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
    **    requested, or vice versa.
    ** 3: A variable arguments function using the same text encoding.
    ** 4: A function with the exact number of arguments requested that
    **    prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
    ** 5: A function with the exact number of arguments requested that
    **    prefers UTF-16LE when UTF-16BE is requested, or vice versa.
    ** 6: An exact match.
    **
    ** A larger value of 'matchqual' indicates a more desirable match.
    */
    if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
      int match = 1;          /* Quality of this match */
      if( p->nArg==nArg || nArg==-1 ){
        match = 4;
      }
      if( enc==p->iPrefEnc ){
        match += 2;
      }
      else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
               (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
        match += 1;
      }

      if( match>bestmatch ){
        pBest = p;
        bestmatch = match;
      }
    }
  }

  /* If the createFlag parameter is true, and the seach did not reveal an
  ** exact match for the name, number of arguments and encoding, then add a
  ** new entry to the hash table and return it.
  */
  if( createFlag && bestmatch<6 && 
      (pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){
    pBest->nArg = nArg;
    pBest->pNext = pFirst;
    pBest->zName = (char*)&pBest[1];
    pBest->iPrefEnc = enc;
    memcpy(pBest->zName, zName, nName);
    pBest->zName[nName] = 0;
    if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
      sqliteFree(pBest);
      return 0;
    }
  }

  if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
    return pBest;
  }
  return 0;
}
Added SQLite.Interop/src/func.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
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
/*
** 2002 February 23
**
** 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 file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
#include "os.h"

static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
  return context->pColl;
}

/*
** Implementation of the non-aggregate min() and max() functions
*/
static void minmaxFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int i;
  int mask;    /* 0 for min() or 0xffffffff for max() */
  int iBest;
  CollSeq *pColl;

  if( argc==0 ) return;
  mask = sqlite3_user_data(context)==0 ? 0 : -1;
  pColl = sqlite3GetFuncCollSeq(context);
  assert( pColl );
  assert( mask==-1 || mask==0 );
  iBest = 0;
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  for(i=1; i<argc; i++){
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
    if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
      iBest = i;
    }
  }
  sqlite3_result_value(context, argv[iBest]);
}

/*
** Return the type of the argument.
*/
static void typeofFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *z = 0;
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_NULL:    z = "null";    break;
    case SQLITE_INTEGER: z = "integer"; break;
    case SQLITE_TEXT:    z = "text";    break;
    case SQLITE_FLOAT:   z = "real";    break;
    case SQLITE_BLOB:    z = "blob";    break;
  }
  sqlite3_result_text(context, z, -1, SQLITE_STATIC);
}

/*
** Implementation of the length() function
*/
static void lengthFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int len;

  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_BLOB:
    case SQLITE_INTEGER:
    case SQLITE_FLOAT: {
      sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
      break;
    }
    case SQLITE_TEXT: {
      const char *z = sqlite3_value_text(argv[0]);
      for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
      sqlite3_result_int(context, len);
      break;
    }
    default: {
      sqlite3_result_null(context);
      break;
    }
  }
}

/*
** Implementation of the abs() function
*/
static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_INTEGER: {
      i64 iVal = sqlite3_value_int64(argv[0]);
      if( iVal<0 ) iVal = iVal * -1;
      sqlite3_result_int64(context, iVal);
      break;
    }
    case SQLITE_NULL: {
      sqlite3_result_null(context);
      break;
    }
    default: {
      double rVal = sqlite3_value_double(argv[0]);
      if( rVal<0 ) rVal = rVal * -1.0;
      sqlite3_result_double(context, rVal);
      break;
    }
  }
}

/*
** Implementation of the substr() function
*/
static void substrFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *z;
  const char *z2;
  int i;
  int p1, p2, len;

  assert( argc==3 );
  z = sqlite3_value_text(argv[0]);
  if( z==0 ) return;
  p1 = sqlite3_value_int(argv[1]);
  p2 = sqlite3_value_int(argv[2]);
  for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; }
  if( p1<0 ){
    p1 += len;
    if( p1<0 ){
      p2 += p1;
      p1 = 0;
    }
  }else if( p1>0 ){
    p1--;
  }
  if( p1+p2>len ){
    p2 = len-p1;
  }
  for(i=0; i<p1 && z[i]; i++){
    if( (z[i]&0xc0)==0x80 ) p1++;
  }
  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p1++; }
  for(; i<p1+p2 && z[i]; i++){
    if( (z[i]&0xc0)==0x80 ) p2++;
  }
  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
  if( p2<0 ) p2 = 0;
  sqlite3_result_text(context, &z[p1], p2, SQLITE_TRANSIENT);
}

/*
** Implementation of the round() function
*/
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  int n = 0;
  double r;
  char zBuf[100];
  assert( argc==1 || argc==2 );
  if( argc==2 ){
    if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
    n = sqlite3_value_int(argv[1]);
    if( n>30 ) n = 30;
    if( n<0 ) n = 0;
  }
  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  r = sqlite3_value_double(argv[0]);
  sprintf(zBuf,"%.*f",n,r);
  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}

/*
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  unsigned char *z;
  int i;
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
  if( z==0 ) return;
  strcpy(z, sqlite3_value_text(argv[0]));
  for(i=0; z[i]; i++){
    z[i] = toupper(z[i]);
  }
  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
  sqliteFree(z);
}
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  unsigned char *z;
  int i;
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
  if( z==0 ) return;
  strcpy(z, sqlite3_value_text(argv[0]));
  for(i=0; z[i]; i++){
    z[i] = tolower(z[i]);
  }
  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
  sqliteFree(z);
}

/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
** All three do the same thing.  They return the first non-NULL
** argument.
*/
static void ifnullFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int i;
  for(i=0; i<argc; i++){
    if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
      sqlite3_result_value(context, argv[i]);
      break;
    }
  }
}

/*
** Implementation of random().  Return a random integer.  
*/
static void randomFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int r;
  sqlite3Randomness(sizeof(r), &r);
  sqlite3_result_int(context, r);
}

/*
** Implementation of the last_insert_rowid() SQL function.  The return
** value is the same as the sqlite3_last_insert_rowid() API function.
*/
static void last_insert_rowid(
  sqlite3_context *context, 
  int arg, 
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_user_data(context);
  sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
}

/*
** Implementation of the changes() SQL function.  The return value is the
** same as the sqlite3_changes() API function.
*/
static void changes(
  sqlite3_context *context,
  int arg,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_user_data(context);
  sqlite3_result_int(context, sqlite3_changes(db));
}

/*
** Implementation of the total_changes() SQL function.  The return value is
** the same as the sqlite3_total_changes() API function.
*/
static void total_changes(
  sqlite3_context *context,
  int arg,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_user_data(context);
  sqlite3_result_int(context, sqlite3_total_changes(db));
}

/*
** A structure defining how to do GLOB-style comparisons.
*/
struct compareInfo {
  u8 matchAll;
  u8 matchOne;
  u8 matchSet;
  u8 noCase;
};
static const struct compareInfo globInfo = { '*', '?', '[', 0 };
static const struct compareInfo likeInfo = { '%', '_',   0, 1 };

/*
** X is a pointer to the first byte of a UTF-8 character.  Increment
** X so that it points to the next character.  This only works right
** if X points to a well-formed UTF-8 string.
*/
#define sqliteNextChar(X)  while( (0xc0&*++(X))==0x80 ){}
#define sqliteCharVal(X)   sqlite3ReadUtf8(X)


/*
** Compare two UTF-8 strings for equality where the first string can
** potentially be a "glob" expression.  Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
**
**      '*'       Matches any sequence of zero or more characters.
**
**      '?'       Matches exactly one character.
**
**     [...]      Matches one character from the enclosed list of
**                characters.
**
**     [^...]     Matches one character not in the enclosed list.
**
** With the [...] and [^...] matching, a ']' character can be included
** in the list by making it the first character after '[' or '^'.  A
** range of characters can be specified using '-'.  Example:
** "[a-z]" matches any single lower-case letter.  To match a '-', make
** it the last character in the list.
**
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]".  Like this:
**
**         abc[*]xyz        Matches "abc*xyz" only
*/
static int patternCompare(
  const u8 *zPattern,              /* The glob pattern */
  const u8 *zString,               /* The string to compare against the glob */
  const struct compareInfo *pInfo, /* Information about how to do the compare */
  const int esc                    /* The escape character */
){
  register int c;
  int invert;
  int seen;
  int c2;
  u8 matchOne = pInfo->matchOne;
  u8 matchAll = pInfo->matchAll;
  u8 matchSet = pInfo->matchSet;
  u8 noCase = pInfo->noCase; 
  int prevEscape = 0;     /* True if the previous character was 'escape' */

  while( (c = *zPattern)!=0 ){
    if( !prevEscape && c==matchAll ){
      while( (c=zPattern[1]) == matchAll || c == matchOne ){
        if( c==matchOne ){
          if( *zString==0 ) return 0;
          sqliteNextChar(zString);
        }
        zPattern++;
      }
      if( c && esc && sqlite3ReadUtf8(&zPattern[1])==esc ){
        u8 const *zTemp = &zPattern[1];
        sqliteNextChar(zTemp);
        c = *zTemp;
      }
      if( c==0 ) return 1;
      if( c==matchSet ){
        assert( esc==0 );   /* This is GLOB, not LIKE */
        while( *zString && patternCompare(&zPattern[1],zString,pInfo,esc)==0 ){
          sqliteNextChar(zString);
        }
        return *zString!=0;
      }else{
        while( (c2 = *zString)!=0 ){
          if( noCase ){
            c2 = sqlite3UpperToLower[c2];
            c = sqlite3UpperToLower[c];
            while( c2 != 0 && c2 != c ){ c2 = sqlite3UpperToLower[*++zString]; }
          }else{
            while( c2 != 0 && c2 != c ){ c2 = *++zString; }
          }
          if( c2==0 ) return 0;
          if( patternCompare(&zPattern[1],zString,pInfo,esc) ) return 1;
          sqliteNextChar(zString);
        }
        return 0;
      }
    }else if( !prevEscape && c==matchOne ){
      if( *zString==0 ) return 0;
      sqliteNextChar(zString);
      zPattern++;
    }else if( c==matchSet ){
      int prior_c = 0;
      assert( esc==0 );    /* This only occurs for GLOB, not LIKE */
      seen = 0;
      invert = 0;
      c = sqliteCharVal(zString);
      if( c==0 ) return 0;
      c2 = *++zPattern;
      if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
      if( c2==']' ){
        if( c==']' ) seen = 1;
        c2 = *++zPattern;
      }
      while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){
        if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){
          zPattern++;
          c2 = sqliteCharVal(zPattern);
          if( c>=prior_c && c<=c2 ) seen = 1;
          prior_c = 0;
        }else if( c==c2 ){
          seen = 1;
          prior_c = c2;
        }else{
          prior_c = c2;
        }
        sqliteNextChar(zPattern);
      }
      if( c2==0 || (seen ^ invert)==0 ) return 0;
      sqliteNextChar(zString);
      zPattern++;
    }else if( esc && !prevEscape && sqlite3ReadUtf8(zPattern)==esc){
      prevEscape = 1;
      sqliteNextChar(zPattern);
    }else{
      if( noCase ){
        if( sqlite3UpperToLower[c] != sqlite3UpperToLower[*zString] ) return 0;
      }else{
        if( c != *zString ) return 0;
      }
      zPattern++;
      zString++;
      prevEscape = 0;
    }
  }
  return *zString==0;
}


/*
** Implementation of the like() SQL function.  This function implements
** the build-in LIKE operator.  The first argument to the function is the
** pattern and the second argument is the string.  So, the SQL statements:
**
**       A LIKE B
**
** is implemented as like(B,A).
**
** If the pointer retrieved by via a call to sqlite3_user_data() is
** not NULL, then this function uses UTF-16. Otherwise UTF-8.
*/
static void likeFunc(
  sqlite3_context *context, 
  int argc, 
  sqlite3_value **argv
){
  const unsigned char *zA = sqlite3_value_text(argv[0]);
  const unsigned char *zB = sqlite3_value_text(argv[1]);
  int escape = 0;
  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
    if( sqlite3utf8CharLen(zEsc, -1)!=1 ){
      sqlite3_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite3ReadUtf8(zEsc);
  }
  if( zA && zB ){
    sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo, escape));
  }
}

/*
** Implementation of the glob() SQL function.  This function implements
** the build-in GLOB operator.  The first argument to the function is the
** string and the second argument is the pattern.  So, the SQL statements:
**
**       A GLOB B
**
** is implemented as glob(B,A).
*/
static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){
  const unsigned char *zA = sqlite3_value_text(argv[0]);
  const unsigned char *zB = sqlite3_value_text(argv[1]);
  if( zA && zB ){
    sqlite3_result_int(context, patternCompare(zA, zB, &globInfo, 0));
  }
}

/*
** Implementation of the NULLIF(x,y) function.  The result is the first
** argument if the arguments are different.  The result is NULL if the
** arguments are equal to each other.
*/
static void nullifFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  CollSeq *pColl = sqlite3GetFuncCollSeq(context);
  if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
    sqlite3_result_value(context, argv[0]);
  }
}

/*
** Implementation of the VERSION(*) function.  The result is the version
** of the SQLite library that is running.
*/
static void versionFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
}


/*
** EXPERIMENTAL - This is not an official function.  The interface may
** change.  This function may disappear.  Do not write code that depends
** on this function.
**
** Implementation of the QUOTE() function.  This function takes a single
** argument.  If the argument is numeric, the return value is the same as
** the argument.  If the argument is NULL, the return value is the string
** "NULL".  Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  if( argc<1 ) return;
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_NULL: {
      sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
      break;
    }
    case SQLITE_INTEGER:
    case SQLITE_FLOAT: {
      sqlite3_result_value(context, argv[0]);
      break;
    }
    case SQLITE_BLOB: {
      static const char hexdigits[] = { 
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
      };
      char *zText = 0;
      int nBlob = sqlite3_value_bytes(argv[0]);
      char const *zBlob = sqlite3_value_blob(argv[0]);

      zText = (char *)sqliteMalloc((2*nBlob)+4); 
      if( !zText ){
        sqlite3_result_error(context, "out of memory", -1);
      }else{
        int i;
        for(i=0; i<nBlob; i++){
          zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
          zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
        }
        zText[(nBlob*2)+2] = '\'';
        zText[(nBlob*2)+3] = '\0';
        zText[0] = 'X';
        zText[1] = '\'';
        sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
        sqliteFree(zText);
      }
      break;
    }
    case SQLITE_TEXT: {
      int i,j,n;
      const char *zArg = sqlite3_value_text(argv[0]);
      char *z;

      for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
      z = sqliteMalloc( i+n+3 );
      if( z==0 ) return;
      z[0] = '\'';
      for(i=0, j=1; zArg[i]; i++){
        z[j++] = zArg[i];
        if( zArg[i]=='\'' ){
          z[j++] = '\'';
        }
      }
      z[j++] = '\'';
      z[j] = 0;
      sqlite3_result_text(context, z, j, SQLITE_TRANSIENT);
      sqliteFree(z);
    }
  }
}

#ifdef SQLITE_SOUNDEX
/*
** Compute the soundex encoding of a word.
*/
static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  char zResult[8];
  const u8 *zIn;
  int i, j;
  static const unsigned char iCode[] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
  };
  assert( argc==1 );
  zIn = (u8*)sqlite3_value_text(argv[0]);
  for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
  if( zIn[i] ){
    zResult[0] = toupper(zIn[i]);
    for(j=1; j<4 && zIn[i]; i++){
      int code = iCode[zIn[i]&0x7f];
      if( code>0 ){
        zResult[j++] = code + '0';
      }
    }
    while( j<4 ){
      zResult[j++] = '0';
    }
    zResult[j] = 0;
    sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
  }else{
    sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
  }
}
#endif

#ifdef SQLITE_TEST
/*
** This function generates a string of random characters.  Used for
** generating test data.
*/
static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){
  static const unsigned char zSrc[] = 
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "0123456789"
     ".-!,:*^+=_|?/<> ";
  int iMin, iMax, n, r, i;
  unsigned char zBuf[1000];
  if( argc>=1 ){
    iMin = sqlite3_value_int(argv[0]);
    if( iMin<0 ) iMin = 0;
    if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
  }else{
    iMin = 1;
  }
  if( argc>=2 ){
    iMax = sqlite3_value_int(argv[1]);
    if( iMax<iMin ) iMax = iMin;
    if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
  }else{
    iMax = 50;
  }
  n = iMin;
  if( iMax>iMin ){
    sqlite3Randomness(sizeof(r), &r);
    r &= 0x7fffffff;
    n += r%(iMax + 1 - iMin);
  }
  assert( n<sizeof(zBuf) );
  sqlite3Randomness(n, zBuf);
  for(i=0; i<n; i++){
    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
  }
  zBuf[n] = 0;
  sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT);
}
#endif /* SQLITE_TEST */

#ifdef SQLITE_TEST
/*
** The following two SQL functions are used to test returning a text
** result with a destructor. Function 'test_destructor' takes one argument
** and returns the same argument interpreted as TEXT. A destructor is
** passed with the sqlite3_result_text() call.
**
** SQL function 'test_destructor_count' returns the number of outstanding 
** allocations made by 'test_destructor';
**
** WARNING: Not threadsafe.
*/
static int test_destructor_count_var = 0;
static void destructor(void *p){
  char *zVal = (char *)p;
  assert(zVal);
  zVal--;
  sqliteFree(zVal);
  test_destructor_count_var--;
}
static void test_destructor(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  char *zVal;
  int len;
  sqlite3 *db = sqlite3_user_data(pCtx);
 
  test_destructor_count_var++;
  assert( nArg==1 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  len = sqlite3ValueBytes(argv[0], db->enc); 
  zVal = sqliteMalloc(len+3);
  zVal[len] = 0;
  zVal[len-1] = 0;
  assert( zVal );
  zVal++;
  memcpy(zVal, sqlite3ValueText(argv[0], db->enc), len);
  if( db->enc==SQLITE_UTF8 ){
    sqlite3_result_text(pCtx, zVal, -1, destructor);
#ifndef SQLITE_OMIT_UTF16
  }else if( db->enc==SQLITE_UTF16LE ){
    sqlite3_result_text16le(pCtx, zVal, -1, destructor);
  }else{
    sqlite3_result_text16be(pCtx, zVal, -1, destructor);
#endif /* SQLITE_OMIT_UTF16 */
  }
}
static void test_destructor_count(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  sqlite3_result_int(pCtx, test_destructor_count_var);
}
#endif /* SQLITE_TEST */

#ifdef SQLITE_TEST
/*
** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata()
** interface.
**
** The test_auxdata() SQL function attempts to register each of its arguments
** as auxiliary data.  If there are no prior registrations of aux data for
** that argument (meaning the argument is not a constant or this is its first
** call) then the result for that argument is 0.  If there is a prior
** registration, the result for that argument is 1.  The overall result
** is the individual argument results separated by spaces.
*/
static void free_test_auxdata(void *p) {sqliteFree(p);}
static void test_auxdata(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  int i;
  char *zRet = sqliteMalloc(nArg*2);
  if( !zRet ) return;
  for(i=0; i<nArg; i++){
    char const *z = sqlite3_value_text(argv[i]);
    if( z ){
      char *zAux = sqlite3_get_auxdata(pCtx, i);
      if( zAux ){
        zRet[i*2] = '1';
        if( strcmp(zAux, z) ){
          sqlite3_result_error(pCtx, "Auxilary data corruption", -1);
          return;
        }
      }else{
        zRet[i*2] = '0';
        zAux = sqliteStrDup(z);
        sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata);
      }
      zRet[i*2+1] = ' ';
    }
  }
  sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
}
#endif /* SQLITE_TEST */

#ifdef SQLITE_TEST
/*
** A function to test error reporting from user functions. This function
** returns a copy of it's first argument as an error.
*/
static void test_error(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  sqlite3_result_error(pCtx, sqlite3_value_text(argv[0]), 0);
}
#endif /* SQLITE_TEST */

/*
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
  double sum;     /* Sum of terms */
  int cnt;        /* Number of elements summed */
};

/*
** Routines used to compute the sum or average.
*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  SumCtx *p;
  if( argc<1 ) return;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p && SQLITE_NULL!=sqlite3_value_type(argv[0]) ){
    p->sum += sqlite3_value_double(argv[0]);
    p->cnt++;
  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  sqlite3_result_double(context, p ? p->sum : 0.0);
}
static void avgFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p && p->cnt>0 ){
    sqlite3_result_double(context, p->sum/(double)p->cnt);
  }
}

/*
** An instance of the following structure holds the context of a
** variance or standard deviation computation.
*/
typedef struct StdDevCtx StdDevCtx;
struct StdDevCtx {
  double sum;     /* Sum of terms */
  double sum2;    /* Sum of the squares of terms */
  int cnt;        /* Number of terms counted */
};

/*
** The following structure keeps track of state information for the
** count() aggregate function.
*/
typedef struct CountCtx CountCtx;
struct CountCtx {
  int n;
};

/*
** Routines to implement the count() aggregate function.
*/
static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  CountCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
    p->n++;
  }
}   
static void countFinalize(sqlite3_context *context){
  CountCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  sqlite3_result_int(context, p ? p->n : 0);
}

/*
** This function tracks state information for the min() and max()
** aggregate functions.
*/
typedef struct MinMaxCtx MinMaxCtx;
struct MinMaxCtx {
  char *z;         /* The best so far */
  char zBuf[28];   /* Space that can be used for storage */
};

/*
** Routines to implement min() and max() aggregate functions.
*/
static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  Mem *pArg  = (Mem *)argv[0];
  Mem *pBest;

  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
  if( !pBest ) return;

  if( pBest->flags ){
    int max;
    int cmp;
    CollSeq *pColl = sqlite3GetFuncCollSeq(context);
    /* This step function is used for both the min() and max() aggregates,
    ** the only difference between the two being that the sense of the
    ** comparison is inverted. For the max() aggregate, the
    ** sqlite3_user_data() function returns (void *)-1. For min() it
    ** returns (void *)db, where db is the sqlite3* database pointer.
    ** Therefore the next statement sets variable 'max' to 1 for the max()
    ** aggregate, or 0 for min().
    */
    max = ((sqlite3_user_data(context)==(void *)-1)?1:0);
    cmp = sqlite3MemCompare(pBest, pArg, pColl);
    if( (max && cmp<0) || (!max && cmp>0) ){
      sqlite3VdbeMemCopy(pBest, pArg);
    }
  }else{
    sqlite3VdbeMemCopy(pBest, pArg);
  }
}
static void minMaxFinalize(sqlite3_context *context){
  sqlite3_value *pRes;
  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, sizeof(Mem));
  if( pRes->flags ){
    sqlite3_result_value(context, pRes);
  }
  sqlite3VdbeMemRelease(pRes);
}


/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
*/
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
  static const struct {
     char *zName;
     signed char nArg;
     u8 argType;           /* 0: none.  1: db  2: (-1) */
     u8 eTextRep;          /* 1: UTF-16.  0: UTF-8 */
     u8 needCollSeq;
     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
  } aFuncs[] = {
    { "min",               -1, 0, SQLITE_UTF8,    1, minmaxFunc },
    { "min",                0, 0, SQLITE_UTF8,    1, 0          },
    { "max",               -1, 2, SQLITE_UTF8,    1, minmaxFunc },
    { "max",                0, 2, SQLITE_UTF8,    1, 0          },
    { "typeof",             1, 0, SQLITE_UTF8,    0, typeofFunc },
    { "length",             1, 0, SQLITE_UTF8,    0, lengthFunc },
    { "substr",             3, 0, SQLITE_UTF8,    0, substrFunc },
#ifndef SQLITE_OMIT_UTF16
    { "substr",             3, 0, SQLITE_UTF16LE, 0, sqlite3utf16Substr },
#endif
    { "abs",                1, 0, SQLITE_UTF8,    0, absFunc    },
    { "round",              1, 0, SQLITE_UTF8,    0, roundFunc  },
    { "round",              2, 0, SQLITE_UTF8,    0, roundFunc  },
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
    { "coalesce",           0, 0, SQLITE_UTF8,    0, 0          },
    { "coalesce",           1, 0, SQLITE_UTF8,    0, 0          },
    { "ifnull",             2, 0, SQLITE_UTF8,    1, ifnullFunc },
    { "random",            -1, 0, SQLITE_UTF8,    0, randomFunc },
    { "like",               2, 0, SQLITE_UTF8,    0, likeFunc   },
    { "like",               3, 0, SQLITE_UTF8,    0, likeFunc   },
    { "glob",               2, 0, SQLITE_UTF8,    0, globFunc   },
    { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
    { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
    { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
    { "last_insert_rowid",  0, 1, SQLITE_UTF8,    0, last_insert_rowid },
    { "changes",            0, 1, SQLITE_UTF8,    0, changes    },
    { "total_changes",      0, 1, SQLITE_UTF8,    0, total_changes },
#ifdef SQLITE_SOUNDEX
    { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
#endif
#ifdef SQLITE_TEST
    { "randstr",               2, 0, SQLITE_UTF8, 0, randStr    },
    { "test_destructor",       1, 1, SQLITE_UTF8, 0, test_destructor},
    { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
    { "test_auxdata",         -1, 0, SQLITE_UTF8, 0, test_auxdata},
    { "test_error",            1, 0, SQLITE_UTF8, 0, test_error},
#endif
  };
  static const struct {
    char *zName;
    signed char nArg;
    u8 argType;
    u8 needCollSeq;
    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
    void (*xFinalize)(sqlite3_context*);
  } aAggs[] = {
    { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
    { "max",    1, 2, 1, minmaxStep,   minMaxFinalize },
    { "sum",    1, 0, 0, sumStep,      sumFinalize    },
    { "avg",    1, 0, 0, sumStep,      avgFinalize    },
    { "count",  0, 0, 0, countStep,    countFinalize  },
    { "count",  1, 0, 0, countStep,    countFinalize  },
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
    void *pArg = 0;
    switch( aFuncs[i].argType ){
      case 1: pArg = db; break;
      case 2: pArg = (void *)(-1); break;
    }
    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
        aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
    if( aFuncs[i].needCollSeq ){
      FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, 
          strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0);
      if( pFunc && aFuncs[i].needCollSeq ){
        pFunc->needCollSeq = 1;
      }
    }
  }
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions(db);
#endif
  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
    void *pArg = 0;
    switch( aAggs[i].argType ){
      case 1: pArg = db; break;
      case 2: pArg = (void *)(-1); break;
    }
    sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
        pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
    if( aAggs[i].needCollSeq ){
      FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
          strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
      if( pFunc && aAggs[i].needCollSeq ){
        pFunc->needCollSeq = 1;
      }
    }
  }
  sqlite3RegisterDateTimeFunctions(db);
}
Added SQLite.Interop/src/hash.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
/*
** 2001 September 22
**
** 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 is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
** "pNew" is a pointer to the hash table that is to be initialized.
** keyClass is one of the constants SQLITE_HASH_INT, SQLITE_HASH_POINTER,
** SQLITE_HASH_BINARY, or SQLITE_HASH_STRING.  The value of keyClass 
** determines what kind of key the hash table will use.  "copyKey" is
** true if the hash table should make its own private copy of keys and
** false if it should just use the supplied pointer.  CopyKey only makes
** sense for SQLITE_HASH_STRING and SQLITE_HASH_BINARY and is ignored
** for other key classes.
*/
void sqlite3HashInit(Hash *pNew, int keyClass, int copyKey){
  assert( pNew!=0 );
  assert( keyClass>=SQLITE_HASH_STRING && keyClass<=SQLITE_HASH_BINARY );
  pNew->keyClass = keyClass;
#if 0
  if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0;
#endif
  pNew->copyKey = copyKey;
  pNew->first = 0;
  pNew->count = 0;
  pNew->htsize = 0;
  pNew->ht = 0;
}

/* Remove all entries from a hash table.  Reclaim all memory.
** Call this routine to delete a hash table or to reset a hash table
** to the empty state.
*/
void sqlite3HashClear(Hash *pH){
  HashElem *elem;         /* For looping over all elements of the table */

  assert( pH!=0 );
  elem = pH->first;
  pH->first = 0;
  if( pH->ht ) sqliteFree(pH->ht);
  pH->ht = 0;
  pH->htsize = 0;
  while( elem ){
    HashElem *next_elem = elem->next;
    if( pH->copyKey && elem->pKey ){
      sqliteFree(elem->pKey);
    }
    sqliteFree(elem);
    elem = next_elem;
  }
  pH->count = 0;
}

#if 0 /* NOT USED */
/*
** Hash and comparison functions when the mode is SQLITE_HASH_INT
*/
static int intHash(const void *pKey, int nKey){
  return nKey ^ (nKey<<8) ^ (nKey>>8);
}
static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
  return n2 - n1;
}
#endif

#if 0 /* NOT USED */
/*
** Hash and comparison functions when the mode is SQLITE_HASH_POINTER
*/
static int ptrHash(const void *pKey, int nKey){
  uptr x = Addr(pKey);
  return x ^ (x<<8) ^ (x>>8);
}
static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
  if( pKey1==pKey2 ) return 0;
  if( pKey1<pKey2 ) return -1;
  return 1;
}
#endif

/*
** Hash and comparison functions when the mode is SQLITE_HASH_STRING
*/
static int strHash(const void *pKey, int nKey){
  const char *z = (const char *)pKey;
  int h = 0;
  if( nKey<=0 ) nKey = strlen(z);
  while( nKey > 0  ){
    h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
    nKey--;
  }
  return h & 0x7fffffff;
}
static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
  if( n1!=n2 ) return 1;
  return sqlite3StrNICmp((const char*)pKey1,(const char*)pKey2,n1);
}

/*
** Hash and comparison functions when the mode is SQLITE_HASH_BINARY
*/
static int binHash(const void *pKey, int nKey){
  int h = 0;
  const char *z = (const char *)pKey;
  while( nKey-- > 0 ){
    h = (h<<3) ^ h ^ *(z++);
  }
  return h & 0x7fffffff;
}
static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
  if( n1!=n2 ) return 1;
  return memcmp(pKey1,pKey2,n1);
}

/*
** Return a pointer to the appropriate hash function given the key class.
**
** The C syntax in this function definition may be unfamilar to some 
** programmers, so we provide the following additional explanation:
**
** The name of the function is "hashFunction".  The function takes a
** single parameter "keyClass".  The return value of hashFunction()
** is a pointer to another function.  Specifically, the return value
** of hashFunction() is a pointer to a function that takes two parameters
** with types "const void*" and "int" and returns an "int".
*/
static int (*hashFunction(int keyClass))(const void*,int){
#if 0  /* HASH_INT and HASH_POINTER are never used */
  switch( keyClass ){
    case SQLITE_HASH_INT:     return &intHash;
    case SQLITE_HASH_POINTER: return &ptrHash;
    case SQLITE_HASH_STRING:  return &strHash;
    case SQLITE_HASH_BINARY:  return &binHash;;
    default: break;
  }
  return 0;
#else
  if( keyClass==SQLITE_HASH_STRING ){
    return &strHash;
  }else{
    assert( keyClass==SQLITE_HASH_BINARY );
    return &binHash;
  }
#endif
}

/*
** Return a pointer to the appropriate hash function given the key class.
**
** For help in interpreted the obscure C code in the function definition,
** see the header comment on the previous function.
*/
static int (*compareFunction(int keyClass))(const void*,int,const void*,int){
#if 0 /* HASH_INT and HASH_POINTER are never used */
  switch( keyClass ){
    case SQLITE_HASH_INT:     return &intCompare;
    case SQLITE_HASH_POINTER: return &ptrCompare;
    case SQLITE_HASH_STRING:  return &strCompare;
    case SQLITE_HASH_BINARY:  return &binCompare;
    default: break;
  }
  return 0;
#else
  if( keyClass==SQLITE_HASH_STRING ){
    return &strCompare;
  }else{
    assert( keyClass==SQLITE_HASH_BINARY );
    return &binCompare;
  }
#endif
}

/* Link an element into the hash table
*/
static void insertElement(
  Hash *pH,              /* The complete hash table */
  struct _ht *pEntry,    /* The entry into which pNew is inserted */
  HashElem *pNew         /* The element to be inserted */
){
  HashElem *pHead;       /* First element already in pEntry */
  pHead = pEntry->chain;
  if( pHead ){
    pNew->next = pHead;
    pNew->prev = pHead->prev;
    if( pHead->prev ){ pHead->prev->next = pNew; }
    else             { pH->first = pNew; }
    pHead->prev = pNew;
  }else{
    pNew->next = pH->first;
    if( pH->first ){ pH->first->prev = pNew; }
    pNew->prev = 0;
    pH->first = pNew;
  }
  pEntry->count++;
  pEntry->chain = pNew;
}


/* Resize the hash table so that it cantains "new_size" buckets.
** "new_size" must be a power of 2.  The hash table might fail 
** to resize if sqliteMalloc() fails.
*/
static void rehash(Hash *pH, int new_size){
  struct _ht *new_ht;            /* The new hash table */
  HashElem *elem, *next_elem;    /* For looping over existing elements */
  int (*xHash)(const void*,int); /* The hash function */

  assert( (new_size & (new_size-1))==0 );
  new_ht = (struct _ht *)sqliteMalloc( new_size*sizeof(struct _ht) );
  if( new_ht==0 ) return;
  if( pH->ht ) sqliteFree(pH->ht);
  pH->ht = new_ht;
  pH->htsize = new_size;
  xHash = hashFunction(pH->keyClass);
  for(elem=pH->first, pH->first=0; elem; elem = next_elem){
    int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
    next_elem = elem->next;
    insertElement(pH, &new_ht[h], elem);
  }
}

/* This function (for internal use only) locates an element in an
** hash table that matches the given key.  The hash for this key has
** already been computed and is passed as the 4th parameter.
*/
static HashElem *findElementGivenHash(
  const Hash *pH,     /* The pH to be searched */
  const void *pKey,   /* The key we are searching for */
  int nKey,
  int h               /* The hash for this key. */
){
  HashElem *elem;                /* Used to loop thru the element list */
  int count;                     /* Number of elements left to test */
  int (*xCompare)(const void*,int,const void*,int);  /* comparison function */

  if( pH->ht ){
    struct _ht *pEntry = &pH->ht[h];
    elem = pEntry->chain;
    count = pEntry->count;
    xCompare = compareFunction(pH->keyClass);
    while( count-- && elem ){
      if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ 
        return elem;
      }
      elem = elem->next;
    }
  }
  return 0;
}

/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
*/
static void removeElementGivenHash(
  Hash *pH,         /* The pH containing "elem" */
  HashElem* elem,   /* The element to be removed from the pH */
  int h             /* Hash value for the element */
){
  struct _ht *pEntry;
  if( elem->prev ){
    elem->prev->next = elem->next; 
  }else{
    pH->first = elem->next;
  }
  if( elem->next ){
    elem->next->prev = elem->prev;
  }
  pEntry = &pH->ht[h];
  if( pEntry->chain==elem ){
    pEntry->chain = elem->next;
  }
  pEntry->count--;
  if( pEntry->count<=0 ){
    pEntry->chain = 0;
  }
  if( pH->copyKey && elem->pKey ){
    sqliteFree(elem->pKey);
  }
  sqliteFree( elem );
  pH->count--;
}

/* Attempt to locate an element of the hash table pH with a key
** that matches pKey,nKey.  Return the data for this element if it is
** found, or NULL if there is no match.
*/
void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
  int h;             /* A hash on key */
  HashElem *elem;    /* The element that matches key */
  int (*xHash)(const void*,int);  /* The hash function */

  if( pH==0 || pH->ht==0 ) return 0;
  xHash = hashFunction(pH->keyClass);
  assert( xHash!=0 );
  h = (*xHash)(pKey,nKey);
  assert( (pH->htsize & (pH->htsize-1))==0 );
  elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1));
  return elem ? elem->data : 0;
}

/* Insert an element into the hash table pH.  The key is pKey,nKey
** and the data is "data".
**
** If no element exists with a matching key, then a new
** element is created.  A copy of the key is made if the copyKey
** flag is set.  NULL is returned.
**
** If another element already exists with the same key, then the
** new data replaces the old data and the old data is returned.
** The key is not copied in this instance.  If a malloc fails, then
** the new data is returned and the hash table is unchanged.
**
** If the "data" parameter to this function is NULL, then the
** element corresponding to "key" is removed from the hash table.
*/
void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
  int hraw;             /* Raw hash value of the key */
  int h;                /* the hash of the key modulo hash table size */
  HashElem *elem;       /* Used to loop thru the element list */
  HashElem *new_elem;   /* New element added to the pH */
  int (*xHash)(const void*,int);  /* The hash function */

  assert( pH!=0 );
  xHash = hashFunction(pH->keyClass);
  assert( xHash!=0 );
  hraw = (*xHash)(pKey, nKey);
  assert( (pH->htsize & (pH->htsize-1))==0 );
  h = hraw & (pH->htsize-1);
  elem = findElementGivenHash(pH,pKey,nKey,h);
  if( elem ){
    void *old_data = elem->data;
    if( data==0 ){
      removeElementGivenHash(pH,elem,h);
    }else{
      elem->data = data;
    }
    return old_data;
  }
  if( data==0 ) return 0;
  new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
  if( new_elem==0 ) return data;
  if( pH->copyKey && pKey!=0 ){
    new_elem->pKey = sqliteMallocRaw( nKey );
    if( new_elem->pKey==0 ){
      sqliteFree(new_elem);
      return data;
    }
    memcpy((void*)new_elem->pKey, pKey, nKey);
  }else{
    new_elem->pKey = (void*)pKey;
  }
  new_elem->nKey = nKey;
  pH->count++;
  if( pH->htsize==0 ){
    rehash(pH,8);
    if( pH->htsize==0 ){
      pH->count = 0;
      sqliteFree(new_elem);
      return data;
    }
  }
  if( pH->count > pH->htsize ){
    rehash(pH,pH->htsize*2);
  }
  assert( pH->htsize>0 );
  assert( (pH->htsize & (pH->htsize-1))==0 );
  h = hraw & (pH->htsize-1);
  insertElement(pH, &pH->ht[h], new_elem);
  new_elem->data = data;
  return 0;
}
Added SQLite.Interop/src/hash.h.


























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2001 September 22
**
** 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 is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_

/* Forward declarations of structures. */
typedef struct Hash Hash;
typedef struct HashElem HashElem;

/* A complete hash table is an instance of the following structure.
** The internals of this structure are intended to be opaque -- client
** code should not attempt to access or modify the fields of this structure
** directly.  Change this structure only by using the routines below.
** However, many of the "procedures" and "functions" for modifying and
** accessing this structure are really macros, so we can't really make
** this structure opaque.
*/
struct Hash {
  char keyClass;          /* SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */
  char copyKey;           /* True if copy of key made on insert */
  int count;              /* Number of entries in this table */
  HashElem *first;        /* The first element of the array */
  int htsize;             /* Number of buckets in the hash table */
  struct _ht {            /* the hash table */
    int count;               /* Number of entries with this hash */
    HashElem *chain;         /* Pointer to first entry with this hash */
  } *ht;
};

/* Each element in the hash table is an instance of the following 
** structure.  All elements are stored on a single doubly-linked list.
**
** Again, this structure is intended to be opaque, but it can't really
** be opaque because it is used by macros.
*/
struct HashElem {
  HashElem *next, *prev;   /* Next and previous elements in the table */
  void *data;              /* Data associated with this element */
  void *pKey; int nKey;    /* Key associated with this element */
};

/*
** There are 4 different modes of operation for a hash table:
**
**   SQLITE_HASH_INT         nKey is used as the key and pKey is ignored.
**
**   SQLITE_HASH_POINTER     pKey is used as the key and nKey is ignored.
**
**   SQLITE_HASH_STRING      pKey points to a string that is nKey bytes long
**                           (including the null-terminator, if any).  Case
**                           is ignored in comparisons.
**
**   SQLITE_HASH_BINARY      pKey points to binary data nKey bytes long. 
**                           memcmp() is used to compare keys.
**
** A copy of the key is made for SQLITE_HASH_STRING and SQLITE_HASH_BINARY
** if the copyKey parameter to HashInit is 1.  
*/
/* #define SQLITE_HASH_INT       1 // NOT USED */
/* #define SQLITE_HASH_POINTER   2 // NOT USED */
#define SQLITE_HASH_STRING    3
#define SQLITE_HASH_BINARY    4

/*
** Access routines.  To delete, insert a NULL pointer.
*/
void sqlite3HashInit(Hash*, int keytype, int copyKey);
void *sqlite3HashInsert(Hash*, const void *pKey, int nKey, void *pData);
void *sqlite3HashFind(const Hash*, const void *pKey, int nKey);
void sqlite3HashClear(Hash*);

/*
** Macros for looping over all elements of a hash table.  The idiom is
** like this:
**
**   Hash h;
**   HashElem *p;
**   ...
**   for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){
**     SomeStructure *pData = sqliteHashData(p);
**     // do something with pData
**   }
*/
#define sqliteHashFirst(H)  ((H)->first)
#define sqliteHashNext(E)   ((E)->next)
#define sqliteHashData(E)   ((E)->data)
#define sqliteHashKey(E)    ((E)->pKey)
#define sqliteHashKeysize(E) ((E)->nKey)

/*
** Number of entries in a hash table
*/
#define sqliteHashCount(H)  ((H)->count)

#endif /* _SQLITE_HASH_H_ */
Added SQLite.Interop/src/insert.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
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
/*
** 2001 September 15
**
** 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 file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.1 2005/03/01 16:04:30 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
**
**  Character      Column affinity
**  ------------------------------
**  'n'            NUMERIC
**  'i'            INTEGER
**  't'            TEXT
**  'o'            NONE
*/
void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
  if( !pIdx->zColAff ){
    /* The first time a column affinity string for a particular index is
    ** required, it is allocated and populated here. It is then stored as
    ** a member of the Index structure for subsequent use.
    **
    ** The column affinity string will eventually be deleted by
    ** sqliteDeleteIndex() when the Index structure itself is cleaned
    ** up.
    */
    int n;
    Table *pTab = pIdx->pTable;
    pIdx->zColAff = (char *)sqliteMalloc(pIdx->nColumn+1);
    if( !pIdx->zColAff ){
      return;
    }
    for(n=0; n<pIdx->nColumn; n++){
      pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
    }
    pIdx->zColAff[pIdx->nColumn] = '\0';
  }
 
  sqlite3VdbeChangeP3(v, -1, pIdx->zColAff, 0);
}

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for table pTab. A column affinity string has one character
** for each column indexed by the index, according to the affinity of the
** column:
**
**  Character      Column affinity
**  ------------------------------
**  'n'            NUMERIC
**  'i'            INTEGER
**  't'            TEXT
**  'o'            NONE
*/
void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
  /* The first time a column affinity string for a particular table
  ** is required, it is allocated and populated here. It is then 
  ** stored as a member of the Table structure for subsequent use.
  **
  ** The column affinity string will eventually be deleted by
  ** sqlite3DeleteTable() when the Table structure itself is cleaned up.
  */
  if( !pTab->zColAff ){
    char *zColAff;
    int i;

    zColAff = (char *)sqliteMalloc(pTab->nCol+1);
    if( !zColAff ){
      return;
    }

    for(i=0; i<pTab->nCol; i++){
      zColAff[i] = pTab->aCol[i].affinity;
    }
    zColAff[pTab->nCol] = '\0';

    pTab->zColAff = zColAff;
  }

  sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0);
}

/*
** Return non-zero if SELECT statement p opens the table with rootpage
** iTab in database iDb.  This is used to see if a statement of the form 
** "INSERT INTO <iDb, iTab> SELECT ..." can run without using temporary
** table for the results of the SELECT. 
**
** No checking is done for sub-selects that are part of expressions.
*/
static int selectReadsTable(Select *p, int iDb, int iTab){
  int i;
  struct SrcList_item *pItem;
  if( p->pSrc==0 ) return 0;
  for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){
    if( pItem->pSelect ){
      if( selectReadsTable(p, iDb, iTab) ) return 1;
    }else{
      if( pItem->pTab->iDb==iDb && pItem->pTab->tnum==iTab ) return 1;
    }
  }
  return 0;
}

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)
**    insert into TABLE (IDLIST) select
**
** The IDLIST following the table name is always optional.  If omitted,
** then a list of all columns for the table is substituted.  The IDLIST
** appears in the pColumn parameter.  pColumn is NULL if IDLIST is omitted.
**
** The pList parameter holds EXPRLIST in the first form of the INSERT
** statement above, and pSelect is NULL.  For the second form, pList is
** NULL and pSelect is a pointer to the select statement used to generate
** data for the insert.
**
** The code generated follows one of three templates.  For a simple
** select with data coming from a VALUES clause, the code executes
** once straight down through.  The template looks like this:
**
**         open write cursor to <table> and its indices
**         puts VALUES clause expressions onto the stack
**         write the resulting record into <table>
**         cleanup
**
** If the statement is of the form
**
**   INSERT INTO <table> SELECT ...
**
** And the SELECT clause does not read from <table> at any time, then
** the generated code follows this template:
**
**         goto B
**      A: setup for the SELECT
**         loop over the tables in the SELECT
**           gosub C
**         end loop
**         cleanup after the SELECT
**         goto D
**      B: open write cursor to <table> and its indices
**         goto A
**      C: insert the select result into <table>
**         return
**      D: cleanup
**
** The third template is used if the insert statement takes its
** values from a SELECT but the data is being inserted into a table
** that is also read as part of the SELECT.  In the third form,
** we have to use a intermediate table to store the results of
** the select.  The template is like this:
**
**         goto B
**      A: setup for the SELECT
**         loop over the tables in the SELECT
**           gosub C
**         end loop
**         cleanup after the SELECT
**         goto D
**      C: insert the select result into the intermediate table
**         return
**      B: open a cursor to an intermediate table
**         goto A
**      D: open write cursor to <table> and its indices
**         loop over the intermediate table
**           transfer values form intermediate table into <table>
**         end the loop
**         cleanup
*/
void sqlite3Insert(
  Parse *pParse,        /* Parser context */
  SrcList *pTabList,    /* Name of table into which we are inserting */
  ExprList *pList,      /* List of values to be inserted */
  Select *pSelect,      /* A SELECT statement to use as the data source */
  IdList *pColumn,      /* Column names corresponding to IDLIST. */
  int onError           /* How to handle constraint errors */
){
  Table *pTab;          /* The table to insert into */
  char *zTab;           /* Name of the table into which we are inserting */
  const char *zDb;      /* Name of the database holding this table */
  int i, j, idx;        /* Loop counters */
  Vdbe *v;              /* Generate code into this virtual machine */
  Index *pIdx;          /* For looping over indices of the table */
  int nColumn;          /* Number of columns in the data */
  int base = 0;         /* VDBE Cursor number for pTab */
  int iCont=0,iBreak=0; /* Beginning and end of the loop over srcTab */
  sqlite3 *db;          /* The main database structure */
  int keyColumn = -1;   /* Column that is the INTEGER PRIMARY KEY */
  int endOfLoop;        /* Label for the end of the insertion loop */
  int useTempTable = 0; /* Store SELECT results in intermediate table */
  int srcTab = 0;       /* Data comes from this temporary cursor if >=0 */
  int iSelectLoop = 0;  /* Address of code that implements the SELECT */
  int iCleanup = 0;     /* Address of the cleanup code */
  int iInsertBlock = 0; /* Address of the subroutine used to insert data */
  int iCntMem = 0;      /* Memory cell used for the row counter */
  int newIdx = -1;      /* Cursor for the NEW table */
  Db *pDb;              /* The database containing table being inserted into */
  int counterMem = 0;   /* Memory cell holding AUTOINCREMENT counter */

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                 /* True if attempting to insert into a view */
  int triggers_exist = 0;     /* True if there are FOR EACH ROW triggers */
#endif

#ifndef SQLITE_OMIT_AUTOINCREMENT
  int counterRowid;     /* Memory cell holding rowid of autoinc counter */
#endif

  if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
  db = pParse->db;

  /* Locate the table into which we will be inserting new information.
  */
  assert( pTabList->nSrc==1 );
  zTab = pTabList->a[0].zName;
  if( zTab==0 ) goto insert_cleanup;
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ){
    goto insert_cleanup;
  }
  assert( pTab->iDb<db->nDb );
  pDb = &db->aDb[pTab->iDb];
  zDb = pDb->zName;
  if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
    goto insert_cleanup;
  }

  /* Figure out if we have any triggers and if the table being
  ** inserted into is a view
  */
#ifndef SQLITE_OMIT_TRIGGER
  triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0);
  isView = pTab->pSelect!=0;
#else
# define triggers_exist 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  /* Ensure that:
  *  (a) the table is not read-only, 
  *  (b) that if it is a view then ON INSERT triggers exist
  */
  if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
    goto insert_cleanup;
  }
  if( pTab==0 ) goto insert_cleanup;

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto insert_cleanup;
  }

  /* Ensure all required collation sequences are available. */
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
      goto insert_cleanup;
    }
  }

  /* Allocate a VDBE
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto insert_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, pTab->iDb);

  /* if there are row triggers, allocate a temp table for new.* references. */
  if( triggers_exist ){
    newIdx = pParse->nTab++;
  }

#ifndef SQLITE_OMIT_AUTOINCREMENT
  /* If this is an AUTOINCREMENT table, look up the sequence number in the
  ** sqlite_sequence table and store it in memory cell counterMem.  Also
  ** remember the rowid of the sqlite_sequence table entry in memory cell
  ** counterRowid.
  */
  if( pTab->autoInc ){
    int iCur = pParse->nTab;
    int base = sqlite3VdbeCurrentAddr(v);
    counterRowid = pParse->nMem++;
    counterMem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pDb->pSeqTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
    sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13);
    sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
    sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
    sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
    sqlite3VdbeAddOp(v, OP_Goto, 0, base+13);
    sqlite3VdbeAddOp(v, OP_Next, iCur, base+4);
    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
  }
#endif /* SQLITE_OMIT_AUTOINCREMENT */

  /* Figure out how many columns of data are supplied.  If the data
  ** is coming from a SELECT statement, then this step also generates
  ** all the code to implement the SELECT statement and invoke a subroutine
  ** to process each row of the result. (Template 2.) If the SELECT
  ** statement uses the the table that is being inserted into, then the
  ** subroutine is also coded here.  That subroutine stores the SELECT
  ** results in a temporary table. (Template 3.)
  */
  if( pSelect ){
    /* Data is coming from a SELECT.  Generate code to implement that SELECT
    */
    int rc, iInitCode;
    iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
    iSelectLoop = sqlite3VdbeCurrentAddr(v);
    iInsertBlock = sqlite3VdbeMakeLabel(v);

    /* Resolve the expressions in the SELECT statement and execute it. */
    rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
    if( rc || pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;

    iCleanup = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;

    /* Set useTempTable to TRUE if the result of the SELECT statement
    ** should be written into a temporary table.  Set to FALSE if each
    ** row of the SELECT can be written directly into the result table.
    **
    ** A temp table must be used if the table being updated is also one
    ** of the tables being read by the SELECT statement.  Also use a 
    ** temp table in the case of row triggers.
    */
    if( triggers_exist || selectReadsTable(pSelect, pTab->iDb, pTab->tnum) ){
      useTempTable = 1;
    }

    if( useTempTable ){
      /* Generate the subroutine that SELECT calls to process each row of
      ** the result.  Store the result in a temporary table
      */
      srcTab = pParse->nTab++;
      sqlite3VdbeResolveLabel(v, iInsertBlock);
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
      sqlite3TableAffinityStr(v, pTab);
      sqlite3VdbeAddOp(v, OP_NewRecno, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);

      /* The following code runs first because the GOTO at the very top
      ** of the program jumps to it.  Create the temporary table, then jump
      ** back up and execute the SELECT code above.
      */
      sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
      sqlite3VdbeAddOp(v, OP_OpenTemp, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn);
      sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
      sqlite3VdbeResolveLabel(v, iCleanup);
    }else{
      sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
    }
  }else{
    /* This is the case if the data for the INSERT is coming from a VALUES
    ** clause
    */
    NameContext sNC;
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    assert( pList!=0 );
    srcTab = -1;
    useTempTable = 0;
    assert( pList );
    nColumn = pList->nExpr;
    for(i=0; i<nColumn; i++){
      if( sqlite3ExprResolveNames(&sNC, pList->a[i].pExpr) ){
        goto insert_cleanup;
      }
    }
  }

  /* Make sure the number of columns in the source data matches the number
  ** of columns to be inserted into the table.
  */
  if( pColumn==0 && nColumn!=pTab->nCol ){
    sqlite3ErrorMsg(pParse, 
       "table %S has %d columns but %d values were supplied",
       pTabList, 0, pTab->nCol, nColumn);
    goto insert_cleanup;
  }
  if( pColumn!=0 && nColumn!=pColumn->nId ){
    sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
    goto insert_cleanup;
  }

  /* If the INSERT statement included an IDLIST term, then make sure
  ** all elements of the IDLIST really are columns of the table and 
  ** remember the column indices.
  **
  ** If the table has an INTEGER PRIMARY KEY column and that column
  ** is named in the IDLIST, then record in the keyColumn variable
  ** the index into IDLIST of the primary key column.  keyColumn is
  ** the index of the primary key as it appears in IDLIST, not as
  ** is appears in the original table.  (The index of the primary
  ** key in the original table is pTab->iPKey.)
  */
  if( pColumn ){
    for(i=0; i<pColumn->nId; i++){
      pColumn->a[i].idx = -1;
    }
    for(i=0; i<pColumn->nId; i++){
      for(j=0; j<pTab->nCol; j++){
        if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
          pColumn->a[i].idx = j;
          if( j==pTab->iPKey ){
            keyColumn = i;
          }
          break;
        }
      }
      if( j>=pTab->nCol ){
        if( sqlite3IsRowid(pColumn->a[i].zName) ){
          keyColumn = i;
        }else{
          sqlite3ErrorMsg(pParse, "table %S has no column named %s",
              pTabList, 0, pColumn->a[i].zName);
          pParse->nErr++;
          goto insert_cleanup;
        }
      }
    }
  }

  /* If there is no IDLIST term but the table has an integer primary
  ** key, the set the keyColumn variable to the primary key column index
  ** in the original table definition.
  */
  if( pColumn==0 ){
    keyColumn = pTab->iPKey;
  }

  /* Open the temp table for FOR EACH ROW triggers
  */
  if( triggers_exist ){
    sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
  }
    
  /* Initialize the count of rows to be inserted
  */
  if( db->flags & SQLITE_CountRows ){
    iCntMem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iCntMem, 1);
  }

  /* Open tables and indices if there are no row triggers */
  if( !triggers_exist ){
    base = pParse->nTab;
    sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
  }

  /* If the data source is a temporary table, then we have to create
  ** a loop because there might be multiple rows of data.  If the data
  ** source is a subroutine call from the SELECT statement, then we need
  ** to launch the SELECT statement processing.
  */
  if( useTempTable ){
    iBreak = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_Rewind, srcTab, iBreak);
    iCont = sqlite3VdbeCurrentAddr(v);
  }else if( pSelect ){
    sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
    sqlite3VdbeResolveLabel(v, iInsertBlock);
  }

  /* Run the BEFORE and INSTEAD OF triggers, if there are any
  */
  endOfLoop = sqlite3VdbeMakeLabel(v);
  if( triggers_exist & TRIGGER_BEFORE ){

    /* build the NEW.* reference row.  Note that if there is an INTEGER
    ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
    ** translated into a unique ID for the row.  But on a BEFORE trigger,
    ** we do not know what the unique ID will be (because the insert has
    ** not happened yet) so we substitute a rowid of -1
    */
    if( keyColumn<0 ){
      sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
    }else if( useTempTable ){
      sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
    }else{
      assert( pSelect==0 );  /* Otherwise useTempTable is true */
      sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    }

    /* Create the new column data
    */
    for(i=0; i<pTab->nCol; i++){
      if( pColumn==0 ){
        j = i;
      }else{
        for(j=0; j<pColumn->nId; j++){
          if( pColumn->a[j].idx==i ) break;
        }
      }
      if( pColumn && j>=pColumn->nId ){
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
      }else if( useTempTable ){
        sqlite3VdbeAddOp(v, OP_Column, srcTab, j); 
      }else{
        assert( pSelect==0 ); /* Otherwise useTempTable is true */
        sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr);
      }
    }
    sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);

    /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
    ** do not attempt any conversions before assembling the record.
    ** If this is a real table, attempt conversions as required by the
    ** table column affinities.
    */
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);

    /* Fire BEFORE or INSTEAD OF triggers */
    if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, 
        newIdx, -1, onError, endOfLoop) ){
      goto insert_cleanup;
    }
  }

  /* If any triggers exists, the opening of tables and indices is deferred
  ** until now.
  */
  if( triggers_exist && !isView ){
    base = pParse->nTab;
    sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
  }

  /* Push the record number for the new entry onto the stack.  The
  ** record number is a randomly generate integer created by NewRecno
  ** except when the table has an INTEGER PRIMARY KEY column, in which
  ** case the record number is the same as that column. 
  */
  if( !isView ){
    if( keyColumn>=0 ){
      if( useTempTable ){
        sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
      }else if( pSelect ){
        sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
      }else{
        sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
      }
      /* If the PRIMARY KEY expression is NULL, then use OP_NewRecno
      ** to generate a unique primary key value.
      */
      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    }else{
      sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
    }
#ifndef SQLITE_OMIT_AUTOINCREMENT
    if( pTab->autoInc ){
      sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0);
    }
#endif /* SQLITE_OMIT_AUTOINCREMENT */

    /* Push onto the stack, data for all columns of the new entry, beginning
    ** with the first column.
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        /* The value of the INTEGER PRIMARY KEY column is always a NULL.
        ** Whenever this column is read, the record number will be substituted
        ** in its place.  So will fill this column with a NULL to avoid
        ** taking up data space with information that will never be used. */
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        continue;
      }
      if( pColumn==0 ){
        j = i;
      }else{
        for(j=0; j<pColumn->nId; j++){
          if( pColumn->a[j].idx==i ) break;
        }
      }
      if( pColumn && j>=pColumn->nId ){
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
      }else if( useTempTable ){
        sqlite3VdbeAddOp(v, OP_Column, srcTab, j); 
      }else if( pSelect ){
        sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
      }else{
        sqlite3ExprCode(pParse, pList->a[j].pExpr);
      }
    }

    /* Generate code to check constraints and generate index keys and
    ** do the insertion.
    */
    sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
                                   0, onError, endOfLoop);
    sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
                            (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1);
  }

  /* Update the count of rows that are inserted
  */
  if( (db->flags & SQLITE_CountRows)!=0 ){
    sqlite3VdbeAddOp(v, OP_MemIncr, iCntMem, 0);
  }

  if( triggers_exist ){
    /* Close all tables opened */
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Close, base, 0);
      for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
        sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
      }
    }

    /* Code AFTER triggers */
    if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_AFTER, pTab,
          newIdx, -1, onError, endOfLoop) ){
      goto insert_cleanup;
    }
  }

  /* The bottom of the loop, if the data source is a SELECT statement
  */
  sqlite3VdbeResolveLabel(v, endOfLoop);
  if( useTempTable ){
    sqlite3VdbeAddOp(v, OP_Next, srcTab, iCont);
    sqlite3VdbeResolveLabel(v, iBreak);
    sqlite3VdbeAddOp(v, OP_Close, srcTab, 0);
  }else if( pSelect ){
    sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
    sqlite3VdbeAddOp(v, OP_Return, 0, 0);
    sqlite3VdbeResolveLabel(v, iCleanup);
  }

  if( !triggers_exist ){
    /* Close all tables opened */
    sqlite3VdbeAddOp(v, OP_Close, base, 0);
    for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
      sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
    }
  }

#ifndef SQLITE_OMIT_AUTOINCREMENT
  /* Update the sqlite_sequence table by storing the content of the
  ** counter value in memory counterMem back into the sqlite_sequence
  ** table.
  */
  if( pTab->autoInc ){
    int iCur = pParse->nTab;
    int base = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pDb->pSeqTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
    sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
    sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp(v, OP_NewRecno, iCur, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
    sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0);
    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
  }
#endif

  /*
  ** Return the number of rows inserted. If this routine is 
  ** generating code because of a call to sqlite3NestedParse(), do not
  ** invoke the callback function.
  */
  if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
    sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
  }

insert_cleanup:
  sqlite3SrcListDelete(pTabList);
  if( pList ) sqlite3ExprListDelete(pList);
  if( pSelect ) sqlite3SelectDelete(pSelect);
  sqlite3IdListDelete(pColumn);
}

/*
** Generate code to do a constraint check prior to an INSERT or an UPDATE.
**
** When this routine is called, the stack contains (from bottom to top)
** the following values:
**
**    1.  The recno of the row to be updated before the update.  This
**        value is omitted unless we are doing an UPDATE that involves a
**        change to the record number.
**
**    2.  The recno of the row after the update.
**
**    3.  The data in the first column of the entry after the update.
**
**    i.  Data from middle columns...
**
**    N.  The data in the last column of the entry after the update.
**
** The old recno shown as entry (1) above is omitted unless both isUpdate
** and recnoChng are 1.  isUpdate is true for UPDATEs and false for
** INSERTs and recnoChng is true if the record number is being changed.
**
** The code generated by this routine pushes additional entries onto
** the stack which are the keys for new index entries for the new record.
** The order of index keys is the same as the order of the indices on
** the pTable->pIndex list.  A key is only created for index i if 
** aIdxUsed!=0 and aIdxUsed[i]!=0.
**
** This routine also generates code to check constraints.  NOT NULL,
** CHECK, and UNIQUE constraints are all checked.  If a constraint fails,
** then the appropriate action is performed.  There are five possible
** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
**
**  Constraint type  Action       What Happens
**  ---------------  ----------   ----------------------------------------
**  any              ROLLBACK     The current transaction is rolled back and
**                                sqlite3_exec() returns immediately with a
**                                return code of SQLITE_CONSTRAINT.
**
**  any              ABORT        Back out changes from the current command
**                                only (do not do a complete rollback) then
**                                cause sqlite3_exec() to return immediately
**                                with SQLITE_CONSTRAINT.
**
**  any              FAIL         Sqlite_exec() returns immediately with a
**                                return code of SQLITE_CONSTRAINT.  The
**                                transaction is not rolled back and any
**                                prior changes are retained.
**
**  any              IGNORE       The record number and data is popped from
**                                the stack and there is an immediate jump
**                                to label ignoreDest.
**
**  NOT NULL         REPLACE      The NULL value is replace by the default
**                                value for that column.  If the default value
**                                is NULL, the action is the same as ABORT.
**
**  UNIQUE           REPLACE      The other row that conflicts with the row
**                                being inserted is removed.
**
**  CHECK            REPLACE      Illegal.  The results in an exception.
**
** Which action to take is determined by the overrideError parameter.
** Or if overrideError==OE_Default, then the pParse->onError parameter
** is used.  Or if pParse->onError==OE_Default then the onError value
** for the constraint is used.
**
** The calling routine must open a read/write cursor for pTab with
** cursor number "base".  All indices of pTab must also have open
** read/write cursors with cursor number base+i for the i-th cursor.
** Except, if there is no possibility of a REPLACE action then
** cursors do not need to be open for indices where aIdxUsed[i]==0.
**
** If the isUpdate flag is true, it means that the "base" cursor is
** initially pointing to an entry that is being updated.  The isUpdate
** flag causes extra code to be generated so that the "base" cursor
** is still pointing at the same entry after the routine returns.
** Without the isUpdate flag, the "base" cursor might be moved.
*/
void sqlite3GenerateConstraintChecks(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int base,           /* Index of a read/write cursor pointing at pTab */
  char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
  int recnoChng,      /* True if the record number will change */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int overrideError,  /* Override onError to this if not OE_Default */
  int ignoreDest      /* Jump to this label on an OE_Ignore resolution */
){
  int i;
  Vdbe *v;
  int nCol;
  int onError;
  int addr;
  int extra;
  int iCur;
  Index *pIdx;
  int seenReplace = 0;
  int jumpInst1=0, jumpInst2;
  int contAddr;
  int hasTwoRecnos = (isUpdate && recnoChng);

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;

  /* Test all NOT NULL constraints.
  */
  for(i=0; i<nCol; i++){
    if( i==pTab->iPKey ){
      continue;
    }
    onError = pTab->aCol[i].notNull;
    if( onError==OE_None ) continue;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
      onError = OE_Abort;
    }
    sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1);
    addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0);
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
    switch( onError ){
      case OE_Rollback:
      case OE_Abort:
      case OE_Fail: {
        char *zMsg = 0;
        sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
        sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
                        " may not be NULL", (char*)0);
        sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
        break;
      }
      case OE_Ignore: {
        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
      case OE_Replace: {
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
        sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0);
        break;
      }
    }
    sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
  }

  /* Test all CHECK constraints
  */
  /**** TBD ****/

  /* If we have an INTEGER PRIMARY KEY, make sure the primary key
  ** of the new record does not previously exist.  Except, if this
  ** is an UPDATE and the primary key is not changing, that is OK.
  */
  if( recnoChng ){
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    
    if( isUpdate ){
      sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
      sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
      jumpInst1 = sqlite3VdbeAddOp(v, OP_Eq, 0, 0);
    }
    sqlite3VdbeAddOp(v, OP_Dup, nCol, 1);
    jumpInst2 = sqlite3VdbeAddOp(v, OP_NotExists, base, 0);
    switch( onError ){
      default: {
        onError = OE_Abort;
        /* Fall thru into the next case */
      }
      case OE_Rollback:
      case OE_Abort:
      case OE_Fail: {
        sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
                         "PRIMARY KEY must be unique", P3_STATIC);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
          sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
        }
        seenReplace = 1;
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
    }
    contAddr = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
    if( isUpdate ){
      sqlite3VdbeChangeP2(v, jumpInst1, contAddr);
      sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
      sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  extra = -1;
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
    if( aIdxUsed && aIdxUsed[iCur]==0 ) continue;  /* Skip unused indices */
    extra++;

    /* Create a key for accessing the index entry */
    sqlite3VdbeAddOp(v, OP_Dup, nCol+extra, 1);
    for(i=0; i<pIdx->nColumn; i++){
      int idx = pIdx->aiColumn[i];
      if( idx==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
      }else{
        sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
      }
    }
    jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
    sqlite3IndexAffinityStr(v, pIdx);

    /* Find out what action to take in case there is an indexing conflict */
    onError = pIdx->onError;
    if( onError==OE_None ) continue;  /* pIdx is not a UNIQUE index */
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( seenReplace ){
      if( onError==OE_Ignore ) onError = OE_Replace;
      else if( onError==OE_Fail ) onError = OE_Abort;
    }
    

    /* Check to see if the new index entry will be unique */
    sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
    jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);

    /* Generate code that executes if the new index entry is not unique */
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
    switch( onError ){
      case OE_Rollback:
      case OE_Abort:
      case OE_Fail: {
        int j, n1, n2;
        char zErrMsg[200];
        strcpy(zErrMsg, pIdx->nColumn>1 ? "columns " : "column ");
        n1 = strlen(zErrMsg);
        for(j=0; j<pIdx->nColumn && n1<sizeof(zErrMsg)-30; j++){
          char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
          n2 = strlen(zCol);
          if( j>0 ){
            strcpy(&zErrMsg[n1], ", ");
            n1 += 2;
          }
          if( n1+n2>sizeof(zErrMsg)-30 ){
            strcpy(&zErrMsg[n1], "...");
            n1 += 3;
            break;
          }else{
            strcpy(&zErrMsg[n1], zCol);
            n1 += n2;
          }
        }
        strcpy(&zErrMsg[n1], 
            pIdx->nColumn>1 ? " are not unique" : " is not unique");
        sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
          sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
        }
        seenReplace = 1;
        break;
      }
    }
    contAddr = sqlite3VdbeCurrentAddr(v);
    assert( contAddr<(1<<24) );
#if NULL_DISTINCT_FOR_UNIQUE
    sqlite3VdbeChangeP2(v, jumpInst1, contAddr | (1<<24));
#endif
    sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
  }
}

/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
** The stack must contain keys for all active indices followed by data
** and the recno for the new entry.  This routine creates the new
** entries in all indices and in the main table.
**
** The arguments to this routine should be the same as the first six
** arguments to sqlite3GenerateConstraintChecks.
*/
void sqlite3CompleteInsertion(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int base,           /* Index of a read/write cursor pointing at pTab */
  char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
  int recnoChng,      /* True if the record number will change */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int newIdx          /* Index of NEW table for triggers.  -1 if none */
){
  int i;
  Vdbe *v;
  int nIdx;
  Index *pIdx;
  int pik_flags;

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  for(i=nIdx-1; i>=0; i--){
    if( aIdxUsed && aIdxUsed[i]==0 ) continue;
    sqlite3VdbeAddOp(v, OP_IdxPut, base+i+1, 0);
  }
  sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
  sqlite3TableAffinityStr(v, pTab);
#ifndef SQLITE_OMIT_TRIGGER
  if( newIdx>=0 ){
    sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
  }
#endif
  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
  }
  sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags);
  
  if( isUpdate && recnoChng ){
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  }
}

/*
** Generate code that will open cursors for a table and for all
** indices of that table.  The "base" parameter is the cursor number used
** for the table.  Indices are opened on subsequent cursors.
*/
void sqlite3OpenTableAndIndices(
  Parse *pParse,   /* Parsing context */
  Table *pTab,     /* Table to be opened */
  int base,        /* Cursor number assigned to the table */
  int op           /* OP_OpenRead or OP_OpenWrite */
){
  int i;
  Index *pIdx;
  Vdbe *v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, op, base, pTab->tnum);
  VdbeComment((v, "# %s", pTab->zName));
  sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, op, i+base, pIdx->tnum,
                   (char*)&pIdx->keyInfo, P3_KEYINFO);
  }
  if( pParse->nTab<=base+i ){
    pParse->nTab = base+i;
  }
}
Added SQLite.Interop/src/keywordhash.h.






























































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* Hash score: 148 */
static int keywordCode(const char *z, int n){
  static const char zText[504] =
    "ABORTABLEFTEMPORARYAFTERAISELECTHENDATABASEACHECKEYALTEREFERENCES"
    "CAPELSEXCEPTRANSACTIONATURALIKEXCLUSIVEXISTSTATEMENTRIGGEREINDEX"
    "PLAINITIALLYANDEFAULTATTACHAVINGLOBEFOREIGNORENAMEAUTOINCREMENT"
    "BEGINNEREPLACEBETWEENOTNULLIMITBYCASCADEFERRABLECASECOLLATECOMMIT"
    "CONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATECURRENT_TIMESTAMP"
    "RAGMATCHDEFERREDELETEDESCDETACHDISTINCTDROPRIMARYFAILFROMFULL"
    "GROUPDATEIMMEDIATEINSERTINSTEADINTOFFSETISNULLJOINORDERESTRICT"
    "OUTERIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEWHERE";
  static const unsigned char aHash[127] = {
      87,  78,  99,  86,   0,   4,   0,   0, 106,   0,  72,   0,   0,
      90,  43,   0,  88,   0,  98, 101,  92,   0,   0,   9,   0,   0,
     105,   0, 102,  96,   0,  10,  46,   0,  40,   0,   0,  61,  66,
       0,  60,  14,   0,   0,  35,  80,   0, 100,  69,   0,   0,  26,
       0,  73,  59,   0,  12,   0, 107,  37,  11,   0,  75,  39,  20,
       0,   0,   0,  34,  79,  51,  33,  48,  15,  84,   0,  36,   0,
      70,  21,   0,  67,   0,   0,   0,   0,  45,  62,  17,  83,  32,
      64,  82,   0,   1,   0,  13,  50,  56,   8,   0, 104,  71,  94,
      52,   6,  55,   0,   0,  47,  89,   0,  97,   0,  65,   0,   0,
      23,   0, 108,  49,  54,   0,   2,  53,   0, 103,
  };
  static const unsigned char aNext[108] = {
       0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,  18,   5,
       0,   0,   0,   0,   0,   0,   0,   0,   0,  27,   0,   0,   0,
       0,   0,   0,   0,   0,  42,   0,   0,   0,   0,   0,   0,   0,
      24,   0,   0,  44,   0,   0,   0,  30,  57,   0,   0,   0,   0,
       0,   0,   0,  68,  41,   0,   0,   0,   0,  19,  58,  16,   0,
      77,   0,  63,   0,  81,  31,   0,   0,   0,   0,   0,   0,   0,
      38,  91,  93,   0,   0,  95,  22,  29,  76,   0,  25,  85,   0,
      28,   0,  74,   0,
  };
  static const unsigned char aLen[108] = {
       5,   5,   4,   4,   9,   2,   5,   5,   6,   4,   3,   8,   2,
       4,   5,   3,   5,  10,   6,   4,   6,  11,   2,   7,   4,   9,
       6,   9,   7,   7,   5,   7,   9,   3,   3,   7,   6,   6,   4,
       6,   3,   7,   6,   6,  13,   2,   2,   5,   5,   7,   7,   3,
       7,   4,   5,   2,   7,   3,  10,   4,   7,   6,   8,  10,   9,
       6,   5,  12,  12,  17,   6,   5,   8,   6,   4,   6,   8,   2,
       4,   7,   4,   4,   4,   5,   6,   9,   6,   7,   4,   2,   6,
       3,   6,   4,   5,   8,   5,   5,   8,   3,   4,   5,   6,   5,
       6,   6,   4,   5,
  };
  static const unsigned short int aOffset[108] = {
       0,   4,   7,  10,  10,  14,  19,  23,  26,  31,  33,  35,  40,
      42,  44,  48,  51,  55,  63,  68,  71,  76,  85,  86,  92,  95,
     103, 108, 116, 122, 124, 127, 132, 137, 141, 143, 150, 155, 160,
     163, 165, 165, 169, 173, 179, 181, 183, 192, 195, 199, 206, 212,
     212, 215, 218, 223, 225, 226, 230, 240, 244, 251, 257, 265, 272,
     281, 287, 292, 304, 304, 320, 324, 329, 336, 342, 346, 352, 353,
     360, 363, 370, 374, 378, 382, 385, 391, 400, 406, 413, 416, 416,
     419, 422, 428, 432, 436, 444, 448, 453, 461, 463, 467, 472, 478,
     483, 489, 495, 498,
  };
  static const unsigned char aCode[108] = {
    TK_ABORT,      TK_TABLE,      TK_JOIN_KW,    TK_TEMP,       TK_TEMP,       
    TK_OR,         TK_AFTER,      TK_RAISE,      TK_SELECT,     TK_THEN,       
    TK_END,        TK_DATABASE,   TK_AS,         TK_EACH,       TK_CHECK,      
    TK_KEY,        TK_ALTER,      TK_REFERENCES, TK_ESCAPE,     TK_ELSE,       
    TK_EXCEPT,     TK_TRANSACTION,TK_ON,         TK_JOIN_KW,    TK_LIKE,       
    TK_EXCLUSIVE,  TK_EXISTS,     TK_STATEMENT,  TK_TRIGGER,    TK_REINDEX,    
    TK_INDEX,      TK_EXPLAIN,    TK_INITIALLY,  TK_ALL,        TK_AND,        
    TK_DEFAULT,    TK_ATTACH,     TK_HAVING,     TK_GLOB,       TK_BEFORE,     
    TK_FOR,        TK_FOREIGN,    TK_IGNORE,     TK_RENAME,     TK_AUTOINCR,   
    TK_TO,         TK_IN,         TK_BEGIN,      TK_JOIN_KW,    TK_REPLACE,    
    TK_BETWEEN,    TK_NOT,        TK_NOTNULL,    TK_NULL,       TK_LIMIT,      
    TK_BY,         TK_CASCADE,    TK_ASC,        TK_DEFERRABLE, TK_CASE,       
    TK_COLLATE,    TK_COMMIT,     TK_CONFLICT,   TK_CONSTRAINT, TK_INTERSECT,  
    TK_CREATE,     TK_JOIN_KW,    TK_CDATE,      TK_CTIME,      TK_CTIMESTAMP, 
    TK_PRAGMA,     TK_MATCH,      TK_DEFERRED,   TK_DELETE,     TK_DESC,       
    TK_DETACH,     TK_DISTINCT,   TK_IS,         TK_DROP,       TK_PRIMARY,    
    TK_FAIL,       TK_FROM,       TK_JOIN_KW,    TK_GROUP,      TK_UPDATE,     
    TK_IMMEDIATE,  TK_INSERT,     TK_INSTEAD,    TK_INTO,       TK_OF,         
    TK_OFFSET,     TK_SET,        TK_ISNULL,     TK_JOIN,       TK_ORDER,      
    TK_RESTRICT,   TK_JOIN_KW,    TK_JOIN_KW,    TK_ROLLBACK,   TK_ROW,        
    TK_WHEN,       TK_UNION,      TK_UNIQUE,     TK_USING,      TK_VACUUM,     
    TK_VALUES,     TK_VIEW,       TK_WHERE,      
  };
  int h, i;
  if( n<2 ) return TK_ID;
  h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^
      (sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^
      n) % 127;
  for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
    if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
      return aCode[i];
    }
  }
  return TK_ID;
}
int sqlite3KeywordCode(const char *z, int n){
  return keywordCode(z, n);
}
Added SQLite.Interop/src/legacy.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
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.1 2005/03/01 16:04:30 rmsimpson Exp $
*/

#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** Execute SQL code.  Return one of the SQLITE_ success/failure
** codes.  Also write an error message into memory obtained from
** malloc() and make *pzErrMsg point to that message.
**
** If the SQL is a query, then for each row in the query result
** the xCallback() function is called.  pArg becomes the first
** argument to xCallback().  If xCallback=NULL then no callback
** is invoked, even for queries.
*/
int sqlite3_exec(
  sqlite3 *db,                /* The database on which the SQL executes */
  const char *zSql,           /* The SQL to be executed */
  sqlite3_callback xCallback, /* Invoke this callback routine */
  void *pArg,                 /* First argument to xCallback() */
  char **pzErrMsg             /* Write error messages here */
){
  int rc = SQLITE_OK;
  const char *zLeftover;
  sqlite3_stmt *pStmt = 0;
  char **azCols = 0;

  int nRetry = 0;
  int nChange = 0;
  int nCallback;

  if( zSql==0 ) return SQLITE_OK;
  while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
    int nCol;
    char **azVals = 0;

    pStmt = 0;
    rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
    if( rc!=SQLITE_OK ){
      if( pStmt ) sqlite3_finalize(pStmt);
      continue;
    }
    if( !pStmt ){
      /* this happens for a comment or white-space */
      zSql = zLeftover;
      continue;
    }

    db->nChange += nChange;
    nCallback = 0;

    nCol = sqlite3_column_count(pStmt);
    azCols = sqliteMalloc(2*nCol*sizeof(const char *));
    if( nCol && !azCols ){
      rc = SQLITE_NOMEM;
      goto exec_out;
    }

    while( 1 ){
      int i;
      rc = sqlite3_step(pStmt);

      /* Invoke the callback function if required */
      if( xCallback && (SQLITE_ROW==rc || 
          (SQLITE_DONE==rc && !nCallback && db->flags&SQLITE_NullCallback)) ){
        if( 0==nCallback ){
          for(i=0; i<nCol; i++){
            azCols[i] = (char *)sqlite3_column_name(pStmt, i);
          }
          nCallback++;
        }
        if( rc==SQLITE_ROW ){
          azVals = &azCols[nCol];
          for(i=0; i<nCol; i++){
            azVals[i] = (char *)sqlite3_column_text(pStmt, i);
          }
        }
        if( xCallback(pArg, nCol, azVals, azCols) ){
          rc = SQLITE_ABORT;
          goto exec_out;
        }
      }

      if( rc!=SQLITE_ROW ){
        rc = sqlite3_finalize(pStmt);
        pStmt = 0;
        if( db->pVdbe==0 ){
          nChange = db->nChange;
        }
        if( rc!=SQLITE_SCHEMA ){
          nRetry = 0;
          zSql = zLeftover;
          while( isspace((unsigned char)zSql[0]) ) zSql++;
        }
        break;
      }
    }

    sqliteFree(azCols);
    azCols = 0;
  }

exec_out:
  if( pStmt ) sqlite3_finalize(pStmt);
  if( azCols ) sqliteFree(azCols);

  if( sqlite3_malloc_failed ){
    rc = SQLITE_NOMEM;
  }
  if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
    *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
    if( *pzErrMsg ){
      strcpy(*pzErrMsg, sqlite3_errmsg(db));
    }
  }else if( pzErrMsg ){
    *pzErrMsg = 0;
  }

  return rc;
}
Added SQLite.Interop/src/main.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
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
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.1 2005/03/01 16:04:30 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
** SQLITE_LITTLEENDIAN macros.
*/
const int sqlite3one = 1;

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(InitData *pData, const char *zExtra){
  if( !sqlite3_malloc_failed ){
    sqlite3SetString(pData->pzErrMsg, "malformed database schema",
       zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
  }
}

/*
** This is the callback routine for the code that initializes the
** database.  See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**
** Each callback contains the following information:
**
**     argv[0] = name of thing being created
**     argv[1] = root page number for table or index.  NULL for trigger or view.
**     argv[2] = SQL text for the CREATE statement.
**     argv[3] = "1" for temporary files, "0" for main database, "2" or more
**               for auxiliary database files.
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb;

  assert( argc==4 );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[1]==0 || argv[3]==0 ){
    corruptSchema(pData, 0);
    return 1;
  }
  iDb = atoi(argv[3]);
  assert( iDb>=0 && iDb<db->nDb );
  if( argv[2] && argv[2][0] ){
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    */
    char *zErr;
    int rc;
    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
    db->init.iDb = 0;
    if( SQLITE_OK!=rc ){
      corruptSchema(pData, zErr);
      sqlite3_free(zErr);
      return rc;
    }
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */
    Index *pIndex;
    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
    if( pIndex==0 || pIndex->tnum!=0 ){
      /* This can occur if there exists an index on a TEMP table which
      ** has the same name as another index on a permanent index.  Since
      ** the permanent table is hidden by the TEMP table, we can also
      ** safely ignore the index on the permanent table.
      */
      /* Do Nothing */;
    }else{
      pIndex->tnum = atoi(argv[1]);
    }
  }
  return 0;
}

/*
** Attempt to read the database schema and initialize internal
** data structures for a single database file.  The index of the
** database file is given by iDb.  iDb==0 is used for the main
** database.  iDb==1 should never be used.  iDb>=2 is used for
** auxiliary databases.  Return one of the SQLITE_ error codes to
** indicate success or failure.
*/
static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
  int rc;
  BtCursor *curMain;
  int size;
  Table *pTab;
  char const *azArg[5];
  char zDbNum[30];
  int meta[10];
  InitData initData;
  char const *zMasterSchema;
  char const *zMasterName;

  /*
  ** The master database table has a structure like this
  */
  static const char master_schema[] = 
     "CREATE TABLE sqlite_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"
  ;
  static const char temp_master_schema[] = 
     "CREATE TEMP TABLE sqlite_temp_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"
  ;

  assert( iDb>=0 && iDb<db->nDb );

  /* zMasterSchema and zInitScript are set to point at the master schema
  ** and initialisation script appropriate for the database being
  ** initialised. zMasterName is the name of the master table.
  */
  if( iDb==1 ){
    zMasterSchema = temp_master_schema;
    zMasterName = TEMP_MASTER_NAME;
  }else{
    zMasterSchema = master_schema;
    zMasterName = MASTER_NAME;
  }

  /* Construct the schema tables.  */
  sqlite3SafetyOff(db);
  azArg[0] = zMasterName;
  azArg[1] = "1";
  azArg[2] = zMasterSchema;
  sprintf(zDbNum, "%d", iDb);
  azArg[3] = zDbNum;
  azArg[4] = 0;
  initData.db = db;
  initData.pzErrMsg = pzErrMsg;
  rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0);
  if( rc!=SQLITE_OK ){
    sqlite3SafetyOn(db);
    return rc;
  }
  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( pTab ){
    pTab->readOnly = 1;
  }
  sqlite3SafetyOn(db);

  /* Create a cursor to hold the database open
  */
  if( db->aDb[iDb].pBt==0 ){
    if( iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded);
    return SQLITE_OK;
  }
  rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
  if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
    sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
    return rc;
  }

  /* Get the database meta information.
  **
  ** Meta values are as follows:
  **    meta[0]   Schema cookie.  Changes with each schema change.
  **    meta[1]   File format of schema layer.
  **    meta[2]   Size of the page cache.
  **    meta[3]   Use freelist if 0.  Autovacuum if greater than zero.
  **    meta[4]   Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE
  **    meta[5]   The user cookie. Used by the application.
  **    meta[6]   
  **    meta[7]
  **    meta[8]
  **    meta[9]
  **
  ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to
  ** the possible values of meta[4].
  */
  if( rc==SQLITE_OK ){
    int i;
    for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, (u32 *)&meta[i]);
    }
    if( rc ){
      sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
      sqlite3BtreeCloseCursor(curMain);
      return rc;
    }
  }else{
    memset(meta, 0, sizeof(meta));
  }
  db->aDb[iDb].schema_cookie = meta[0];

  /* If opening a non-empty database, check the text encoding. For the
  ** main database, set sqlite3.enc to the encoding of the main database.
  ** For an attached db, it is an error if the encoding is not the same
  ** as sqlite3.enc.
  */
  if( meta[4] ){  /* text encoding */
    if( iDb==0 ){
      /* If opening the main database, set db->enc. */
      db->enc = (u8)meta[4];
      db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0);
    }else{
      /* If opening an attached database, the encoding much match db->enc */
      if( meta[4]!=db->enc ){
        sqlite3BtreeCloseCursor(curMain);
        sqlite3SetString(pzErrMsg, "attached databases must use the same"
            " text encoding as main database", (char*)0);
        return SQLITE_ERROR;
      }
    }
  }

  size = meta[2];
  if( size==0 ){ size = MAX_PAGES; }
  db->aDb[iDb].cache_size = size;

  if( iDb==0 ){
    db->file_format = meta[1];
    if( db->file_format==0 ){
      /* This happens if the database was initially empty */
      db->file_format = 1;
    }

    if( db->file_format==2 ){
      /* File format 2 is treated exactly as file format 1. New 
      ** databases are created with file format 1.
      */ 
      db->file_format = 1;
    }
  }

  /*
  ** file_format==1    Version 3.0.0.
  ** file_format==2    Version 3.1.3.
  **
  ** Version 3.0 can only use files with file_format==1. Version 3.1.3
  ** can read and write files with file_format==1 or file_format==2.
  */
  if( meta[1]>2 ){
    sqlite3BtreeCloseCursor(curMain);
    sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
    return SQLITE_ERROR;
  }

  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);

  /* Read the schema information out of the schema tables
  */
  assert( db->init.busy );
  if( rc==SQLITE_EMPTY ){
    /* For an empty database, there is nothing to read */
    rc = SQLITE_OK;
  }else{
    char *zSql;
    zSql = sqlite3MPrintf(
        "SELECT name, rootpage, sql, '%s' FROM '%q'.%s",
        zDbNum, db->aDb[iDb].zName, zMasterName);
    sqlite3SafetyOff(db);
    rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
    sqlite3SafetyOn(db);
    sqliteFree(zSql);
    sqlite3BtreeCloseCursor(curMain);
  }
  if( sqlite3_malloc_failed ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    rc = SQLITE_NOMEM;
    sqlite3ResetInternalSchema(db, 0);
  }
  if( rc==SQLITE_OK ){
    DbSetProperty(db, iDb, DB_SchemaLoaded);
  }else{
    sqlite3ResetInternalSchema(db, iDb);
  }
  return rc;
}

/*
** Initialize all database files - the main database file, the file
** used to store temporary tables, and any additional database files
** created using ATTACH statements.  Return a success code.  If an
** error occurs, write an error message into *pzErrMsg.
**
** After the database is initialized, the SQLITE_Initialized
** bit is set in the flags field of the sqlite structure. 
*/
int sqlite3Init(sqlite3 *db, char **pzErrMsg){
  int i, rc;
  
  if( db->init.busy ) return SQLITE_OK;
  assert( (db->flags & SQLITE_Initialized)==0 );
  rc = SQLITE_OK;
  db->init.busy = 1;
  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
    rc = sqlite3InitOne(db, i, pzErrMsg);
    if( rc ){
      sqlite3ResetInternalSchema(db, i);
    }
  }

  /* Once all the other databases have been initialised, load the schema
  ** for the TEMP database. This is loaded last, as the TEMP database
  ** schema may contain references to objects in other databases.
  */
  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
    rc = sqlite3InitOne(db, 1, pzErrMsg);
    if( rc ){
      sqlite3ResetInternalSchema(db, 1);
    }
  }

  db->init.busy = 0;
  if( rc==SQLITE_OK ){
    db->flags |= SQLITE_Initialized;
    sqlite3CommitInternalChanges(db);
  }

  if( rc!=SQLITE_OK ){
    db->flags &= ~SQLITE_Initialized;
  }
  return rc;
}

/*
** This routine is a no-op if the database schema is already initialised.
** Otherwise, the schema is loaded. An error code is returned.
*/
int sqlite3ReadSchema(Parse *pParse){
  int rc = SQLITE_OK;
  sqlite3 *db = pParse->db;
  if( !db->init.busy ){
    if( (db->flags & SQLITE_Initialized)==0 ){
      rc = sqlite3Init(db, &pParse->zErrMsg);
    }
  }
  assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy );
  if( rc!=SQLITE_OK ){
    pParse->rc = rc;
    pParse->nErr++;
  }
  return rc;
}

/*
** The version of the library
*/
const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
const char sqlite3_version[] = SQLITE_VERSION;
const char *sqlite3_libversion(void){ return sqlite3_version; }
int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }

/*
** This is the default collating function named "BINARY" which is always
** available.
*/
static int binCollFunc(
  void *NotUsed,
  int nKey1, const void *pKey1,
  int nKey2, const void *pKey2
){
  int rc, n;
  n = nKey1<nKey2 ? nKey1 : nKey2;
  rc = memcmp(pKey1, pKey2, n);
  if( rc==0 ){
    rc = nKey1 - nKey2;
  }
  return rc;
}

/*
** Another built-in collating sequence: NOCASE. 
**
** This collating sequence is intended to be used for "case independant
** comparison". SQLite's knowledge of upper and lower case equivalents
** extends only to the 26 characters used in the English language.
**
** At the moment there is only a UTF-8 implementation.
*/
static int nocaseCollatingFunc(
  void *NotUsed,
  int nKey1, const void *pKey1,
  int nKey2, const void *pKey2
){
  int r = sqlite3StrNICmp(
      (const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2);
  if( 0==r ){
    r = nKey1-nKey2;
  }
  return r;
}

/*
** Return the ROWID of the most recent insert
*/
sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
  return db->lastRowid;
}

/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
int sqlite3_changes(sqlite3 *db){
  return db->nChange;
}

/*
** Return the number of changes since the database handle was opened.
*/
int sqlite3_total_changes(sqlite3 *db){
  return db->nTotalChange;
}

/*
** Close an existing SQLite database
*/
int sqlite3_close(sqlite3 *db){
  HashElem *i;
  int j;

  if( !db ){
    return SQLITE_OK;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }

  /* If there are any outstanding VMs, return SQLITE_BUSY. */
  if( db->pVdbe ){
    sqlite3Error(db, SQLITE_BUSY, 
        "Unable to close due to unfinalised statements");
    return SQLITE_BUSY;
  }
  assert( !sqlite3SafetyCheck(db) );

  /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database
  ** cannot be opened for some reason. So this routine needs to run in
  ** that case. But maybe there should be an extra magic value for the
  ** "failed to open" state.
  */
  if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){
    /* printf("DID NOT CLOSE\n"); fflush(stdout); */
    return SQLITE_ERROR;
  }

  for(j=0; j<db->nDb; j++){
    struct Db *pDb = &db->aDb[j];
    if( pDb->pBt ){
      sqlite3BtreeClose(pDb->pBt);
      pDb->pBt = 0;
    }
  }
  sqlite3ResetInternalSchema(db, 0);
  assert( db->nDb<=2 );
  assert( db->aDb==db->aDbStatic );
  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
    FuncDef *pFunc, *pNext;
    for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
      pNext = pFunc->pNext;
      sqliteFree(pFunc);
    }
  }

  for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
    CollSeq *pColl = (CollSeq *)sqliteHashData(i);
    sqliteFree(pColl);
  }
  sqlite3HashClear(&db->aCollSeq);

  sqlite3HashClear(&db->aFunc);
  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
  if( db->pValue ){
    sqlite3ValueFree(db->pValue);
  }
  if( db->pErr ){
    sqlite3ValueFree(db->pErr);
  }

  db->magic = SQLITE_MAGIC_ERROR;
  sqliteFree(db);
  return SQLITE_OK;
}

/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
  int i;
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt ){
      sqlite3BtreeRollback(db->aDb[i].pBt);
      db->aDb[i].inTrans = 0;
    }
  }
  sqlite3ResetInternalSchema(db, 0);
}

/*
** Return a static string that describes the kind of error specified in the
** argument.
*/
const char *sqlite3ErrStr(int rc){
  const char *z;
  switch( rc ){
    case SQLITE_ROW:
    case SQLITE_DONE:
    case SQLITE_OK:         z = "not an error";                          break;
    case SQLITE_ERROR:      z = "SQL logic error or missing database";   break;
    case SQLITE_INTERNAL:   z = "internal SQLite implementation flaw";   break;
    case SQLITE_PERM:       z = "access permission denied";              break;
    case SQLITE_ABORT:      z = "callback requested query abort";        break;
    case SQLITE_BUSY:       z = "database is locked";                    break;
    case SQLITE_LOCKED:     z = "database table is locked";              break;
    case SQLITE_NOMEM:      z = "out of memory";                         break;
    case SQLITE_READONLY:   z = "attempt to write a readonly database";  break;
    case SQLITE_INTERRUPT:  z = "interrupted";                           break;
    case SQLITE_IOERR:      z = "disk I/O error";                        break;
    case SQLITE_CORRUPT:    z = "database disk image is malformed";      break;
    case SQLITE_NOTFOUND:   z = "table or record not found";             break;
    case SQLITE_FULL:       z = "database is full";                      break;
    case SQLITE_CANTOPEN:   z = "unable to open database file";          break;
    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
    case SQLITE_EMPTY:      z = "table contains no data";                break;
    case SQLITE_SCHEMA:     z = "database schema has changed";           break;
    case SQLITE_TOOBIG:     z = "too much data for one table row";       break;
    case SQLITE_CONSTRAINT: z = "constraint failed";                     break;
    case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;
    case SQLITE_MISUSE:     z = "library routine called out of sequence";break;
    case SQLITE_NOLFS:      z = "kernel lacks large file support";       break;
    case SQLITE_AUTH:       z = "authorization denied";                  break;
    case SQLITE_FORMAT:     z = "auxiliary database format error";       break;
    case SQLITE_RANGE:      z = "bind or column index out of range";     break;
    case SQLITE_NOTADB:     z = "file is encrypted or is not a database";break;
    default:                z = "unknown error";                         break;
  }
  return z;
}

/*
** This routine implements a busy callback that sleeps and tries
** again until a timeout value is reached.  The timeout value is
** an integer number of milliseconds passed in as the first
** argument.
*/
static int sqliteDefaultBusyCallback(
 void *Timeout,           /* Maximum amount of time to wait */
 int count                /* Number of times table has been busy */
){
#if SQLITE_MIN_SLEEP_MS==1
  static const char delays[] =
     { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50,  50, 100};
  static const short int totals[] =
     { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228, 287};
# define NDELAY (sizeof(delays)/sizeof(delays[0]))
  ptr timeout = (ptr)Timeout;
  ptr delay, prior;

  if( count <= NDELAY ){
    delay = delays[count-1];
    prior = totals[count-1];
  }else{
    delay = delays[NDELAY-1];
    prior = totals[NDELAY-1] + delay*(count-NDELAY-1);
  }
  if( prior + delay > timeout ){
    delay = timeout - prior;
    if( delay<=0 ) return 0;
  }
  sqlite3OsSleep(delay);
  return 1;
#else
  int timeout = (int)Timeout;
  if( (count+1)*1000 > timeout ){
    return 0;
  }
  sqlite3OsSleep(1000);
  return 1;
#endif
}

/*
** This routine sets the busy callback for an Sqlite database to the
** given callback function with the given argument.
*/
int sqlite3_busy_handler(
  sqlite3 *db,
  int (*xBusy)(void*,int),
  void *pArg
){
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  db->busyHandler.xFunc = xBusy;
  db->busyHandler.pArg = pArg;
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This routine sets the progress callback for an Sqlite database to the
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
*/
void sqlite3_progress_handler(
  sqlite3 *db, 
  int nOps,
  int (*xProgress)(void*), 
  void *pArg
){
  if( !sqlite3SafetyCheck(db) ){
    if( nOps>0 ){
      db->xProgress = xProgress;
      db->nProgressOps = nOps;
      db->pProgressArg = pArg;
    }else{
      db->xProgress = 0;
      db->nProgressOps = 0;
      db->pProgressArg = 0;
    }
  }
}
#endif


/*
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
int sqlite3_busy_timeout(sqlite3 *db, int ms){
  if( ms>0 ){
    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)(ptr)ms);
  }else{
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*
** Cause any pending operation to stop at its earliest opportunity.
*/
void sqlite3_interrupt(sqlite3 *db){
  if( !sqlite3SafetyCheck(db) ){
    db->flags |= SQLITE_Interrupt;
  }
}

/*
** Windows systems should call this routine to free memory that
** is returned in the in the errmsg parameter of sqlite3_open() when
** SQLite is a DLL.  For some reason, it does not work to call free()
** directly.
**
** Note that we need to call free() not sqliteFree() here.
*/
void sqlite3_free(char *p){ free(p); }

/*
** Create new user functions.
*/
int sqlite3_create_function(
  sqlite3 *db,
  const char *zFunctionName,
  int nArg,
  int enc,
  void *pUserData,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
  void (*xFinal)(sqlite3_context*)
){
  FuncDef *p;
  int nName;

  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  if( zFunctionName==0 ||
      (xFunc && (xFinal || xStep)) || 
      (!xFunc && (xFinal && !xStep)) ||
      (!xFunc && (!xFinal && xStep)) ||
      (nArg<-1 || nArg>127) ||
      (255<(nName = strlen(zFunctionName))) ){
    return SQLITE_ERROR;
  }
  
#ifndef SQLITE_OMIT_UTF16
  /* If SQLITE_UTF16 is specified as the encoding type, transform this
  ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
  ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
  **
  ** If SQLITE_ANY is specified, add three versions of the function
  ** to the hash table.
  */
  if( enc==SQLITE_UTF16 ){
    enc = SQLITE_UTF16NATIVE;
  }else if( enc==SQLITE_ANY ){
    int rc;
    rc = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF8,
         pUserData, xFunc, xStep, xFinal);
    if( rc!=SQLITE_OK ) return rc;
    rc = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF16LE,
        pUserData, xFunc, xStep, xFinal);
    if( rc!=SQLITE_OK ) return rc;
    enc = SQLITE_UTF16BE;
  }
#else
  enc = SQLITE_UTF8;
#endif
  
  /* Check if an existing function is being overridden or deleted. If so,
  ** and there are active VMs, then return SQLITE_BUSY. If a function
  ** is being overridden/deleted but there are no active VMs, allow the
  ** operation to continue but invalidate all precompiled statements.
  */
  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0);
  if( p && p->iPrefEnc==enc && p->nArg==nArg ){
    if( db->activeVdbeCnt ){
      sqlite3Error(db, SQLITE_BUSY, 
        "Unable to delete/modify user-function due to active statements");
      return SQLITE_BUSY;
    }else{
      sqlite3ExpirePreparedStatements(db);
    }
  }

  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
  if( p==0 ) return SQLITE_NOMEM;
  p->xFunc = xFunc;
  p->xStep = xStep;
  p->xFinalize = xFinal;
  p->pUserData = pUserData;
  return SQLITE_OK;
}
#ifndef SQLITE_OMIT_UTF16
int sqlite3_create_function16(
  sqlite3 *db,
  const void *zFunctionName,
  int nArg,
  int eTextRep,
  void *pUserData,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
){
  int rc;
  char const *zFunc8;
  sqlite3_value *pTmp;

  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  pTmp = sqlite3GetTransientValue(db);
  sqlite3ValueSetStr(pTmp, -1, zFunctionName, SQLITE_UTF16NATIVE,SQLITE_STATIC);
  zFunc8 = sqlite3ValueText(pTmp, SQLITE_UTF8);

  if( !zFunc8 ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_create_function(db, zFunc8, nArg, eTextRep, 
      pUserData, xFunc, xStep, xFinal);
  return rc;
}
#endif

/*
** Register a trace function.  The pArg from the previously registered trace
** is returned.  
**
** A NULL trace function means that no tracing is executes.  A non-NULL
** trace is a pointer to a function that is invoked at the start of each
** sqlite3_exec().
*/
void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
  void *pOld = db->pTraceArg;
  db->xTrace = xTrace;
  db->pTraceArg = pArg;
  return pOld;
}

/*** EXPERIMENTAL ***
**
** Register a function to be invoked when a transaction comments.
** If either function returns non-zero, then the commit becomes a
** rollback.
*/
void *sqlite3_commit_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  int (*xCallback)(void*),  /* Function to invoke on each commit */
  void *pArg                /* Argument to the function */
){
  void *pOld = db->pCommitArg;
  db->xCommitCallback = xCallback;
  db->pCommitArg = pArg;
  return pOld;
}


/*
** This routine is called to create a connection to a database BTree
** driver.  If zFilename is the name of a file, then that file is
** opened and used.  If zFilename is the magic name ":memory:" then
** the database is stored in memory (and is thus forgotten as soon as
** the connection is closed.)  If zFilename is NULL then the database
** is for temporary use only and is deleted as soon as the connection
** is closed.
**
** A temporary database can be either a disk file (that is automatically
** deleted when the file is closed) or a set of red-black trees held in memory,
** depending on the values of the TEMP_STORE compile-time macro and the
** db->temp_store variable, according to the following chart:
**
**       TEMP_STORE     db->temp_store     Location of temporary database
**       ----------     --------------     ------------------------------
**           0               any             file
**           1                1              file
**           1                2              memory
**           1                0              file
**           2                1              file
**           2                2              memory
**           2                0              memory
**           3               any             memory
*/
int sqlite3BtreeFactory(
  const sqlite3 *db,        /* Main database when opening aux otherwise 0 */
  const char *zFilename,    /* Name of the file containing the BTree database */
  int omitJournal,          /* if TRUE then do not journal this file */
  int nCache,               /* How many pages in the page cache */
  Btree **ppBtree           /* Pointer to new Btree object written here */
){
  int btree_flags = 0;
  int rc;
  
  assert( ppBtree != 0);
  if( omitJournal ){
    btree_flags |= BTREE_OMIT_JOURNAL;
  }
  if( db->flags & SQLITE_NoReadlock ){
    btree_flags |= BTREE_NO_READLOCK;
  }
  if( zFilename==0 ){
#if TEMP_STORE==0
    /* Do nothing */
#endif
#ifndef SQLITE_OMIT_MEMORYDB
#if TEMP_STORE==1
    if( db->temp_store==2 ) zFilename = ":memory:";
#endif
#if TEMP_STORE==2
    if( db->temp_store!=1 ) zFilename = ":memory:";
#endif
#if TEMP_STORE==3
    zFilename = ":memory:";
#endif
#endif /* SQLITE_OMIT_MEMORYDB */
  }

  rc = sqlite3BtreeOpen(zFilename, ppBtree, btree_flags);
  if( rc==SQLITE_OK ){
    sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
    sqlite3BtreeSetCacheSize(*ppBtree, nCache);
  }
  return rc;
}

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
  const char *z;
  if( sqlite3_malloc_failed ){
    return sqlite3ErrStr(SQLITE_NOMEM);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return sqlite3ErrStr(SQLITE_MISUSE);
  }
  z = sqlite3_value_text(db->pErr);
  if( z==0 ){
    z = sqlite3ErrStr(db->errCode);
  }
  return z;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
const void *sqlite3_errmsg16(sqlite3 *db){
  /* Because all the characters in the string are in the unicode
  ** range 0x00-0xFF, if we pad the big-endian string with a 
  ** zero byte, we can obtain the little-endian string with
  ** &big_endian[1].
  */
  static const char outOfMemBe[] = {
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0
  };
  static const char misuseBe [] = {
    0, 'l', 0, 'i', 0, 'b', 0, 'r', 0, 'a', 0, 'r', 0, 'y', 0, ' ', 
    0, 'r', 0, 'o', 0, 'u', 0, 't', 0, 'i', 0, 'n', 0, 'e', 0, ' ', 
    0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
  };

  const void *z;
  if( sqlite3_malloc_failed ){
    return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  z = sqlite3_value_text16(db->pErr);
  if( z==0 ){
    sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
         SQLITE_UTF8, SQLITE_STATIC);
    z = sqlite3_value_text16(db->pErr);
  }
  return z;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the most recent error code generated by an SQLite routine.
*/
int sqlite3_errcode(sqlite3 *db){
  if( sqlite3_malloc_failed ){
    return SQLITE_NOMEM;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  return db->errCode;
}

/*
** Check schema cookies in all databases.  If any cookie is out
** of date, return 0.  If all schema cookies are current, return 1.
*/
static int schemaIsValid(sqlite3 *db){
  int iDb;
  int rc;
  BtCursor *curTemp;
  int cookie;
  int allOk = 1;

  for(iDb=0; allOk && iDb<db->nDb; iDb++){
    Btree *pBt;
    pBt = db->aDb[iDb].pBt;
    if( pBt==0 ) continue;
    rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp);
    if( rc==SQLITE_OK ){
      rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);
      if( rc==SQLITE_OK && cookie!=db->aDb[iDb].schema_cookie ){
        allOk = 0;
      }
      sqlite3BtreeCloseCursor(curTemp);
    }
  }
  return allOk;
}

/*
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
int sqlite3_prepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char** pzTail       /* OUT: End of parsed string */
){
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;

  if( sqlite3_malloc_failed ){
    return SQLITE_NOMEM;
  }

  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    return SQLITE_MISUSE;
  }

  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( sqlite3_malloc_failed ){
    rc = SQLITE_NOMEM;
    sqlite3RollbackAll(db);
    sqlite3ResetInternalSchema(db, 0);
    db->flags &= ~SQLITE_InTrans;
    goto prepare_out;
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);
  }
  if( pzTail ) *pzTail = sParse.zTail;
  rc = sParse.rc;

#ifndef SQLITE_OMIT_EXPLAIN
  if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
    sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
    sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
    sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
    sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
    sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
    sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
  } 
#endif

prepare_out:
  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
  }
  if( rc==SQLITE_OK ){
    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  }else if( sParse.pVdbe ){
    sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
  }

  if( zErrMsg ){
    sqlite3Error(db, rc, "%s", zErrMsg);
    sqliteFree(zErrMsg);
  }else{
    sqlite3Error(db, rc, 0);
  }
  return rc;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
*/
int sqlite3_prepare16(
  sqlite3 *db,              /* Database handle. */ 
  const void *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const void **pzTail       /* OUT: End of parsed string */
){
  /* This function currently works by first transforming the UTF-16
  ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
  ** tricky bit is figuring out the pointer to return in *pzTail.
  */
  char const *zSql8 = 0;
  char const *zTail8 = 0;
  int rc;
  sqlite3_value *pTmp;

  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  pTmp = sqlite3GetTransientValue(db);
  sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
  if( !zSql8 ){
    sqlite3Error(db, SQLITE_NOMEM, 0);
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);

  if( zTail8 && pzTail ){
    /* If sqlite3_prepare returns a tail pointer, we calculate the
    ** equivalent pointer into the UTF-16 string by counting the unicode
    ** characters between zSql8 and zTail8, and then returning a pointer
    ** the same number of characters into the UTF-16 string.
    */
    int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
    *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
  }
 
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** This routine does the work of opening a database on behalf of
** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
** is UTF-8 encoded. The fourth argument, "def_enc" is one of the TEXT_*
** macros from sqliteInt.h. If we end up creating a new database file
** (not opening an existing one), the text encoding of the database
** will be set to this value.
*/
static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb         /* OUT: Returned database handle */
){
  sqlite3 *db;
  int rc, i;

  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  db->nDb = 2;
  db->aDb = db->aDbStatic;
  db->enc = SQLITE_UTF8;
  db->autoCommit = 1;
  db->flags |= SQLITE_ShortColNames;
  sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
  for(i=0; i<db->nDb; i++){
    sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
  }
  
  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.
  */
  if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
      sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
      !(db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0)) ){
    rc = db->errCode;
    assert( rc!=SQLITE_OK );
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);

  /* Open the backend database driver */
  rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
  if( rc!=SQLITE_OK ){
    sqlite3Error(db, rc, 0);
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }
  db->aDb[0].zName = "main";
  db->aDb[1].zName = "temp";

  /* The default safety_level for the main database is 'full' for the temp
  ** database it is 'NONE'. This matches the pager layer defaults.  */
  db->aDb[0].safety_level = 3;
  db->aDb[1].safety_level = 1;

  /* Register all built-in functions, but do not attempt to read the
  ** database schema yet. This is delayed until the first time the database
  ** is accessed.
  */
  sqlite3RegisterBuiltinFunctions(db);
  sqlite3Error(db, SQLITE_OK, 0);
  db->magic = SQLITE_MAGIC_OPEN;

opendb_out:
  if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){
    sqlite3Error(db, SQLITE_NOMEM, 0);
  }
  *ppDb = db;
  return sqlite3_errcode(db);
}

/*
** Open a new database handle.
*/
int sqlite3_open(
  const char *zFilename, 
  sqlite3 **ppDb 
){
  return openDatabase(zFilename, ppDb);
}

#ifndef SQLITE_OMIT_UTF16
/*
** Open a new database handle.
*/
int sqlite3_open16(
  const void *zFilename, 
  sqlite3 **ppDb
){
  char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
  int rc = SQLITE_NOMEM;
  sqlite3_value *pVal;

  assert( ppDb );
  *ppDb = 0;
  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb);
    if( rc==SQLITE_OK && *ppDb ){
      sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
    }
  }
  if( pVal ){
    sqlite3ValueFree(pVal);
  }

  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** The following routine destroys a virtual machine that is created by
** the sqlite3_compile() routine. The integer returned is an SQLITE_
** success/failure code that describes the result of executing the virtual
** machine.
**
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
int sqlite3_finalize(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
  }
  return rc;
}

/*
** Terminate the current execution of an SQL statement and reset it
** back to its starting state so that it can be reused. A success code from
** the prior execution is returned.
**
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
int sqlite3_reset(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    rc = sqlite3VdbeReset((Vdbe*)pStmt);
    sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0, 0);
  }
  return rc;
}

/*
** Register a new collation sequence with the database handle db.
*/
int sqlite3_create_collation(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){
  CollSeq *pColl;
  int rc = SQLITE_OK;
  
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }

  /* If SQLITE_UTF16 is specified as the encoding type, transform this
  ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
  ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
  */
  if( enc==SQLITE_UTF16 ){
    enc = SQLITE_UTF16NATIVE;
  }

  if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16LE && enc!=SQLITE_UTF16BE ){
    sqlite3Error(db, SQLITE_ERROR, 
        "Param 3 to sqlite3_create_collation() must be one of "
        "SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16LE or SQLITE_UTF16BE"
    );
    return SQLITE_ERROR;
  }

  /* Check if this call is removing or replacing an existing collation 
  ** sequence. If so, and there are active VMs, return busy. If there
  ** are no active VMs, invalidate any pre-compiled statements.
  */
  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0);
  if( pColl && pColl->xCmp ){
    if( db->activeVdbeCnt ){
      sqlite3Error(db, SQLITE_BUSY, 
        "Unable to delete/modify collation sequence due to active statements");
      return SQLITE_BUSY;
    }
    sqlite3ExpirePreparedStatements(db);
  }

  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
  if( 0==pColl ){
   rc = SQLITE_NOMEM;
  }else{
    pColl->xCmp = xCompare;
    pColl->pUser = pCtx;
    pColl->enc = enc;
  }
  sqlite3Error(db, rc, 0);
  return rc;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Register a new collation sequence with the database handle db.
*/
int sqlite3_create_collation16(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){
  char const *zName8;
  sqlite3_value *pTmp;
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  pTmp = sqlite3GetTransientValue(db);
  sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
  return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
int sqlite3_collation_needed(
  sqlite3 *db, 
  void *pCollNeededArg, 
  void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
){
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  db->xCollNeeded = xCollNeeded;
  db->xCollNeeded16 = 0;
  db->pCollNeededArg = pCollNeededArg;
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
int sqlite3_collation_needed16(
  sqlite3 *db, 
  void *pCollNeededArg, 
  void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
){
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  db->xCollNeeded = 0;
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */
Added SQLite.Interop/src/opcodes.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
/* Automatically generated.  Do not edit */
/* See the mkopcodec.awk script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
const char *const sqlite3OpcodeNames[] = { "?",
 /*   1 */ "ContextPop",
 /*   2 */ "IntegrityCk",
 /*   3 */ "DropTrigger",
 /*   4 */ "DropIndex",
 /*   5 */ "Recno",
 /*   6 */ "KeyAsData",
 /*   7 */ "Delete",
 /*   8 */ "MoveGt",
 /*   9 */ "VerifyCookie",
 /*  10 */ "Push",
 /*  11 */ "Dup",
 /*  12 */ "Blob",
 /*  13 */ "IdxGT",
 /*  14 */ "IdxRecno",
 /*  15 */ "RowKey",
 /*  16 */ "PutStrKey",
 /*  17 */ "IsUnique",
 /*  18 */ "SetNumColumns",
 /*  19 */ "Expire",
 /*  20 */ "IdxIsNull",
 /*  21 */ "NullRow",
 /*  22 */ "OpenPseudo",
 /*  23 */ "OpenWrite",
 /*  24 */ "OpenRead",
 /*  25 */ "Transaction",
 /*  26 */ "AutoCommit",
 /*  27 */ "Pop",
 /*  28 */ "Halt",
 /*  29 */ "Vacuum",
 /*  30 */ "ListRead",
 /*  31 */ "RowData",
 /*  32 */ "NotExists",
 /*  33 */ "MoveLe",
 /*  34 */ "SetCookie",
 /*  35 */ "Variable",
 /*  36 */ "AggNext",
 /*  37 */ "AggReset",
 /*  38 */ "Sort",
 /*  39 */ "AggContextPush",
 /*  40 */ "IdxDelete",
 /*  41 */ "ResetCount",
 /*  42 */ "OpenTemp",
 /*  43 */ "Integer",
 /*  44 */ "AggSet",
 /*  45 */ "CreateIndex",
 /*  46 */ "IdxPut",
 /*  47 */ "MoveLt",
 /*  48 */ "Return",
 /*  49 */ "MemLoad",
 /*  50 */ "SortNext",
 /*  51 */ "IdxLT",
 /*  52 */ "Rewind",
 /*  53 */ "AddImm",
 /*  54 */ "AggFunc",
 /*  55 */ "AggInit",
 /*  56 */ "MemIncr",
 /*  57 */ "ListReset",
 /*  58 */ "Clear",
 /*  59 */ "PutIntKey",
 /*  60 */ "If",
 /*  61 */ "Callback",
 /*  62 */ "SortReset",
 /*  63 */ "SortPut",
 /*  64 */ "Or",
 /*  65 */ "And",
 /*  66 */ "Not",
 /*  67 */ "AggContextPop",
 /*  68 */ "Last",
 /*  69 */ "NotFound",
 /*  70 */ "IsNull",
 /*  71 */ "NotNull",
 /*  72 */ "Ne",
 /*  73 */ "Eq",
 /*  74 */ "Gt",
 /*  75 */ "Le",
 /*  76 */ "Lt",
 /*  77 */ "Ge",
 /*  78 */ "MakeRecord",
 /*  79 */ "BitAnd",
 /*  80 */ "BitOr",
 /*  81 */ "ShiftLeft",
 /*  82 */ "ShiftRight",
 /*  83 */ "Add",
 /*  84 */ "Subtract",
 /*  85 */ "Multiply",
 /*  86 */ "Divide",
 /*  87 */ "Remainder",
 /*  88 */ "Concat",
 /*  89 */ "Negative",
 /*  90 */ "String",
 /*  91 */ "BitNot",
 /*  92 */ "String8",
 /*  93 */ "Goto",
 /*  94 */ "AggFocus",
 /*  95 */ "IfMemPos",
 /*  96 */ "DropTable",
 /*  97 */ "Column",
 /*  98 */ "Noop",
 /*  99 */ "AggGet",
 /* 100 */ "CreateTable",
 /* 101 */ "NewRecno",
 /* 102 */ "Found",
 /* 103 */ "Distinct",
 /* 104 */ "Close",
 /* 105 */ "Statement",
 /* 106 */ "IfNot",
 /* 107 */ "Pull",
 /* 108 */ "MemMax",
 /* 109 */ "MemStore",
 /* 110 */ "Next",
 /* 111 */ "Prev",
 /* 112 */ "MoveGe",
 /* 113 */ "MustBeInt",
 /* 114 */ "ForceInt",
 /* 115 */ "CollSeq",
 /* 116 */ "Gosub",
 /* 117 */ "ContextPush",
 /* 118 */ "ListRewind",
 /* 119 */ "ListWrite",
 /* 120 */ "ParseSchema",
 /* 121 */ "Destroy",
 /* 122 */ "IdxGE",
 /* 123 */ "FullKey",
 /* 124 */ "ReadCookie",
 /* 125 */ "AbsValue",
 /* 126 */ "Function",
 /* 127 */ "NotUsed_127",
 /* 128 */ "NotUsed_128",
 /* 129 */ "NotUsed_129",
 /* 130 */ "Real",
 /* 131 */ "HexBlob",
};
#endif
Added SQLite.Interop/src/opcodes.h.














































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* Automatically generated.  Do not edit */
/* See the mkopcodeh.awk script for details */
#define OP_ContextPop                           1
#define OP_IntegrityCk                          2
#define OP_DropTrigger                          3
#define OP_DropIndex                            4
#define OP_Recno                                5
#define OP_KeyAsData                            6
#define OP_Delete                               7
#define OP_MoveGt                               8
#define OP_VerifyCookie                         9
#define OP_Push                                10
#define OP_Dup                                 11
#define OP_Blob                                12
#define OP_IdxGT                               13
#define OP_IdxRecno                            14
#define OP_RowKey                              15
#define OP_PutStrKey                           16
#define OP_IsUnique                            17
#define OP_SetNumColumns                       18
#define OP_Eq                                  73   /* same as TK_EQ       */
#define OP_Expire                              19
#define OP_IdxIsNull                           20
#define OP_NullRow                             21
#define OP_OpenPseudo                          22
#define OP_OpenWrite                           23
#define OP_OpenRead                            24
#define OP_Transaction                         25
#define OP_AutoCommit                          26
#define OP_Negative                            89   /* same as TK_UMINUS   */
#define OP_Pop                                 27
#define OP_Halt                                28
#define OP_Vacuum                              29
#define OP_ListRead                            30
#define OP_RowData                             31
#define OP_NotExists                           32
#define OP_MoveLe                              33
#define OP_SetCookie                           34
#define OP_Variable                            35
#define OP_AggNext                             36
#define OP_AggReset                            37
#define OP_Sort                                38
#define OP_AggContextPush                      39
#define OP_IdxDelete                           40
#define OP_ResetCount                          41
#define OP_OpenTemp                            42
#define OP_NotNull                             71   /* same as TK_NOTNULL  */
#define OP_Ge                                  77   /* same as TK_GE       */
#define OP_Remainder                           87   /* same as TK_REM      */
#define OP_Divide                              86   /* same as TK_SLASH    */
#define OP_Integer                             43
#define OP_AggSet                              44
#define OP_CreateIndex                         45
#define OP_IdxPut                              46
#define OP_MoveLt                              47
#define OP_And                                 65   /* same as TK_AND      */
#define OP_ShiftLeft                           81   /* same as TK_LSHIFT   */
#define OP_Real                               130   /* same as TK_FLOAT    */
#define OP_Return                              48
#define OP_MemLoad                             49
#define OP_SortNext                            50
#define OP_IdxLT                               51
#define OP_Rewind                              52
#define OP_Gt                                  74   /* same as TK_GT       */
#define OP_AddImm                              53
#define OP_Subtract                            84   /* same as TK_MINUS    */
#define OP_AggFunc                             54
#define OP_AggInit                             55
#define OP_MemIncr                             56
#define OP_ListReset                           57
#define OP_Clear                               58
#define OP_PutIntKey                           59
#define OP_IsNull                              70   /* same as TK_ISNULL   */
#define OP_If                                  60
#define OP_Callback                            61
#define OP_SortReset                           62
#define OP_SortPut                             63
#define OP_AggContextPop                       67
#define OP_Last                                68
#define OP_NotFound                            69
#define OP_MakeRecord                          78
#define OP_BitAnd                              79   /* same as TK_BITAND   */
#define OP_Add                                 83   /* same as TK_PLUS     */
#define OP_HexBlob                            131   /* same as TK_BLOB     */
#define OP_String                              90
#define OP_Goto                                93
#define OP_AggFocus                            94
#define OP_IfMemPos                            95
#define OP_DropTable                           96
#define OP_Column                              97
#define OP_Noop                                98
#define OP_Not                                 66   /* same as TK_NOT      */
#define OP_Le                                  75   /* same as TK_LE       */
#define OP_BitOr                               80   /* same as TK_BITOR    */
#define OP_Multiply                            85   /* same as TK_STAR     */
#define OP_String8                             92   /* same as TK_STRING   */
#define OP_AggGet                              99
#define OP_CreateTable                        100
#define OP_NewRecno                           101
#define OP_Found                              102
#define OP_Distinct                           103
#define OP_Close                              104
#define OP_Statement                          105
#define OP_IfNot                              106
#define OP_Pull                               107
#define OP_MemMax                             108
#define OP_MemStore                           109
#define OP_Next                               110
#define OP_Prev                               111
#define OP_MoveGe                             112
#define OP_Lt                                  76   /* same as TK_LT       */
#define OP_Ne                                  72   /* same as TK_NE       */
#define OP_MustBeInt                          113
#define OP_ForceInt                           114
#define OP_ShiftRight                          82   /* same as TK_RSHIFT   */
#define OP_CollSeq                            115
#define OP_Gosub                              116
#define OP_ContextPush                        117
#define OP_ListRewind                         118
#define OP_ListWrite                          119
#define OP_ParseSchema                        120
#define OP_Destroy                            121
#define OP_IdxGE                              122
#define OP_FullKey                            123
#define OP_ReadCookie                         124
#define OP_BitNot                              91   /* same as TK_BITNOT   */
#define OP_AbsValue                           125
#define OP_Or                                  64   /* same as TK_OR       */
#define OP_Function                           126
#define OP_Concat                              88   /* same as TK_CONCAT   */

/* The following opcode values are never used */
#define OP_NotUsed_127                        127
#define OP_NotUsed_128                        128
#define OP_NotUsed_129                        129
Added SQLite.Interop/src/os.h.












































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2001 September 16
**
** 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 header file (together with is companion C source-code file
** "os.c") attempt to abstract the underlying operating system so that
** the SQLite library will work on both POSIX and windows systems.
*/
#ifndef _SQLITE_OS_H_
#define _SQLITE_OS_H_

/*
** Figure out if we are dealing with Unix, Windows or MacOS.
**
** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix.
**      The MacOS build is designed to use CodeWarrior (tested with v8)
*/
#if !defined(OS_UNIX) && !defined(OS_TEST)
# ifndef OS_WIN
#   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
#     define OS_WIN 1
#     define OS_UNIX 0
#   else
#     define OS_WIN 0
#     define OS_UNIX 1
#  endif
# else
#  define OS_UNIX 0
# endif
#else
# ifndef OS_WIN
#  define OS_WIN 0
# endif
#endif

/*
** Invoke the appropriate operating-system specific header file.
*/
#if OS_TEST
# include "os_test.h"
#endif
#if OS_UNIX
# include "os_unix.h"
#endif
#if OS_WIN
# include "os_win.h"
#endif

/*
** Temporary files are named starting with this prefix followed by 16 random
** alphanumeric characters, and no file extension. They are stored in the
** OS's standard temporary file directory, and are deleted prior to exit.
** If sqlite is being embedded in another program, you may wish to change the
** prefix to reflect your program's name, so that if your program exits
** prematurely, old temporary files can be easily identified. This can be done
** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
*/
#ifndef TEMP_FILE_PREFIX
# define TEMP_FILE_PREFIX "sqlite_"
#endif

/*
** The following values may be passed as the second argument to
** sqlite3OsLock(). The various locks exhibit the following semantics:
**
** SHARED:    Any number of processes may hold a SHARED lock simultaneously.
** RESERVED:  A single process may hold a RESERVED lock on a file at
**            any time. Other processes may hold and obtain new SHARED locks.
** PENDING:   A single process may hold a PENDING lock on a file at
**            any one time. Existing SHARED locks may persist, but no new
**            SHARED locks may be obtained by other processes.
** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks.
**
** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a
** process that requests an EXCLUSIVE lock may actually obtain a PENDING
** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to
** sqlite3OsLock().
*/
#define NO_LOCK         0
#define SHARED_LOCK     1
#define RESERVED_LOCK   2
#define PENDING_LOCK    3
#define EXCLUSIVE_LOCK  4

/*
** File Locking Notes:  (Mostly about windows but also some info for Unix)
**
** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
** those functions are not available.  So we use only LockFile() and
** UnlockFile().
**
** LockFile() prevents not just writing but also reading by other processes.
** A SHARED_LOCK is obtained by locking a single randomly-chosen 
** byte out of a specific range of bytes. The lock byte is obtained at 
** random so two separate readers can probably access the file at the 
** same time, unless they are unlucky and choose the same lock byte.
** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range.
** There can only be one writer.  A RESERVED_LOCK is obtained by locking
** a single byte of the file that is designated as the reserved lock byte.
** A PENDING_LOCK is obtained by locking a designated byte different from
** the RESERVED_LOCK byte.
**
** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
** which means we can use reader/writer locks.  When reader/writer locks
** are used, the lock is placed on the same range of bytes that is used
** for probabilistic locking in Win95/98/ME.  Hence, the locking scheme
** will support two or more Win95 readers or two or more WinNT readers.
** But a single Win95 reader will lock out all WinNT readers and a single
** WinNT reader will lock out all other Win95 readers.
**
** The following #defines specify the range of bytes used for locking.
** SHARED_SIZE is the number of bytes available in the pool from which
** a random byte is selected for a shared lock.  The pool of bytes for
** shared locks begins at SHARED_FIRST. 
**
** These #defines are available in os.h so that Unix can use the same
** byte ranges for locking.  This leaves open the possiblity of having
** clients on win95, winNT, and unix all talking to the same shared file
** and all locking correctly.  To do so would require that samba (or whatever
** tool is being used for file sharing) implements locks correctly between
** windows and unix.  I'm guessing that isn't likely to happen, but by
** using the same locking range we are at least open to the possibility.
**
** Locking in windows is manditory.  For this reason, we cannot store
** actual data in the bytes used for locking.  The pager never allocates
** the pages involved in locking therefore.  SHARED_SIZE is selected so
** that all locks will fit on a single page even at the minimum page size.
** PENDING_BYTE defines the beginning of the locks.  By default PENDING_BYTE
** is set high so that we don't have to allocate an unused page except
** for very large databases.  But one should test the page skipping logic 
** by setting PENDING_BYTE low and running the entire regression suite.
**
** Changing the value of PENDING_BYTE results in a subtly incompatible
** file format.  Depending on how it is changed, you might not notice
** the incompatibility right away, even running a full regression test.
** The default location of PENDING_BYTE is the first byte past the
** 1GB boundary.
**
*/
#define PENDING_BYTE      0x40000000  /* First byte past the 1GB boundary */
/* #define PENDING_BYTE     0x5400   // Page 22 - for testing */
#define RESERVED_BYTE     (PENDING_BYTE+1)
#define SHARED_FIRST      (PENDING_BYTE+2)
#define SHARED_SIZE       510


int sqlite3OsDelete(const char*);
int sqlite3OsFileExists(const char*);
int sqlite3OsOpenReadWrite(const char*, OsFile*, int*);
int sqlite3OsOpenExclusive(const char*, OsFile*, int);
int sqlite3OsOpenReadOnly(const char*, OsFile*);
int sqlite3OsOpenDirectory(const char*, OsFile*);
int sqlite3OsSyncDirectory(const char*);
int sqlite3OsTempFileName(char*);
int sqlite3OsIsDirWritable(char*);
int sqlite3OsClose(OsFile*);
int sqlite3OsRead(OsFile*, void*, int amt);
int sqlite3OsWrite(OsFile*, const void*, int amt);
int sqlite3OsSeek(OsFile*, i64 offset);
int sqlite3OsSync(OsFile*);
int sqlite3OsTruncate(OsFile*, i64 size);
int sqlite3OsFileSize(OsFile*, i64 *pSize);
int sqlite3OsRandomSeed(char*);
int sqlite3OsSleep(int ms);
int sqlite3OsCurrentTime(double*);
int sqlite3OsFileModTime(OsFile*, double*);
void sqlite3OsEnterMutex(void);
void sqlite3OsLeaveMutex(void);
char *sqlite3OsFullPathname(const char*);
int sqlite3OsLock(OsFile*, int);
int sqlite3OsUnlock(OsFile*, int);
int sqlite3OsCheckReservedLock(OsFile *id);

#endif /* _SQLITE_OS_H_ */
Added SQLite.Interop/src/os_common.h.






















































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2004 May 22
**
** 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 file contains macros and a little bit of code that is common to
** all of the platform-specific files (os_*.c) and is #included into those
** files.
**
** This file should be #included by the os_*.c files only.  It is not a
** general purpose header file.
*/

/*
** At least two bugs have slipped in because we changed the MEMORY_DEBUG
** macro to SQLITE_DEBUG and some older makefiles have not yet made the
** switch.  The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG
# error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
#endif


int sqlite3_os_trace = 0;
#ifdef SQLITE_DEBUG
static int last_page = 0;
#define SEEK(X)           last_page=(X)
#define TRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
#define TRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
#define TRACE4(X,Y,Z,A)   if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
#define TRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
#define TRACE6(X,Y,Z,A,B,C) if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
#define TRACE7(X,Y,Z,A,B,C,D) \
    if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
#else
#define SEEK(X)
#define TRACE1(X)
#define TRACE2(X,Y)
#define TRACE3(X,Y,Z)
#define TRACE4(X,Y,Z,A)
#define TRACE5(X,Y,Z,A,B)
#define TRACE6(X,Y,Z,A,B,C)
#define TRACE7(X,Y,Z,A,B,C,D)
#endif

/*
** Macros for performance tracing.  Normally turned off.  Only works
** on i486 hardware.
*/
#ifdef SQLITE_PERFORMANCE_TRACE
__inline__ unsigned long long int hwtime(void){
  unsigned long long int x;
  __asm__("rdtsc\n\t"
          "mov %%edx, %%ecx\n\t"
          :"=A" (x));
  return x;
}
static unsigned long long int g_start;
static unsigned int elapse;
#define TIMER_START       g_start=hwtime()
#define TIMER_END         elapse=hwtime()-g_start
#define TIMER_ELAPSED     elapse
#else
#define TIMER_START
#define TIMER_END
#define TIMER_ELAPSED     0
#endif

/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error.  This
** is used for testing the I/O recovery logic.
*/
#ifdef SQLITE_TEST
int sqlite3_io_error_pending = 0;
int sqlite3_diskfull_pending = 0;
#define SimulateIOError(A)  \
   if( sqlite3_io_error_pending ) \
     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
static void local_ioerr(){
  sqlite3_io_error_pending = 0;  /* Really just a place to set a breakpoint */
}
#define SimulateDiskfullError \
   if( sqlite3_diskfull_pending ) \
     if( sqlite3_diskfull_pending-- == 1 ){ local_ioerr(); return SQLITE_FULL; }
#else
#define SimulateIOError(A)
#define SimulateDiskfullError
#endif

/*
** When testing, keep a count of the number of open files.
*/
#ifdef SQLITE_TEST
int sqlite3_open_file_count = 0;
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
#else
#define OpenCounter(X)
#endif
Added SQLite.Interop/src/os_unix.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
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
/*
** 2004 May 22
**
** 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 file contains code that is specific to Unix systems.
*/
#include "sqliteInt.h"
#include "os.h"
#if OS_UNIX              /* This file is used on unix only */


#include <time.h>
#include <errno.h>
#include <unistd.h>
#ifndef O_LARGEFILE
# define O_LARGEFILE 0
#endif
#ifdef SQLITE_DISABLE_LFS
# undef O_LARGEFILE
# define O_LARGEFILE 0
#endif
#ifndef O_NOFOLLOW
# define O_NOFOLLOW 0
#endif
#ifndef O_BINARY
# define O_BINARY 0
#endif


/*
** The DJGPP compiler environment looks mostly like Unix, but it
** lacks the fcntl() system call.  So redefine fcntl() to be something
** that always succeeds.  This means that locking does not occur under
** DJGPP.  But its DOS - what did you expect?
*/
#ifdef __DJGPP__
# define fcntl(A,B,C) 0
#endif

/*
** Macros used to determine whether or not to use threads.  The
** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for
** Posix threads and SQLITE_W32_THREADS is defined if we are
** synchronizing using Win32 threads.
*/
#if defined(THREADSAFE) && THREADSAFE
# include <pthread.h>
# define SQLITE_UNIX_THREADS 1
#endif


/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

#if defined(THREADSAFE) && THREADSAFE && defined(__linux__)
#define getpid pthread_self
#endif

/*
** Here is the dirt on POSIX advisory locks:  ANSI STD 1003.1 (1996)
** section 6.5.2.2 lines 483 through 490 specify that when a process
** sets or clears a lock, that operation overrides any prior locks set
** by the same process.  It does not explicitly say so, but this implies
** that it overrides locks set by the same process using a different
** file descriptor.  Consider this test case:
**
**       int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
**       int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
**
** Suppose ./file1 and ./file2 are really the same file (because
** one is a hard or symbolic link to the other) then if you set
** an exclusive lock on fd1, then try to get an exclusive lock
** on fd2, it works.  I would have expected the second lock to
** fail since there was already a lock on the file due to fd1.
** But not so.  Since both locks came from the same process, the
** second overrides the first, even though they were on different
** file descriptors opened on different file names.
**
** Bummer.  If you ask me, this is broken.  Badly broken.  It means
** that we cannot use POSIX locks to synchronize file access among
** competing threads of the same process.  POSIX locks will work fine
** to synchronize access for threads in separate processes, but not
** threads within the same process.
**
** To work around the problem, SQLite has to manage file locks internally
** on its own.  Whenever a new database is opened, we have to find the
** specific inode of the database file (the inode is determined by the
** st_dev and st_ino fields of the stat structure that fstat() fills in)
** and check for locks already existing on that inode.  When locks are
** created or removed, we have to look at our own internal record of the
** locks to see if another thread has previously set a lock on that same
** inode.
**
** The OsFile structure for POSIX is no longer just an integer file
** descriptor.  It is now a structure that holds the integer file
** descriptor and a pointer to a structure that describes the internal
** locks on the corresponding inode.  There is one locking structure
** per inode, so if the same inode is opened twice, both OsFile structures
** point to the same locking structure.  The locking structure keeps
** a reference count (so we will know when to delete it) and a "cnt"
** field that tells us its internal lock status.  cnt==0 means the
** file is unlocked.  cnt==-1 means the file has an exclusive lock.
** cnt>0 means there are cnt shared locks on the file.
**
** Any attempt to lock or unlock a file first checks the locking
** structure.  The fcntl() system call is only invoked to set a 
** POSIX lock if the internal lock structure transitions between
** a locked and an unlocked state.
**
** 2004-Jan-11:
** More recent discoveries about POSIX advisory locks.  (The more
** I discover, the more I realize the a POSIX advisory locks are
** an abomination.)
**
** If you close a file descriptor that points to a file that has locks,
** all locks on that file that are owned by the current process are
** released.  To work around this problem, each OsFile structure contains
** a pointer to an openCnt structure.  There is one openCnt structure
** per open inode, which means that multiple OsFiles can point to a single
** openCnt.  When an attempt is made to close an OsFile, if there are
** other OsFiles open on the same inode that are holding locks, the call
** to close() the file descriptor is deferred until all of the locks clear.
** The openCnt structure keeps a list of file descriptors that need to
** be closed and that list is walked (and cleared) when the last lock
** clears.
**
** First, under Linux threads, because each thread has a separate
** process ID, lock operations in one thread do not override locks
** to the same file in other threads.  Linux threads behave like
** separate processes in this respect.  But, if you close a file
** descriptor in linux threads, all locks are cleared, even locks
** on other threads and even though the other threads have different
** process IDs.  Linux threads is inconsistent in this respect.
** (I'm beginning to think that linux threads is an abomination too.)
** The consequence of this all is that the hash table for the lockInfo
** structure has to include the process id as part of its key because
** locks in different threads are treated as distinct.  But the 
** openCnt structure should not include the process id in its
** key because close() clears lock on all threads, not just the current
** thread.  Were it not for this goofiness in linux threads, we could
** combine the lockInfo and openCnt structures into a single structure.
**
** 2004-Jun-28:
** On some versions of linux, threads can override each others locks.
** On others not.  Sometimes you can change the behavior on the same
** system by setting the LD_ASSUME_KERNEL environment variable.  The
** POSIX standard is silent as to which behavior is correct, as far
** as I can tell, so other versions of unix might show the same
** inconsistency.  There is no little doubt in my mind that posix
** advisory locks and linux threads are profoundly broken.
**
** To work around the inconsistencies, we have to test at runtime 
** whether or not threads can override each others locks.  This test
** is run once, the first time any lock is attempted.  A static 
** variable is set to record the results of this test for future
** use.
*/

/*
** An instance of the following structure serves as the key used
** to locate a particular lockInfo structure given its inode.
**
** If threads cannot override each others locks, then we set the
** lockKey.tid field to the thread ID.  If threads can override
** each others locks then tid is always set to zero.  tid is also
** set to zero if we compile without threading support.
*/
struct lockKey {
  dev_t dev;       /* Device number */
  ino_t ino;       /* Inode number */
#ifdef SQLITE_UNIX_THREADS
  pthread_t tid;   /* Thread ID or zero if threads cannot override each other */
#endif
};

/*
** An instance of the following structure is allocated for each open
** inode on each thread with a different process ID.  (Threads have
** different process IDs on linux, but not on most other unixes.)
**
** A single inode can have multiple file descriptors, so each OsFile
** structure contains a pointer to an instance of this object and this
** object keeps a count of the number of OsFiles pointing to it.
*/
struct lockInfo {
  struct lockKey key;  /* The lookup key */
  int cnt;             /* Number of SHARED locks held */
  int locktype;        /* One of SHARED_LOCK, RESERVED_LOCK etc. */
  int nRef;            /* Number of pointers to this structure */
};

/*
** An instance of the following structure serves as the key used
** to locate a particular openCnt structure given its inode.  This
** is the same as the lockKey except that the thread ID is omitted.
*/
struct openKey {
  dev_t dev;   /* Device number */
  ino_t ino;   /* Inode number */
};

/*
** An instance of the following structure is allocated for each open
** inode.  This structure keeps track of the number of locks on that
** inode.  If a close is attempted against an inode that is holding
** locks, the close is deferred until all locks clear by adding the
** file descriptor to be closed to the pending list.
*/
struct openCnt {
  struct openKey key;   /* The lookup key */
  int nRef;             /* Number of pointers to this structure */
  int nLock;            /* Number of outstanding locks */
  int nPending;         /* Number of pending close() operations */
  int *aPending;        /* Malloced space holding fd's awaiting a close() */
};

/* 
** These hash table maps inodes and process IDs into lockInfo and openCnt
** structures.  Access to these hash tables must be protected by a mutex.
*/
static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };


#ifdef SQLITE_UNIX_THREADS
/*
** This variable records whether or not threads can override each others
** locks.
**
**    0:  No.  Threads cannot override each others locks.
**    1:  Yes.  Threads can override each others locks.
**   -1:  We don't know yet.
*/
static int threadsOverrideEachOthersLocks = -1;

/*
** This structure holds information passed into individual test
** threads by the testThreadLockingBehavior() routine.
*/
struct threadTestData {
  int fd;                /* File to be locked */
  struct flock lock;     /* The locking operation */
  int result;            /* Result of the locking operation */
};

/*
** The testThreadLockingBehavior() routine launches two separate
** threads on this routine.  This routine attempts to lock a file
** descriptor then returns.  The success or failure of that attempt
** allows the testThreadLockingBehavior() procedure to determine
** whether or not threads can override each others locks.
*/
static void *threadLockingTest(void *pArg){
  struct threadTestData *pData = (struct threadTestData*)pArg;
  pData->result = fcntl(pData->fd, F_SETLK, &pData->lock);
  return pArg;
}

/*
** This procedure attempts to determine whether or not threads
** can override each others locks then sets the 
** threadsOverrideEachOthersLocks variable appropriately.
*/
static void testThreadLockingBehavior(fd_orig){
  int fd;
  struct threadTestData d[2];
  pthread_t t[2];

  fd = dup(fd_orig);
  if( fd<0 ) return;
  memset(d, 0, sizeof(d));
  d[0].fd = fd;
  d[0].lock.l_type = F_RDLCK;
  d[0].lock.l_len = 1;
  d[0].lock.l_start = 0;
  d[0].lock.l_whence = SEEK_SET;
  d[1] = d[0];
  d[1].lock.l_type = F_WRLCK;
  pthread_create(&t[0], 0, threadLockingTest, &d[0]);
  pthread_create(&t[1], 0, threadLockingTest, &d[1]);
  pthread_join(t[0], 0);
  pthread_join(t[1], 0);
  close(fd);
  threadsOverrideEachOthersLocks =  d[0].result==0 && d[1].result==0;
}
#endif /* SQLITE_UNIX_THREADS */

/*
** Release a lockInfo structure previously allocated by findLockInfo().
*/
static void releaseLockInfo(struct lockInfo *pLock){
  pLock->nRef--;
  if( pLock->nRef==0 ){
    sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
    sqliteFree(pLock);
  }
}

/*
** Release a openCnt structure previously allocated by findLockInfo().
*/
static void releaseOpenCnt(struct openCnt *pOpen){
  pOpen->nRef--;
  if( pOpen->nRef==0 ){
    sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
    sqliteFree(pOpen->aPending);
    sqliteFree(pOpen);
  }
}

/*
** Given a file descriptor, locate lockInfo and openCnt structures that
** describes that file descriptor.  Create a new ones if necessary.  The
** return values might be unset if an error occurs.
**
** Return the number of errors.
*/
static int findLockInfo(
  int fd,                      /* The file descriptor used in the key */
  struct lockInfo **ppLock,    /* Return the lockInfo structure here */
  struct openCnt **ppOpen      /* Return the openCnt structure here */
){
  int rc;
  struct lockKey key1;
  struct openKey key2;
  struct stat statbuf;
  struct lockInfo *pLock;
  struct openCnt *pOpen;
  rc = fstat(fd, &statbuf);
  if( rc!=0 ) return 1;
  memset(&key1, 0, sizeof(key1));
  key1.dev = statbuf.st_dev;
  key1.ino = statbuf.st_ino;
#ifdef SQLITE_UNIX_THREADS
  if( threadsOverrideEachOthersLocks<0 ){
    testThreadLockingBehavior(fd);
  }
  key1.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
#endif
  memset(&key2, 0, sizeof(key2));
  key2.dev = statbuf.st_dev;
  key2.ino = statbuf.st_ino;
  pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
  if( pLock==0 ){
    struct lockInfo *pOld;
    pLock = sqliteMallocRaw( sizeof(*pLock) );
    if( pLock==0 ) return 1;
    pLock->key = key1;
    pLock->nRef = 1;
    pLock->cnt = 0;
    pLock->locktype = 0;
    pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
    if( pOld!=0 ){
      assert( pOld==pLock );
      sqliteFree(pLock);
      return 1;
    }
  }else{
    pLock->nRef++;
  }
  *ppLock = pLock;
  pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
  if( pOpen==0 ){
    struct openCnt *pOld;
    pOpen = sqliteMallocRaw( sizeof(*pOpen) );
    if( pOpen==0 ){
      releaseLockInfo(pLock);
      return 1;
    }
    pOpen->key = key2;
    pOpen->nRef = 1;
    pOpen->nLock = 0;
    pOpen->nPending = 0;
    pOpen->aPending = 0;
    pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
    if( pOld!=0 ){
      assert( pOld==pOpen );
      sqliteFree(pOpen);
      releaseLockInfo(pLock);
      return 1;
    }
  }else{
    pOpen->nRef++;
  }
  *ppOpen = pOpen;
  return 0;
}

/*
** Delete the named file
*/
int sqlite3OsDelete(const char *zFilename){
  unlink(zFilename);
  return SQLITE_OK;
}

/*
** Return TRUE if the named file exists.
*/
int sqlite3OsFileExists(const char *zFilename){
  return access(zFilename, 0)==0;
}

/*
** Attempt to open a file for both reading and writing.  If that
** fails, try opening it read-only.  If the file does not exist,
** try to create it.
**
** On success, a handle for the open file is written to *id
** and *pReadonly is set to 0 if the file was opened for reading and
** writing or 1 if the file was opened read-only.  The function returns
** SQLITE_OK.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id and *pReadonly unchanged.
*/
int sqlite3OsOpenReadWrite(
  const char *zFilename,
  OsFile *id,
  int *pReadonly
){
  int rc;
  assert( !id->isOpen );
  id->dirfd = -1;
  id->h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644);
  if( id->h<0 ){
#ifdef EISDIR
    if( errno==EISDIR ){
      return SQLITE_CANTOPEN;
    }
#endif
    id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
    if( id->h<0 ){
      return SQLITE_CANTOPEN; 
    }
    *pReadonly = 1;
  }else{
    *pReadonly = 0;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(id->h);
    return SQLITE_NOMEM;
  }
  id->locktype = 0;
  id->isOpen = 1;
  TRACE3("OPEN    %-3d %s\n", id->h, zFilename);
  OpenCounter(+1);
  return SQLITE_OK;
}


/*
** Attempt to open a new file for exclusive access by this process.
** The file will be opened for both reading and writing.  To avoid
** a potential security problem, we do not allow the file to have
** previously existed.  Nor do we allow the file to be a symbolic
** link.
**
** If delFlag is true, then make arrangements to automatically delete
** the file when it is closed.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
  int rc;
  assert( !id->isOpen );
  if( access(zFilename, 0)==0 ){
    return SQLITE_CANTOPEN;
  }
  id->dirfd = -1;
  id->h = open(zFilename,
                O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600);
  if( id->h<0 ){
    return SQLITE_CANTOPEN;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(id->h);
    unlink(zFilename);
    return SQLITE_NOMEM;
  }
  id->locktype = 0;
  id->isOpen = 1;
  if( delFlag ){
    unlink(zFilename);
  }
  TRACE3("OPEN-EX %-3d %s\n", id->h, zFilename);
  OpenCounter(+1);
  return SQLITE_OK;
}

/*
** Attempt to open a new file for read-only access.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
  int rc;
  assert( !id->isOpen );
  id->dirfd = -1;
  id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
  if( id->h<0 ){
    return SQLITE_CANTOPEN;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(id->h);
    return SQLITE_NOMEM;
  }
  id->locktype = 0;
  id->isOpen = 1;
  TRACE3("OPEN-RO %-3d %s\n", id->h, zFilename);
  OpenCounter(+1);
  return SQLITE_OK;
}

/*
** Attempt to open a file descriptor for the directory that contains a
** file.  This file descriptor can be used to fsync() the directory
** in order to make sure the creation of a new file is actually written
** to disk.
**
** This routine is only meaningful for Unix.  It is a no-op under
** windows since windows does not support hard links.
**
** On success, a handle for a previously open file is at *id is
** updated with the new directory file descriptor and SQLITE_OK is
** returned.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id unchanged.
*/
int sqlite3OsOpenDirectory(
  const char *zDirname,
  OsFile *id
){
  if( !id->isOpen ){
    /* Do not open the directory if the corresponding file is not already
    ** open. */
    return SQLITE_CANTOPEN;
  }
  assert( id->dirfd<0 );
  id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644);
  if( id->dirfd<0 ){
    return SQLITE_CANTOPEN; 
  }
  TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
  return SQLITE_OK;
}

/*
** If the following global variable points to a string which is the
** name of a directory, then that directory will be used to store
** temporary files.
*/
char *sqlite3_temp_directory = 0;

/*
** Create a temporary file name in zBuf.  zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
*/
int sqlite3OsTempFileName(char *zBuf){
  static const char *azDirs[] = {
     0,
     "/var/tmp",
     "/usr/tmp",
     "/tmp",
     ".",
  };
  static const unsigned char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  int i, j;
  struct stat buf;
  const char *zDir = ".";
  azDirs[0] = sqlite3_temp_directory;
  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
    if( azDirs[i]==0 ) continue;
    if( stat(azDirs[i], &buf) ) continue;
    if( !S_ISDIR(buf.st_mode) ) continue;
    if( access(azDirs[i], 07) ) continue;
    zDir = azDirs[i];
    break;
  }
  do{
    sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
    j = strlen(zBuf);
    sqlite3Randomness(15, &zBuf[j]);
    for(i=0; i<15; i++, j++){
      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
    }
    zBuf[j] = 0;
  }while( access(zBuf,0)==0 );
  return SQLITE_OK; 
}

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Check that a given pathname is a directory and is writable 
**
*/
int sqlite3OsIsDirWritable(char *zBuf){
  struct stat buf;
  if( zBuf==0 ) return 0;
  if( zBuf[0]==0 ) return 0;
  if( stat(zBuf, &buf) ) return 0;
  if( !S_ISDIR(buf.st_mode) ) return 0;
  if( access(zBuf, 07) ) return 0;
  return 1;
}
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
*/
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
  int got;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  TIMER_START;
  got = read(id->h, pBuf, amt);
  TIMER_END;
  TRACE4("READ    %-3d %7d %d\n", id->h, last_page, TIMER_ELAPSED);
  SEEK(0);
  /* if( got<0 ) got = 0; */
  if( got==amt ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
  int wrote = 0;
  assert( id->isOpen );
  assert( amt>0 );
  SimulateIOError(SQLITE_IOERR);
  SimulateDiskfullError;
  TIMER_START;
  while( amt>0 && (wrote = write(id->h, pBuf, amt))>0 ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  TIMER_END;
  TRACE4("WRITE   %-3d %7d %d\n", id->h, last_page, TIMER_ELAPSED);
  SEEK(0);
  if( amt>0 ){
    return SQLITE_FULL;
  }
  return SQLITE_OK;
}

/*
** Move the read/write pointer in a file.
*/
int sqlite3OsSeek(OsFile *id, i64 offset){
  assert( id->isOpen );
  SEEK(offset/1024 + 1);
  lseek(id->h, offset, SEEK_SET);
  return SQLITE_OK;
}

/*
** The fsync() system call does not work as advertised on many
** unix systems.  The following procedure is an attempt to make
** it work better.
**
** The SQLITE_NO_SYNC macro disables all fsync()s.  This is useful
** for testing when we want to run through the test suite quickly.
** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
** or power failure will likely corrupt the database file.
*/
static int full_fsync(int fd){
#ifdef SQLITE_NO_SYNC
  return SQLITE_OK;
#else
  int rc;
#ifdef F_FULLFSYNC
  rc = fcntl(fd, F_FULLFSYNC, 0);
  if( rc ) rc = fsync(fd);
#else
  rc = fsync(fd);
#endif
  return rc;
#endif
}

/*
** Make sure all writes to a particular file are committed to disk.
**
** Under Unix, also make sure that the directory entry for the file
** has been created by fsync-ing the directory that contains the file.
** If we do not do this and we encounter a power failure, the directory
** entry for the journal might not exist after we reboot.  The next
** SQLite to access the file will not know that the journal exists (because
** the directory entry for the journal was never created) and the transaction
** will not roll back - possibly leading to database corruption.
*/
int sqlite3OsSync(OsFile *id){
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  TRACE2("SYNC    %-3d\n", id->h);
  if( full_fsync(id->h) ){
    return SQLITE_IOERR;
  }
  if( id->dirfd>=0 ){
    TRACE2("DIRSYNC %-3d\n", id->dirfd);
    full_fsync(id->dirfd);
    close(id->dirfd);  /* Only need to sync once, so close the directory */
    id->dirfd = -1;    /* when we are done. */
  }
  return SQLITE_OK;
}

/*
** Sync the directory zDirname. This is a no-op on operating systems other
** than UNIX.
*/
int sqlite3OsSyncDirectory(const char *zDirname){
  int fd;
  int r;
  SimulateIOError(SQLITE_IOERR);
  fd = open(zDirname, O_RDONLY|O_BINARY, 0644);
  TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
  if( fd<0 ){
    return SQLITE_CANTOPEN; 
  }
  r = fsync(fd);
  close(fd);
  return ((r==0)?SQLITE_OK:SQLITE_IOERR);
}

/*
** Truncate an open file to a specified size
*/
int sqlite3OsTruncate(OsFile *id, i64 nByte){
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  return ftruncate(id->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
}

/*
** Determine the current size of a file in bytes
*/
int sqlite3OsFileSize(OsFile *id, i64 *pSize){
  struct stat buf;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  if( fstat(id->h, &buf)!=0 ){
    return SQLITE_IOERR;
  }
  *pSize = buf.st_size;
  return SQLITE_OK;
}

/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, return
** non-zero.  If the file is unlocked or holds only SHARED locks, then
** return zero.
*/
int sqlite3OsCheckReservedLock(OsFile *id){
  int r = 0;

  assert( id->isOpen );
  sqlite3OsEnterMutex(); /* Needed because id->pLock is shared across threads */

  /* Check if a thread in this process holds such a lock */
  if( id->pLock->locktype>SHARED_LOCK ){
    r = 1;
  }

  /* Otherwise see if some other process holds it.
  */
  if( !r ){
    struct flock lock;
    lock.l_whence = SEEK_SET;
    lock.l_start = RESERVED_BYTE;
    lock.l_len = 1;
    lock.l_type = F_WRLCK;
    fcntl(id->h, F_GETLK, &lock);
    if( lock.l_type!=F_UNLCK ){
      r = 1;
    }
  }
  
  sqlite3OsLeaveMutex();
  TRACE3("TEST WR-LOCK %d %d\n", id->h, r);

  return r;
}

#ifdef SQLITE_DEBUG
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string represetation of the supplied
** integer lock-type.
*/
static const char * locktypeName(int locktype){
  switch( locktype ){
  case NO_LOCK: return "NONE";
  case SHARED_LOCK: return "SHARED";
  case RESERVED_LOCK: return "RESERVED";
  case PENDING_LOCK: return "PENDING";
  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
  }
  return "ERROR";
}
#endif

/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
**     (4) EXCLUSIVE_LOCK
**
** Sometimes when requesting one lock state, additional lock states
** are inserted in between.  The locking might fail on one of the later
** transitions leaving the lock state different from what it started but
** still short of its goal.  The following chart shows the allowed
** transitions and the inserted intermediate states:
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  Use the sqlite3OsUnlock()
** routine to lower a locking level.
*/
int sqlite3OsLock(OsFile *id, int locktype){
  /* The following describes the implementation of the various locks and
  ** lock transitions in terms of the POSIX advisory shared and exclusive
  ** lock primitives (called read-locks and write-locks below, to avoid
  ** confusion with SQLite lock names). The algorithms are complicated
  ** slightly in order to be compatible with windows systems simultaneously
  ** accessing the same database file, in case that is ever required.
  **
  ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
  ** byte', each single bytes at well known offsets, and the 'shared byte
  ** range', a range of 510 bytes at a well known offset.
  **
  ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
  ** byte'.  If this is successful, a random byte from the 'shared byte
  ** range' is read-locked and the lock on the 'pending byte' released.
  **
  ** A process may only obtain a RESERVED lock after it has a SHARED lock.
  ** A RESERVED lock is implemented by grabbing a write-lock on the
  ** 'reserved byte'. 
  **
  ** A process may only obtain a PENDING lock after it has obtained a
  ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock
  ** on the 'pending byte'. This ensures that no new SHARED locks can be
  ** obtained, but existing SHARED locks are allowed to persist. A process
  ** does not have to obtain a RESERVED lock on the way to a PENDING lock.
  ** This property is used by the algorithm for rolling back a journal file
  ** after a crash.
  **
  ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is
  ** implemented by obtaining a write-lock on the entire 'shared byte
  ** range'. Since all other locks require a read-lock on one of the bytes
  ** within this range, this ensures that no other locks are held on the
  ** database. 
  **
  ** The reason a single byte cannot be used instead of the 'shared byte
  ** range' is that some versions of windows do not support read-locks. By
  ** locking a random byte from a range, concurrent SHARED locks may exist
  ** even if the locking primitive used is always a write-lock.
  */
  int rc = SQLITE_OK;
  struct lockInfo *pLock = id->pLock;
  struct flock lock;
  int s;

  assert( id->isOpen );
  TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), 
      locktypeName(id->locktype), locktypeName(pLock->locktype), pLock->cnt
      ,getpid() );

  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( id->locktype>=locktype ){
    TRACE3("LOCK %d %s ok (already held)\n", id->h, locktypeName(locktype));
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );

  /* This mutex is needed because id->pLock is shared across threads
  */
  sqlite3OsEnterMutex();

  /* If some thread using this PID has a lock via a different OsFile*
  ** handle that precludes the requested lock, return BUSY.
  */
  if( (id->locktype!=pLock->locktype && 
          (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK))
  ){
    rc = SQLITE_BUSY;
    goto end_lock;
  }

  /* If a SHARED lock is requested, and some thread using this PID already
  ** has a SHARED or RESERVED lock, then increment reference counts and
  ** return SQLITE_OK.
  */
  if( locktype==SHARED_LOCK && 
      (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
    assert( locktype==SHARED_LOCK );
    assert( id->locktype==0 );
    assert( pLock->cnt>0 );
    id->locktype = SHARED_LOCK;
    pLock->cnt++;
    id->pOpen->nLock++;
    goto end_lock;
  }

  lock.l_len = 1L;
  lock.l_whence = SEEK_SET;

  /* A PENDING lock is needed before acquiring a SHARED lock and before
  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
  ** be released.
  */
  if( locktype==SHARED_LOCK 
      || (locktype==EXCLUSIVE_LOCK && id->locktype<PENDING_LOCK)
  ){
    lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
    lock.l_start = PENDING_BYTE;
    s = fcntl(id->h, F_SETLK, &lock);
    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
      goto end_lock;
    }
  }


  /* If control gets to this point, then actually go ahead and make
  ** operating system calls for the specified lock.
  */
  if( locktype==SHARED_LOCK ){
    assert( pLock->cnt==0 );
    assert( pLock->locktype==0 );

    /* Now get the read-lock */
    lock.l_start = SHARED_FIRST;
    lock.l_len = SHARED_SIZE;
    s = fcntl(id->h, F_SETLK, &lock);

    /* Drop the temporary PENDING lock */
    lock.l_start = PENDING_BYTE;
    lock.l_len = 1L;
    lock.l_type = F_UNLCK;
    fcntl(id->h, F_SETLK, &lock);
    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
    }else{
      id->locktype = SHARED_LOCK;
      id->pOpen->nLock++;
      pLock->cnt = 1;
    }
  }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){
    /* We are trying for an exclusive lock but another thread in this
    ** same process is still holding a shared lock. */
    rc = SQLITE_BUSY;
  }else{
    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
    ** assumed that there is a SHARED or greater lock on the file
    ** already.
    */
    assert( 0!=id->locktype );
    lock.l_type = F_WRLCK;
    switch( locktype ){
      case RESERVED_LOCK:
        lock.l_start = RESERVED_BYTE;
        break;
      case EXCLUSIVE_LOCK:
        lock.l_start = SHARED_FIRST;
        lock.l_len = SHARED_SIZE;
        break;
      default:
        assert(0);
    }
    s = fcntl(id->h, F_SETLK, &lock);
    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
    }
  }
  
  if( rc==SQLITE_OK ){
    id->locktype = locktype;
    pLock->locktype = locktype;
  }else if( locktype==EXCLUSIVE_LOCK ){
    id->locktype = PENDING_LOCK;
    pLock->locktype = PENDING_LOCK;
  }

end_lock:
  sqlite3OsLeaveMutex();
  TRACE4("LOCK %d %s %s\n", id->h, locktypeName(locktype), 
      rc==SQLITE_OK ? "ok" : "failed");
  return rc;
}

/*
** Lower the locking level on file descriptor id to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
**
** It is not possible for this routine to fail if the second argument
** is NO_LOCK.  If the second argument is SHARED_LOCK, this routine
** might return SQLITE_IOERR instead of SQLITE_OK.
*/
int sqlite3OsUnlock(OsFile *id, int locktype){
  struct lockInfo *pLock;
  struct flock lock;
  int rc = SQLITE_OK;

  assert( id->isOpen );
  TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, 
      id->pLock->locktype, id->pLock->cnt, getpid());

  assert( locktype<=SHARED_LOCK );
  if( id->locktype<=locktype ){
    return SQLITE_OK;
  }
  sqlite3OsEnterMutex();
  pLock = id->pLock;
  assert( pLock->cnt!=0 );
  if( id->locktype>SHARED_LOCK ){
    assert( pLock->locktype==id->locktype );
    if( locktype==SHARED_LOCK ){
      lock.l_type = F_RDLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = SHARED_FIRST;
      lock.l_len = SHARED_SIZE;
      if( fcntl(id->h, F_SETLK, &lock)!=0 ){
        /* This should never happen */
        rc = SQLITE_IOERR;
      }
    }
    lock.l_type = F_UNLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = PENDING_BYTE;
    lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
    fcntl(id->h, F_SETLK, &lock);
    pLock->locktype = SHARED_LOCK;
  }
  if( locktype==NO_LOCK ){
    struct openCnt *pOpen;

    /* Decrement the shared lock counter.  Release the lock using an
    ** OS call only when all threads in this same process have released
    ** the lock.
    */
    pLock->cnt--;
    if( pLock->cnt==0 ){
      lock.l_type = F_UNLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = lock.l_len = 0L;
      fcntl(id->h, F_SETLK, &lock);
      pLock->locktype = NO_LOCK;
    }

    /* Decrement the count of locks against this same file.  When the
    ** count reaches zero, close any other file descriptors whose close
    ** was deferred because of outstanding locks.
    */
    pOpen = id->pOpen;
    pOpen->nLock--;
    assert( pOpen->nLock>=0 );
    if( pOpen->nLock==0 && pOpen->nPending>0 ){
      int i;
      for(i=0; i<pOpen->nPending; i++){
        close(pOpen->aPending[i]);
      }
      sqliteFree(pOpen->aPending);
      pOpen->nPending = 0;
      pOpen->aPending = 0;
    }
  }
  sqlite3OsLeaveMutex();
  id->locktype = locktype;
  return rc;
}

/*
** Close a file.
*/
int sqlite3OsClose(OsFile *id){
  if( !id->isOpen ) return SQLITE_OK;
  sqlite3OsUnlock(id, NO_LOCK);
  if( id->dirfd>=0 ) close(id->dirfd);
  id->dirfd = -1;
  sqlite3OsEnterMutex();
  if( id->pOpen->nLock ){
    /* If there are outstanding locks, do not actually close the file just
    ** yet because that would clear those locks.  Instead, add the file
    ** descriptor to pOpen->aPending.  It will be automatically closed when
    ** the last lock is cleared.
    */
    int *aNew;
    struct openCnt *pOpen = id->pOpen;
    pOpen->nPending++;
    aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) );
    if( aNew==0 ){
      /* If a malloc fails, just leak the file descriptor */
    }else{
      pOpen->aPending = aNew;
      pOpen->aPending[pOpen->nPending-1] = id->h;
    }
  }else{
    /* There are no outstanding locks so we can close the file immediately */
    close(id->h);
  }
  releaseLockInfo(id->pLock);
  releaseOpenCnt(id->pOpen);
  sqlite3OsLeaveMutex();
  id->isOpen = 0;
  TRACE2("CLOSE   %-3d\n", id->h);
  OpenCounter(-1);
  return SQLITE_OK;
}

/*
** Get information to seed the random number generator.  The seed
** is written into the buffer zBuf[256].  The calling function must
** supply a sufficiently large buffer.
*/
int sqlite3OsRandomSeed(char *zBuf){
  /* We have to initialize zBuf to prevent valgrind from reporting
  ** errors.  The reports issued by valgrind are incorrect - we would
  ** prefer that the randomness be increased by making use of the
  ** uninitialized space in zBuf - but valgrind errors tend to worry
  ** some users.  Rather than argue, it seems easier just to initialize
  ** the whole array and silence valgrind, even if that means less randomness
  ** in the random seed.
  **
  ** When testing, initializing zBuf[] to zero is all we do.  That means
  ** that we always use the same random number sequence.* This makes the
  ** tests repeatable.
  */
  memset(zBuf, 0, 256);
#if !defined(SQLITE_TEST)
  {
    int pid, fd;
    fd = open("/dev/urandom", O_RDONLY);
    if( fd<0 ){
      time((time_t*)zBuf);
      pid = getpid();
      memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
    }else{
      read(fd, zBuf, 256);
      close(fd);
    }
  }
#endif
  return SQLITE_OK;
}

/*
** Sleep for a little while.  Return the amount of time slept.
*/
int sqlite3OsSleep(int ms){
#if defined(HAVE_USLEEP) && HAVE_USLEEP
  usleep(ms*1000);
  return ms;
#else
  sleep((ms+999)/1000);
  return 1000*((ms+999)/1000);
#endif
}

/*
** Static variables used for thread synchronization
*/
static int inMutex = 0;
#ifdef SQLITE_UNIX_THREADS
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#endif

/*
** The following pair of routine implement mutual exclusion for
** multi-threaded processes.  Only a single thread is allowed to
** executed code that is surrounded by EnterMutex() and LeaveMutex().
**
** SQLite uses only a single Mutex.  There is not much critical
** code and what little there is executes quickly and without blocking.
*/
void sqlite3OsEnterMutex(){
#ifdef SQLITE_UNIX_THREADS
  pthread_mutex_lock(&mutex);
#endif
  assert( !inMutex );
  inMutex = 1;
}
void sqlite3OsLeaveMutex(){
  assert( inMutex );
  inMutex = 0;
#ifdef SQLITE_UNIX_THREADS
  pthread_mutex_unlock(&mutex);
#endif
}

/*
** Turn a relative pathname into a full pathname.  Return a pointer
** to the full pathname stored in space obtained from sqliteMalloc().
** The calling function is responsible for freeing this space once it
** is no longer needed.
*/
char *sqlite3OsFullPathname(const char *zRelative){
  char *zFull = 0;
  if( zRelative[0]=='/' ){
    sqlite3SetString(&zFull, zRelative, (char*)0);
  }else{
    char zBuf[5000];
    sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
                    (char*)0);
  }
  return zFull;
}

/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime().  This is used for testing.
*/
#ifdef SQLITE_TEST
int sqlite3_current_time = 0;
#endif

/*
** Find the current time (in Universal Coordinated Time).  Write the
** current time and date as a Julian Day number into *prNow and
** return 0.  Return 1 if the time and date cannot be found.
*/
int sqlite3OsCurrentTime(double *prNow){
  time_t t;
  time(&t);
  *prNow = t/86400.0 + 2440587.5;
#ifdef SQLITE_TEST
  if( sqlite3_current_time ){
    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
  }
#endif
  return 0;
}

#if 0 /* NOT USED */
/*
** Find the time that the file was last modified.  Write the
** modification time and date as a Julian Day number into *prNow and
** return SQLITE_OK.  Return SQLITE_ERROR if the modification
** time cannot be found.
*/
int sqlite3OsFileModTime(OsFile *id, double *prNow){
  int rc;
  struct stat statbuf;
  if( fstat(id->h, &statbuf)==0 ){
    *prNow = statbuf.st_mtime/86400.0 + 2440587.5;
    rc = SQLITE_OK;
  }else{
    rc = SQLITE_ERROR;
  }
  return rc;
}
#endif /* NOT USED */

#endif /* OS_UNIX */
Added SQLite.Interop/src/os_unix.h.


















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2004 May 22
**
** 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 header file defined OS-specific features for Unix.
*/
#ifndef _SQLITE_OS_UNIX_H_
#define _SQLITE_OS_UNIX_H_

/*
** Helpful hint:  To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
** to the compiler command line.
*/

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line.  This is necessary if you are compiling
** on a recent machine (ex: RedHat 7.2) but you want your code to work
** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
** without this option, LFS is enable.  But LFS does not exist in the kernel
** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
** portability you should omit LFS.
**
** Similar is true for MacOS.  LFS is only supported on MacOS 9 and later.
*/
#ifndef SQLITE_DISABLE_LFS
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif

/*
** standard include files.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/*
** The OsFile structure is a operating-system independing representation
** of an open file handle.  It is defined differently for each architecture.
**
** This is the definition for Unix.
**
** OsFile.locktype takes one of the values SHARED_LOCK, RESERVED_LOCK,
** PENDING_LOCK or EXCLUSIVE_LOCK.
*/
typedef struct OsFile OsFile;
struct OsFile {
  struct Pager *pPager;     /* The pager that owns this OsFile.  Might be 0 */
  struct openCnt *pOpen;    /* Info about all open fd's on this inode */
  struct lockInfo *pLock;   /* Info about locks on this inode */
  int h;                    /* The file descriptor */
  unsigned char locktype;   /* The type of lock held on this fd */
  unsigned char isOpen;     /* True if needs to be closed */
  int dirfd;                /* File descriptor for the directory */
};

/*
** Maximum number of characters in a temporary file name
*/
#define SQLITE_TEMPNAME_SIZE 200

/*
** Minimum interval supported by sqlite3OsSleep().
*/
#if defined(HAVE_USLEEP) && HAVE_USLEEP
# define SQLITE_MIN_SLEEP_MS 1
#else
# define SQLITE_MIN_SLEEP_MS 1000
#endif


#endif /* _SQLITE_OS_UNIX_H_ */
Added SQLite.Interop/src/os_win.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
761
762
763
764
765
766
/*
** 2004 May 22
**
** 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 file contains code that is specific to windows.
*/
#include "sqliteInt.h"
#include "os.h"
#if OS_WIN               /* This file is used for windows only */

#include <winbase.h>

/*
** Macros used to determine whether or not to use threads.
*/
#if defined(THREADSAFE) && THREADSAFE
# define SQLITE_W32_THREADS 1
#endif

/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

/*
** Delete the named file
*/
int sqlite3OsDelete(const char *zFilename){
  DeleteFileA(zFilename);
  TRACE2("DELETE \"%s\"\n", zFilename);
  return SQLITE_OK;
}

/*
** Return TRUE if the named file exists.
*/
int sqlite3OsFileExists(const char *zFilename){
  return GetFileAttributesA(zFilename) != 0xffffffff;
}

/*
** Attempt to open a file for both reading and writing.  If that
** fails, try opening it read-only.  If the file does not exist,
** try to create it.
**
** On success, a handle for the open file is written to *id
** and *pReadonly is set to 0 if the file was opened for reading and
** writing or 1 if the file was opened read-only.  The function returns
** SQLITE_OK.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id and *pReadonly unchanged.
*/
int sqlite3OsOpenReadWrite(
  const char *zFilename,
  OsFile *id,
  int *pReadonly
){
  HANDLE h;
  assert( !id->isOpen );
  h = CreateFileA(zFilename,
     GENERIC_READ | GENERIC_WRITE,
     FILE_SHARE_READ | FILE_SHARE_WRITE,
     NULL,
     OPEN_ALWAYS,
     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
     NULL
  );
  if( h==INVALID_HANDLE_VALUE ){
    h = CreateFileA(zFilename,
       GENERIC_READ,
       FILE_SHARE_READ,
       NULL,
       OPEN_ALWAYS,
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
       NULL
    );
    if( h==INVALID_HANDLE_VALUE ){
      return SQLITE_CANTOPEN;
    }
    *pReadonly = 1;
  }else{
    *pReadonly = 0;
  }
  id->h = h;
  id->locktype = NO_LOCK;
  id->sharedLockByte = 0;
  id->isOpen = 1;
  OpenCounter(+1);
  TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
  return SQLITE_OK;
}


/*
** Attempt to open a new file for exclusive access by this process.
** The file will be opened for both reading and writing.  To avoid
** a potential security problem, we do not allow the file to have
** previously existed.  Nor do we allow the file to be a symbolic
** link.
**
** If delFlag is true, then make arrangements to automatically delete
** the file when it is closed.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
  HANDLE h;
  int fileflags;
  assert( !id->isOpen );
  if( delFlag ){
    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
                     | FILE_FLAG_DELETE_ON_CLOSE;
  }else{
    fileflags = FILE_FLAG_RANDOM_ACCESS;
  }
  h = CreateFileA(zFilename,
     GENERIC_READ | GENERIC_WRITE,
     0,
     NULL,
     CREATE_ALWAYS,
     fileflags,
     NULL
  );
  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  id->h = h;
  id->locktype = NO_LOCK;
  id->sharedLockByte = 0;
  id->isOpen = 1;
  OpenCounter(+1);
  TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
  return SQLITE_OK;
}

/*
** Attempt to open a new file for read-only access.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
  HANDLE h;
  assert( !id->isOpen );
  h = CreateFileA(zFilename,
     GENERIC_READ,
     0,
     NULL,
     OPEN_EXISTING,
     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
     NULL
  );
  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  id->h = h;
  id->locktype = NO_LOCK;
  id->sharedLockByte = 0;
  id->isOpen = 1;
  OpenCounter(+1);
  TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
  return SQLITE_OK;
}

/*
** Attempt to open a file descriptor for the directory that contains a
** file.  This file descriptor can be used to fsync() the directory
** in order to make sure the creation of a new file is actually written
** to disk.
**
** This routine is only meaningful for Unix.  It is a no-op under
** windows since windows does not support hard links.
**
** On success, a handle for a previously open file is at *id is
** updated with the new directory file descriptor and SQLITE_OK is
** returned.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id unchanged.
*/
int sqlite3OsOpenDirectory(
  const char *zDirname,
  OsFile *id
){
  return SQLITE_OK;
}

/*
** If the following global variable points to a string which is the
** name of a directory, then that directory will be used to store
** temporary files.
*/
char *sqlite3_temp_directory = 0;

/*
** Create a temporary file name in zBuf.  zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
*/
int sqlite3OsTempFileName(char *zBuf){
  static char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  int i, j;
  char zTempPath[SQLITE_TEMPNAME_SIZE];
  if( sqlite3_temp_directory ){
    strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
    zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
  }else{
    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
  }
  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
  zTempPath[i] = 0;
  for(;;){
    sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
    j = strlen(zBuf);
    sqlite3Randomness(15, &zBuf[j]);
    for(i=0; i<15; i++, j++){
      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
    }
    zBuf[j] = 0;
    if( !sqlite3OsFileExists(zBuf) ) break;
  }
  TRACE2("TEMP FILENAME: %s\n", zBuf);
  return SQLITE_OK; 
}

/*
** Close a file.
*/
int sqlite3OsClose(OsFile *id){
  if( id->isOpen ){
    TRACE2("CLOSE %d\n", id->h);
    CloseHandle(id->h);
    OpenCounter(-1);
    id->isOpen = 0;
  }
  return SQLITE_OK;
}

/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
*/
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
  DWORD got;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  TRACE3("READ %d lock=%d\n", id->h, id->locktype);
  if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
    got = 0;
  }
  if( got==(DWORD)amt ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
  int rc = 0;
  DWORD wrote;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  SimulateDiskfullError;
  TRACE3("WRITE %d lock=%d\n", id->h, id->locktype);
  assert( amt>0 );
  while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  if( !rc || amt>(int)wrote ){
    return SQLITE_FULL;
  }
  return SQLITE_OK;
}

/*
** Move the read/write pointer in a file.
*/
int sqlite3OsSeek(OsFile *id, i64 offset){
  LONG upperBits = offset>>32;
  LONG lowerBits = offset & 0xffffffff;
  DWORD rc;
  assert( id->isOpen );
  SEEK(offset/1024 + 1);
  rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
  TRACE3("SEEK %d %lld\n", id->h, offset);
  return SQLITE_OK;
}

/*
** Make sure all writes to a particular file are committed to disk.
*/
int sqlite3OsSync(OsFile *id){
  assert( id->isOpen );
  TRACE3("SYNC %d lock=%d\n", id->h, id->locktype);
  if( FlushFileBuffers(id->h) ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Sync the directory zDirname. This is a no-op on operating systems other
** than UNIX.
*/
int sqlite3OsSyncDirectory(const char *zDirname){
  SimulateIOError(SQLITE_IOERR);
  return SQLITE_OK;
}

/*
** Truncate an open file to a specified size
*/
int sqlite3OsTruncate(OsFile *id, i64 nByte){
  LONG upperBits = nByte>>32;
  assert( id->isOpen );
  TRACE3("TRUNCATE %d %lld\n", id->h, nByte);
  SimulateIOError(SQLITE_IOERR);
  SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
  SetEndOfFile(id->h);
  return SQLITE_OK;
}

/*
** Determine the current size of a file in bytes
*/
int sqlite3OsFileSize(OsFile *id, i64 *pSize){
  DWORD upperBits, lowerBits;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  lowerBits = GetFileSize(id->h, &upperBits);
  *pSize = (((i64)upperBits)<<32) + lowerBits;
  return SQLITE_OK;
}

/*
** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
** Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation:  Win95, Win98, and WinME lack
** the LockFileEx() API.  But we can still statically link against that
** API as long as we don't call it win running Win95/98/ME.  A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
static int isNT(void){
  static int osType = 0;   /* 0=unknown 1=win95 2=winNT */
  if( osType==0 ){
    OSVERSIONINFO sInfo;
    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
    GetVersionEx(&sInfo);
    osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
  }
  return osType==2;
}

/*
** Acquire a reader lock.
** Different API routines are called depending on whether or not this
** is Win95 or WinNT.
*/
static int getReadLock(OsFile *id){
  int res;
  if( isNT() ){
    OVERLAPPED ovlp;
    ovlp.Offset = SHARED_FIRST;
    ovlp.OffsetHigh = 0;
    ovlp.hEvent = 0;
    res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
  }else{
    int lk;
    sqlite3Randomness(sizeof(lk), &lk);
    id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
    res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
  }
  return res;
}

/*
** Undo a readlock
*/
static int unlockReadLock(OsFile *id){
  int res;
  if( isNT() ){
    res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  }else{
    res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
  }
  return res;
}

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Check that a given pathname is a directory and is writable 
**
*/
int sqlite3OsIsDirWritable(char *zBuf){
  int fileAttr;
  if(! zBuf ) return 0;
  if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0;
  fileAttr = GetFileAttributesA(zBuf);
  if( fileAttr == 0xffffffff ) return 0;
  if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
    return 0;
  }
  return 1;
}
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
**     (4) EXCLUSIVE_LOCK
**
** Sometimes when requesting one lock state, additional lock states
** are inserted in between.  The locking might fail on one of the later
** transitions leaving the lock state different from what it started but
** still short of its goal.  The following chart shows the allowed
** transitions and the inserted intermediate states:
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  The sqlite3OsUnlock() routine
** erases all locks at once and returns us immediately to locking level 0.
** It is not possible to lower the locking level one step at a time.  You
** must go straight to locking level 0.
*/
int sqlite3OsLock(OsFile *id, int locktype){
  int rc = SQLITE_OK;    /* Return code from subroutines */
  int res = 1;           /* Result of a windows lock call */
  int newLocktype;       /* Set id->locktype to this value before exiting */
  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */

  assert( id->isOpen );
  TRACE5("LOCK %d %d was %d(%d)\n",
          id->h, locktype, id->locktype, id->sharedLockByte);

  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( id->locktype>=locktype ){
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );

  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
  ** the PENDING_LOCK byte is temporary.
  */
  newLocktype = id->locktype;
  if( id->locktype==NO_LOCK
   || (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK)
  ){
    int cnt = 3;
    while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){
      /* Try 3 times to get the pending lock.  The pending lock might be
      ** held by another reader process who will release it momentarily.
      */
      TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
      Sleep(1);
    }
    gotPendingLock = res;
  }

  /* Acquire a shared lock
  */
  if( locktype==SHARED_LOCK && res ){
    assert( id->locktype==NO_LOCK );
    res = getReadLock(id);
    if( res ){
      newLocktype = SHARED_LOCK;
    }
  }

  /* Acquire a RESERVED lock
  */
  if( locktype==RESERVED_LOCK && res ){
    assert( id->locktype==SHARED_LOCK );
    res = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
    if( res ){
      newLocktype = RESERVED_LOCK;
    }
  }

  /* Acquire a PENDING lock
  */
  if( locktype==EXCLUSIVE_LOCK && res ){
    newLocktype = PENDING_LOCK;
    gotPendingLock = 0;
  }

  /* Acquire an EXCLUSIVE lock
  */
  if( locktype==EXCLUSIVE_LOCK && res ){
    assert( id->locktype>=SHARED_LOCK );
    res = unlockReadLock(id);
    TRACE2("unreadlock = %d\n", res);
    res = LockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
    if( res ){
      newLocktype = EXCLUSIVE_LOCK;
    }else{
      TRACE2("error-code = %d\n", GetLastError());
    }
  }

  /* If we are holding a PENDING lock that ought to be released, then
  ** release it now.
  */
  if( gotPendingLock && locktype==SHARED_LOCK ){
    UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
  }

  /* Update the state of the lock has held in the file descriptor then
  ** return the appropriate result code.
  */
  if( res ){
    rc = SQLITE_OK;
  }else{
    TRACE4("LOCK FAILED %d trying for %d but got %d\n", id->h,
           locktype, newLocktype);
    rc = SQLITE_BUSY;
  }
  id->locktype = newLocktype;
  return rc;
}

/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, return
** non-zero, otherwise zero.
*/
int sqlite3OsCheckReservedLock(OsFile *id){
  int rc;
  assert( id->isOpen );
  if( id->locktype>=RESERVED_LOCK ){
    rc = 1;
    TRACE3("TEST WR-LOCK %d %d (local)\n", id->h, rc);
  }else{
    rc = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
    if( rc ){
      UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
    }
    rc = !rc;
    TRACE3("TEST WR-LOCK %d %d (remote)\n", id->h, rc);
  }
  return rc;
}

/*
** Lower the locking level on file descriptor id to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
**
** It is not possible for this routine to fail if the second argument
** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
** might return SQLITE_IOERR;
*/
int sqlite3OsUnlock(OsFile *id, int locktype){
  int type;
  int rc = SQLITE_OK;
  assert( id->isOpen );
  assert( locktype<=SHARED_LOCK );
  TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype,
          id->locktype, id->sharedLockByte);
  type = id->locktype;
  if( type>=EXCLUSIVE_LOCK ){
    UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
    if( locktype==SHARED_LOCK && !getReadLock(id) ){
      /* This should never happen.  We should always be able to
      ** reacquire the read lock */
      rc = SQLITE_IOERR;
    }
  }
  if( type>=RESERVED_LOCK ){
    UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
  }
  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
    unlockReadLock(id);
  }
  if( type>=PENDING_LOCK ){
    UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
  }
  id->locktype = locktype;
  return rc;
}

/*
** Get information to seed the random number generator.  The seed
** is written into the buffer zBuf[256].  The calling function must
** supply a sufficiently large buffer.
*/
int sqlite3OsRandomSeed(char *zBuf){
  /* We have to initialize zBuf to prevent valgrind from reporting
  ** errors.  The reports issued by valgrind are incorrect - we would
  ** prefer that the randomness be increased by making use of the
  ** uninitialized space in zBuf - but valgrind errors tend to worry
  ** some users.  Rather than argue, it seems easier just to initialize
  ** the whole array and silence valgrind, even if that means less randomness
  ** in the random seed.
  **
  ** When testing, initializing zBuf[] to zero is all we do.  That means
  ** that we always use the same random number sequence.* This makes the
  ** tests repeatable.
  */
  memset(zBuf, 0, 256);
  GetSystemTime((LPSYSTEMTIME)zBuf);
  return SQLITE_OK;
}

/*
** Sleep for a little while.  Return the amount of time slept.
*/
int sqlite3OsSleep(int ms){
  Sleep(ms);
  return ms;
}

/*
** Static variables used for thread synchronization
*/
static int inMutex = 0;
#ifdef SQLITE_W32_THREADS
  static CRITICAL_SECTION cs;
#endif

/*
** The following pair of routine implement mutual exclusion for
** multi-threaded processes.  Only a single thread is allowed to
** executed code that is surrounded by EnterMutex() and LeaveMutex().
**
** SQLite uses only a single Mutex.  There is not much critical
** code and what little there is executes quickly and without blocking.
*/
void sqlite3OsEnterMutex(){
#ifdef SQLITE_W32_THREADS
  static int isInit = 0;
  while( !isInit ){
    static long lock = 0;
    if( InterlockedIncrement(&lock)==1 ){
      InitializeCriticalSection(&cs);
      isInit = 1;
    }else{
      Sleep(1);
    }
  }
  EnterCriticalSection(&cs);
#endif
  assert( !inMutex );
  inMutex = 1;
}
void sqlite3OsLeaveMutex(){
  assert( inMutex );
  inMutex = 0;
#ifdef SQLITE_W32_THREADS
  LeaveCriticalSection(&cs);
#endif
}

/*
** Turn a relative pathname into a full pathname.  Return a pointer
** to the full pathname stored in space obtained from sqliteMalloc().
** The calling function is responsible for freeing this space once it
** is no longer needed.
*/
char *sqlite3OsFullPathname(const char *zRelative){
  char *zNotUsed;
  char *zFull;
  int nByte;
  nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
  zFull = sqliteMalloc( nByte );
  if( zFull==0 ) return 0;
  GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
  return zFull;
}

/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime().  This is used for testing.
*/
#ifdef SQLITE_TEST
int sqlite3_current_time = 0;
#endif

/*
** Find the current time (in Universal Coordinated Time).  Write the
** current time and date as a Julian Day number into *prNow and
** return 0.  Return 1 if the time and date cannot be found.
*/
int sqlite3OsCurrentTime(double *prNow){
  FILETIME ft;
  /* FILETIME structure is a 64-bit value representing the number of 
     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
  */
  double now;
  GetSystemTimeAsFileTime( &ft );
  now = ((double)ft.dwHighDateTime) * 4294967296.0; 
  *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
#ifdef SQLITE_TEST
  if( sqlite3_current_time ){
    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
  }
#endif
  return 0;
}

/*
** Find the time that the file was last modified.  Write the
** modification time and date as a Julian Day number into *prNow and
** return SQLITE_OK.  Return SQLITE_ERROR if the modification
** time cannot be found.
*/
int sqlite3OsFileModTime(OsFile *id, double *prMTime){
  int rc;
  FILETIME ft;
  /* FILETIME structure is a 64-bit value representing the number of 
  ** 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
  */
  if( GetFileTime(id->h, 0, 0, &ft) ){
    double t;
    t = ((double)ft.dwHighDateTime) * 4294967296.0; 
    *prMTime = (t + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
    rc = SQLITE_OK;
  }else{
    rc = SQLITE_ERROR;
  }
  return rc;
}

#endif /* OS_WIN */
Added SQLite.Interop/src/os_win.h.
















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2004 May 22
**
** 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 header file defines OS-specific features for Win32
*/
#ifndef _SQLITE_OS_WIN_H_
#define _SQLITE_OS_WIN_H_

#include <windows.h>
#include <winbase.h>

/*
** The OsFile structure is a operating-system independing representation
** of an open file handle.  It is defined differently for each architecture.
**
** This is the definition for Win32.
*/
typedef struct OsFile OsFile;
struct OsFile {
  HANDLE h;               /* Handle for accessing the file */
  unsigned char locktype; /* Type of lock currently held on this file */
  unsigned char isOpen;   /* True if needs to be closed */
  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
};


#define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
#define SQLITE_MIN_SLEEP_MS 1


#endif /* _SQLITE_OS_WIN_H_ */
Added SQLite.Interop/src/pager.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
/*
** 2001 September 15
**
** 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 is the implementation of the page cache subsystem or "pager".
** 
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.1 2005/03/01 16:04:31 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

/*
** Macros for troubleshooting.  Normally turned off
*/
#if 0
#define TRACE1(X)       sqlite3DebugPrintf(X)
#define TRACE2(X,Y)     sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z)   sqlite3DebugPrintf(X,Y,Z)
#define TRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W)
#define TRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W,V)
#else
#define TRACE1(X)
#define TRACE2(X,Y)
#define TRACE3(X,Y,Z)
#define TRACE4(X,Y,Z,W)
#define TRACE5(X,Y,Z,W,V)
#endif

/*
** The following two macros are used within the TRACEX() macros above
** to print out file-descriptors. They are required so that tracing
** can be turned on when using both the regular os_unix.c and os_test.c
** backends.
**
** PAGERID() takes a pointer to a Pager struct as it's argument. The
** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile
** struct as it's argument.
*/
#ifdef OS_TEST
#define PAGERID(p) (p->fd->fd.h)
#define FILEHANDLEID(fd) (fd->fd.h)
#else
#define PAGERID(p) (p->fd.h)
#define FILEHANDLEID(fd) (fd.h)
#endif

/*
** The page cache as a whole is always in one of the following
** states:
**
**   PAGER_UNLOCK        The page cache is not currently reading or 
**                       writing the database file.  There is no
**                       data held in memory.  This is the initial
**                       state.
**
**   PAGER_SHARED        The page cache is reading the database.
**                       Writing is not permitted.  There can be
**                       multiple readers accessing the same database
**                       file at the same time.
**
**   PAGER_RESERVED      This process has reserved the database for writing
**                       but has not yet made any changes.  Only one process
**                       at a time can reserve the database.  The original
**                       database file has not been modified so other
**                       processes may still be reading the on-disk
**                       database file.
**
**   PAGER_EXCLUSIVE     The page cache is writing the database.
**                       Access is exclusive.  No other processes or
**                       threads can be reading or writing while one
**                       process is writing.
**
**   PAGER_SYNCED        The pager moves to this state from PAGER_EXCLUSIVE
**                       after all dirty pages have been written to the
**                       database file and the file has been synced to
**                       disk. All that remains to do is to remove the
**                       journal file and the transaction will be
**                       committed.
**
** The page cache comes up in PAGER_UNLOCK.  The first time a
** sqlite3pager_get() occurs, the state transitions to PAGER_SHARED.
** After all pages have been released using sqlite_page_unref(),
** the state transitions back to PAGER_UNLOCK.  The first time
** that sqlite3pager_write() is called, the state transitions to
** PAGER_RESERVED.  (Note that sqlite_page_write() can only be
** called on an outstanding page which means that the pager must
** be in PAGER_SHARED before it transitions to PAGER_RESERVED.)
** The transition to PAGER_EXCLUSIVE occurs when before any changes
** are made to the database file.  After an sqlite3pager_rollback()
** or sqlite_pager_commit(), the state goes back to PAGER_SHARED.
*/
#define PAGER_UNLOCK      0
#define PAGER_SHARED      1   /* same as SHARED_LOCK */
#define PAGER_RESERVED    2   /* same as RESERVED_LOCK */
#define PAGER_EXCLUSIVE   4   /* same as EXCLUSIVE_LOCK */
#define PAGER_SYNCED      5

/*
** If the SQLITE_BUSY_RESERVED_LOCK macro is set to true at compile-time,
** then failed attempts to get a reserved lock will invoke the busy callback.
** This is off by default.  To see why, consider the following scenario:
** 
** Suppose thread A already has a shared lock and wants a reserved lock.
** Thread B already has a reserved lock and wants an exclusive lock.  If
** both threads are using their busy callbacks, it might be a long time
** be for one of the threads give up and allows the other to proceed.
** But if the thread trying to get the reserved lock gives up quickly
** (if it never invokes its busy callback) then the contention will be
** resolved quickly.
*/
#ifndef SQLITE_BUSY_RESERVED_LOCK
# define SQLITE_BUSY_RESERVED_LOCK 0
#endif

/*
** This macro rounds values up so that if the value is an address it
** is guaranteed to be an address that is aligned to an 8-byte boundary.
*/
#define FORCE_ALIGNMENT(X)   (((X)+7)&~7)

/*
** Each in-memory image of a page begins with the following header.
** This header is only visible to this pager module.  The client
** code that calls pager sees only the data that follows the header.
**
** Client code should call sqlite3pager_write() on a page prior to making
** any modifications to that page.  The first time sqlite3pager_write()
** is called, the original page contents are written into the rollback
** journal and PgHdr.inJournal and PgHdr.needSync are set.  Later, once
** the journal page has made it onto the disk surface, PgHdr.needSync
** is cleared.  The modified page cannot be written back into the original
** database file until the journal pages has been synced to disk and the
** PgHdr.needSync has been cleared.
**
** The PgHdr.dirty flag is set when sqlite3pager_write() is called and
** is cleared again when the page content is written back to the original
** database file.
*/
typedef struct PgHdr PgHdr;
struct PgHdr {
  Pager *pPager;                 /* The pager to which this page belongs */
  Pgno pgno;                     /* The page number for this page */
  PgHdr *pNextHash, *pPrevHash;  /* Hash collision chain for PgHdr.pgno */
  PgHdr *pNextFree, *pPrevFree;  /* Freelist of pages where nRef==0 */
  PgHdr *pNextAll;               /* A list of all pages */
  PgHdr *pNextStmt, *pPrevStmt;  /* List of pages in the statement journal */
  u8 inJournal;                  /* TRUE if has been written to journal */
  u8 inStmt;                     /* TRUE if in the statement subjournal */
  u8 dirty;                      /* TRUE if we need to write back changes */
  u8 needSync;                   /* Sync journal before writing this page */
  u8 alwaysRollback;             /* Disable dont_rollback() for this page */
  short int nRef;                /* Number of users of this page */
  PgHdr *pDirty;                 /* Dirty pages sorted by PgHdr.pgno */
#ifdef SQLITE_CHECK_PAGES
  u32 pageHash;
#endif
  /* pPager->psAligned bytes of page data follow this header */
  /* Pager.nExtra bytes of local data follow the page data */
};

/*
** For an in-memory only database, some extra information is recorded about
** each page so that changes can be rolled back.  (Journal files are not
** used for in-memory databases.)  The following information is added to
** the end of every EXTRA block for in-memory databases.
**
** This information could have been added directly to the PgHdr structure.
** But then it would take up an extra 8 bytes of storage on every PgHdr
** even for disk-based databases.  Splitting it out saves 8 bytes.  This
** is only a savings of 0.8% but those percentages add up.
*/
typedef struct PgHistory PgHistory;
struct PgHistory {
  u8 *pOrig;     /* Original page text.  Restore to this on a full rollback */
  u8 *pStmt;     /* Text as it was at the beginning of the current statement */
};

/*
** A macro used for invoking the codec if there is one
*/
#ifdef SQLITE_HAS_CODEC
# define CODEC(P,D,N,X) if( P->xCodec ){ P->xCodec(P->pCodecArg,D,N,X); }
#else
# define CODEC(P,D,N,X)
#endif

/*
** Convert a pointer to a PgHdr into a pointer to its data
** and back again.
*/
#define PGHDR_TO_DATA(P)  ((void*)(&(P)[1]))
#define DATA_TO_PGHDR(D)  (&((PgHdr*)(D))[-1])
#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->psAligned])
#define PGHDR_TO_HIST(P,PGR)  \
            ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->psAligned+(PGR)->nExtra])

/*
** How big to make the hash table used for locating in-memory pages
** by page number.
*/
#define N_PG_HASH 2048

/*
** Hash a page number
*/
#define pager_hash(PN)  ((PN)&(N_PG_HASH-1))

/*
** A open page cache is an instance of the following structure.
*/
struct Pager {
  char *zFilename;            /* Name of the database file */
  char *zJournal;             /* Name of the journal file */
  char *zDirectory;           /* Directory hold database and journal files */
  OsFile fd, jfd;             /* File descriptors for database and journal */
  OsFile stfd;                /* File descriptor for the statement subjournal*/
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  i64 stmtJSize;              /* Size of journal at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
  u32 cksumInit;              /* Quasi-random value added to every checksum */
  int stmtNRec;               /* Number of records in stmt subjournal */
  int nExtra;                 /* Add this many bytes to each in-memory page */
  void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
  void (*xReiniter)(void*,int);   /* Call this routine when reloading pages */
  int pageSize;               /* Number of bytes in a page */
  int psAligned;              /* pageSize rounded up to a multiple of 8 */
  int nPage;                  /* Total number of in-memory pages */
  int nRef;                   /* Number of in-memory pages with PgHdr.nRef>0 */
  int mxPage;                 /* Maximum number of pages to hold in cache */
  int nHit, nMiss, nOvfl;     /* Cache hits, missing, and LRU overflows */
  int nRead,nWrite;           /* Database pages read/written */
  void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
  void *pCodecArg;            /* First argument to xCodec() */
  u8 journalOpen;             /* True if journal file descriptors is valid */
  u8 journalStarted;          /* True if header of journal is synced */
  u8 useJournal;              /* Use a rollback journal on this file */
  u8 noReadlock;              /* Do not bother to obtain readlocks */
  u8 stmtOpen;                /* True if the statement subjournal is open */
  u8 stmtInUse;               /* True we are in a statement subtransaction */
  u8 stmtAutoopen;            /* Open stmt journal when main journal is opened*/
  u8 noSync;                  /* Do not sync the journal if true */
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
  u8 errMask;                 /* One of several kinds of errors */
  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable dont_rollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 *aInJournal;             /* One bit for each page in the database file */
  u8 *aInStmt;                /* One bit for each page in the database */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  BusyHandler *pBusyHandler;  /* Pointer to sqlite.busyHandler */
  PgHdr *pFirst, *pLast;      /* List of free pages */
  PgHdr *pFirstSynced;        /* First free page with PgHdr.needSync==0 */
  PgHdr *pAll;                /* List of all pages */
  PgHdr *pStmt;               /* List of pages in the statement subjournal */
  i64 journalOff;             /* Current byte offset in the journal file */
  i64 journalHdr;             /* Byte offset to previous journal header */
  i64 stmtHdrOff;             /* First journal header written this statement */
  i64 stmtCksum;              /* cksumInit when statement was started */
  int sectorSize;             /* Assumed sector size during rollback */
  PgHdr *aHash[N_PG_HASH];    /* Hash table to map page number to PgHdr */
};

/*
** These are bits that can be set in Pager.errMask.
*/
#define PAGER_ERR_FULL     0x01  /* a write() failed */
#define PAGER_ERR_MEM      0x02  /* malloc() failed */
#define PAGER_ERR_LOCK     0x04  /* error in the locking protocol */
#define PAGER_ERR_CORRUPT  0x08  /* database or journal corruption */
#define PAGER_ERR_DISK     0x10  /* general disk I/O error - bad hard drive? */

/*
** Journal files begin with the following magic string.  The data
** was obtained from /dev/random.  It is used only as a sanity check.
**
** Since version 2.8.0, the journal format contains additional sanity
** checking information.  If the power fails while the journal is begin
** written, semi-random garbage data might appear in the journal
** file after power is restored.  If an attempt is then made
** to roll the journal back, the database could be corrupted.  The additional
** sanity checking data is an attempt to discover the garbage in the
** journal and ignore it.
**
** The sanity checking information for the new journal format consists
** of a 32-bit checksum on each page of data.  The checksum covers both
** the page number and the pPager->pageSize bytes of data for the page.
** This cksum is initialized to a 32-bit random value that appears in the
** journal file right after the header.  The random initializer is important,
** because garbage data that appears at the end of a journal is likely
** data that was once in other files that have now been deleted.  If the
** garbage data came from an obsolete journal file, the checksums might
** be correct.  But by initializing the checksum to random value which
** is different for every journal, we minimize that risk.
*/
static const unsigned char aJournalMagic[] = {
  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
};

/*
** The size of the header and of each page in the journal is determined
** by the following macros.
*/
#define JOURNAL_PG_SZ(pPager)  ((pPager->pageSize) + 8)

/*
** The journal header size for this pager. In the future, this could be
** set to some value read from the disk controller. The important
** characteristic is that it is the same size as a disk sector.
*/
#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)

/*
** The macro MEMDB is true if we are dealing with an in-memory database.
** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
** the value of MEMDB will be a constant and the compiler will optimize
** out code that would never execute.
*/
#ifdef SQLITE_OMIT_MEMORYDB
# define MEMDB 0
#else
# define MEMDB pPager->memDb
#endif

/*
** The default size of a disk sector
*/
#define PAGER_SECTOR_SIZE 512

/*
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
** reserved for working around a windows/posix incompatibility). It is
** used in the journal to signify that the remainder of the journal file 
** is devoted to storing a master journal name - there are no more pages to
** roll back. See comments for function writeMasterJournal() for details.
*/
/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */
#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1)

/*
** The maximum legal page number is (2^31 - 1).
*/
#define PAGER_MAX_PGNO 2147483647

/*
** Enable reference count tracking (for debugging) here:
*/
#ifdef SQLITE_DEBUG
  int pager3_refinfo_enable = 0;
  static void pager_refinfo(PgHdr *p){
    static int cnt = 0;
    if( !pager3_refinfo_enable ) return;
    sqlite3DebugPrintf(
       "REFCNT: %4d addr=%p nRef=%d\n",
       p->pgno, PGHDR_TO_DATA(p), p->nRef
    );
    cnt++;   /* Something to set a breakpoint on */
  }
# define REFINFO(X)  pager_refinfo(X)
#else
# define REFINFO(X)
#endif

/*
** Read a 32-bit integer from the given file descriptor.  Store the integer
** that is read in *pRes.  Return SQLITE_OK if everything worked, or an
** error code is something goes wrong.
**
** All values are stored on disk as big-endian.
*/
static int read32bits(OsFile *fd, u32 *pRes){
  u32 res;
  int rc;
  rc = sqlite3OsRead(fd, &res, sizeof(res));
  if( rc==SQLITE_OK ){
    unsigned char ac[4];
    memcpy(ac, &res, 4);
    res = (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
  }
  *pRes = res;
  return rc;
}

/*
** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
** on success or an error code is something goes wrong.
*/
static int write32bits(OsFile *fd, u32 val){
  unsigned char ac[4];
  ac[0] = (val>>24) & 0xff;
  ac[1] = (val>>16) & 0xff;
  ac[2] = (val>>8) & 0xff;
  ac[3] = val & 0xff;
  return sqlite3OsWrite(fd, ac, 4);
}

/*
** Write the 32-bit integer 'val' into the page identified by page header
** 'p' at offset 'offset'.
*/
static void store32bits(u32 val, PgHdr *p, int offset){
  unsigned char *ac;
  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
  ac[0] = (val>>24) & 0xff;
  ac[1] = (val>>16) & 0xff;
  ac[2] = (val>>8) & 0xff;
  ac[3] = val & 0xff;
}

/*
** Read a 32-bit integer at offset 'offset' from the page identified by
** page header 'p'.
*/
static u32 retrieve32bits(PgHdr *p, int offset){
  unsigned char *ac;
  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
  return (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
}


/*
** Convert the bits in the pPager->errMask into an approprate
** return code.
*/
static int pager_errcode(Pager *pPager){
  int rc = SQLITE_OK;
  if( pPager->errMask & PAGER_ERR_LOCK )    rc = SQLITE_PROTOCOL;
  if( pPager->errMask & PAGER_ERR_DISK )    rc = SQLITE_IOERR;
  if( pPager->errMask & PAGER_ERR_FULL )    rc = SQLITE_FULL;
  if( pPager->errMask & PAGER_ERR_MEM )     rc = SQLITE_NOMEM;
  if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
  return rc;
}

#ifdef SQLITE_CHECK_PAGES
/*
** Return a 32-bit hash of the page data for pPage.
*/
static u32 pager_pagehash(PgHdr *pPage){
  u32 hash = 0;
  int i;
  unsigned char *pData = (unsigned char *)PGHDR_TO_DATA(pPage);
  for(i=0; i<pPage->pPager->pageSize; i++){
    hash = (hash+i)^pData[i];
  }
  return hash;
}

/*
** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
** is defined, and NDEBUG is not defined, an assert() statement checks
** that the page is either dirty or still matches the calculated page-hash.
*/
#define CHECK_PAGE(x) checkPage(x)
static void checkPage(PgHdr *pPg){
  Pager *pPager = pPg->pPager;
  assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty || 
      pPg->pageHash==pager_pagehash(pPg) );
}

#else
#define CHECK_PAGE(x)
#endif

/*
** When this is called the journal file for pager pPager must be open.
** The master journal file name is read from the end of the file and 
** written into memory obtained from sqliteMalloc(). *pzMaster is
** set to point at the memory and SQLITE_OK returned. The caller must
** sqliteFree() *pzMaster.
**
** If no master journal file name is present *pzMaster is set to 0 and
** SQLITE_OK returned.
*/
static int readMasterJournal(OsFile *pJrnl, char **pzMaster){
  int rc;
  u32 len;
  i64 szJ;
  u32 cksum;
  int i;
  unsigned char aMagic[8]; /* A buffer to hold the magic header */

  *pzMaster = 0;

  rc = sqlite3OsFileSize(pJrnl, &szJ);
  if( rc!=SQLITE_OK || szJ<16 ) return rc;

  rc = sqlite3OsSeek(pJrnl, szJ-16);
  if( rc!=SQLITE_OK ) return rc;
 
  rc = read32bits(pJrnl, &len);
  if( rc!=SQLITE_OK ) return rc;

  rc = read32bits(pJrnl, &cksum);
  if( rc!=SQLITE_OK ) return rc;

  rc = sqlite3OsRead(pJrnl, aMagic, 8);
  if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc;

  rc = sqlite3OsSeek(pJrnl, szJ-16-len);
  if( rc!=SQLITE_OK ) return rc;

  *pzMaster = (char *)sqliteMalloc(len+1);
  if( !*pzMaster ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3OsRead(pJrnl, *pzMaster, len);
  if( rc!=SQLITE_OK ){
    sqliteFree(*pzMaster);
    *pzMaster = 0;
    return rc;
  }

  /* See if the checksum matches the master journal name */
  for(i=0; i<len; i++){
    cksum -= (*pzMaster)[i];
  }
  if( cksum ){
    /* If the checksum doesn't add up, then one or more of the disk sectors
    ** containing the master journal filename is corrupted. This means
    ** definitely roll back, so just return SQLITE_OK and report a (nul)
    ** master-journal filename.
    */
    sqliteFree(*pzMaster);
    *pzMaster = 0;
  }else{
    (*pzMaster)[len] = '\0';
  }
   
  return SQLITE_OK;
}

/*
** Seek the journal file descriptor to the next sector boundary where a
** journal header may be read or written. Pager.journalOff is updated with
** the new seek offset.
**
** i.e for a sector size of 512:
**
** Input Offset              Output Offset
** ---------------------------------------
** 0                         0
** 512                       512
** 100                       512
** 2000                      2048
** 
*/
static int seekJournalHdr(Pager *pPager){
  i64 offset = 0;
  i64 c = pPager->journalOff;
  if( c ){
    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
  }
  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
  assert( offset>=c );
  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
  pPager->journalOff = offset;
  return sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
}

/*
** The journal file must be open when this routine is called. A journal
** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
** current location.
**
** The format for the journal header is as follows:
** - 8 bytes: Magic identifying journal format.
** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
** - 4 bytes: Random number used for page hash.
** - 4 bytes: Initial database page count.
** - 4 bytes: Sector size used by the process that wrote this journal.
** 
** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space.
*/
static int writeJournalHdr(Pager *pPager){

  int rc = seekJournalHdr(pPager);
  if( rc ) return rc;

  pPager->journalHdr = pPager->journalOff;
  if( pPager->stmtHdrOff==0 ){
    pPager->stmtHdrOff = pPager->journalHdr;
  }
  pPager->journalOff += JOURNAL_HDR_SZ(pPager);

  /* FIX ME: 
  **
  ** Possibly for a pager not in no-sync mode, the journal magic should not
  ** be written until nRec is filled in as part of next syncJournal(). 
  **
  ** Actually maybe the whole journal header should be delayed until that
  ** point. Think about this.
  */
  rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));

  if( rc==SQLITE_OK ){
    /* The nRec Field. 0xFFFFFFFF for no-sync journals. */
    rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0);
  }
  if( rc==SQLITE_OK ){
    /* The random check-hash initialiser */ 
    sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
    rc = write32bits(&pPager->jfd, pPager->cksumInit);
  }
  if( rc==SQLITE_OK ){
    /* The initial database size */
    rc = write32bits(&pPager->jfd, pPager->dbSize);
  }
  if( rc==SQLITE_OK ){
    /* The assumed sector size for this process */
    rc = write32bits(&pPager->jfd, pPager->sectorSize);
  }

  /* The journal header has been written successfully. Seek the journal
  ** file descriptor to the end of the journal header sector.
  */
  if( rc==SQLITE_OK ){
    sqlite3OsSeek(&pPager->jfd, pPager->journalOff-1);
    rc = sqlite3OsWrite(&pPager->jfd, "\000", 1);
  }
  return rc;
}

/*
** The journal file must be open when this is called. A journal header file
** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
** file. See comments above function writeJournalHdr() for a description of
** the journal header format.
**
** If the header is read successfully, *nRec is set to the number of
** page records following this header and *dbSize is set to the size of the
** database before the transaction began, in pages. Also, pPager->cksumInit
** is set to the value read from the journal header. SQLITE_OK is returned
** in this case.
**
** If the journal header file appears to be corrupted, SQLITE_DONE is
** returned and *nRec and *dbSize are not set.  If JOURNAL_HDR_SZ bytes
** cannot be read from the journal file an error code is returned.
*/
static int readJournalHdr(
  Pager *pPager, 
  i64 journalSize,
  u32 *pNRec, 
  u32 *pDbSize
){
  int rc;
  unsigned char aMagic[8]; /* A buffer to hold the magic header */

  rc = seekJournalHdr(pPager);
  if( rc ) return rc;

  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
    return SQLITE_DONE;
  }

  rc = sqlite3OsRead(&pPager->jfd, aMagic, sizeof(aMagic));
  if( rc ) return rc;

  if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
    return SQLITE_DONE;
  }

  rc = read32bits(&pPager->jfd, pNRec);
  if( rc ) return rc;

  rc = read32bits(&pPager->jfd, &pPager->cksumInit);
  if( rc ) return rc;

  rc = read32bits(&pPager->jfd, pDbSize);
  if( rc ) return rc;

  /* Update the assumed sector-size to match the value used by 
  ** the process that created this journal. If this journal was
  ** created by a process other than this one, then this routine
  ** is being called from within pager_playback(). The local value
  ** of Pager.sectorSize is restored at the end of that routine.
  */
  rc = read32bits(&pPager->jfd, (u32 *)&pPager->sectorSize);
  if( rc ) return rc;

  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
  rc = sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
  return rc;
}


/*
** Write the supplied master journal name into the journal file for pager
** pPager at the current location. The master journal name must be the last
** thing written to a journal file. If the pager is in full-sync mode, the
** journal file descriptor is advanced to the next sector boundary before
** anything is written. The format is:
**
** + 4 bytes: PAGER_MJ_PGNO.
** + N bytes: length of master journal name.
** + 4 bytes: N
** + 4 bytes: Master journal name checksum.
** + 8 bytes: aJournalMagic[].
**
** The master journal page checksum is the sum of the bytes in the master
** journal name.
*/
static int writeMasterJournal(Pager *pPager, const char *zMaster){
  int rc;
  int len; 
  int i; 
  u32 cksum = 0; 

  if( !zMaster || pPager->setMaster) return SQLITE_OK;
  pPager->setMaster = 1;

  len = strlen(zMaster);
  for(i=0; i<len; i++){
    cksum += zMaster[i];
  }

  /* If in full-sync mode, advance to the next disk sector before writing
  ** the master journal name. This is in case the previous page written to
  ** the journal has already been synced.
  */
  if( pPager->fullSync ){
    rc = seekJournalHdr(pPager);
    if( rc!=SQLITE_OK ) return rc;
  }
  pPager->journalOff += (len+20);

  rc = write32bits(&pPager->jfd, PAGER_MJ_PGNO(pPager));
  if( rc!=SQLITE_OK ) return rc;

  rc = sqlite3OsWrite(&pPager->jfd, zMaster, len);
  if( rc!=SQLITE_OK ) return rc;

  rc = write32bits(&pPager->jfd, len);
  if( rc!=SQLITE_OK ) return rc;

  rc = write32bits(&pPager->jfd, cksum);
  if( rc!=SQLITE_OK ) return rc;

  rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
  pPager->needSync = 1;
  return rc;
}

/*
** Add or remove a page from the list of all pages that are in the
** statement journal.
**
** The Pager keeps a separate list of pages that are currently in
** the statement journal.  This helps the sqlite3pager_stmt_commit()
** routine run MUCH faster for the common case where there are many
** pages in memory but only a few are in the statement journal.
*/
static void page_add_to_stmt_list(PgHdr *pPg){
  Pager *pPager = pPg->pPager;
  if( pPg->inStmt ) return;
  assert( pPg->pPrevStmt==0 && pPg->pNextStmt==0 );
  pPg->pPrevStmt = 0;
  if( pPager->pStmt ){
    pPager->pStmt->pPrevStmt = pPg;
  }
  pPg->pNextStmt = pPager->pStmt;
  pPager->pStmt = pPg;
  pPg->inStmt = 1;
}
static void page_remove_from_stmt_list(PgHdr *pPg){
  if( !pPg->inStmt ) return;
  if( pPg->pPrevStmt ){
    assert( pPg->pPrevStmt->pNextStmt==pPg );
    pPg->pPrevStmt->pNextStmt = pPg->pNextStmt;
  }else{
    assert( pPg->pPager->pStmt==pPg );
    pPg->pPager->pStmt = pPg->pNextStmt;
  }
  if( pPg->pNextStmt ){
    assert( pPg->pNextStmt->pPrevStmt==pPg );
    pPg->pNextStmt->pPrevStmt = pPg->pPrevStmt;
  }
  pPg->pNextStmt = 0;
  pPg->pPrevStmt = 0;
  pPg->inStmt = 0;
}

/*
** Find a page in the hash table given its page number.  Return
** a pointer to the page or NULL if not found.
*/
static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
  PgHdr *p = pPager->aHash[pager_hash(pgno)];
  while( p && p->pgno!=pgno ){
    p = p->pNextHash;
  }
  return p;
}

/*
** Unlock the database and clear the in-memory cache.  This routine
** sets the state of the pager back to what it was when it was first
** opened.  Any outstanding pages are invalidated and subsequent attempts
** to access those pages will likely result in a coredump.
*/
static void pager_reset(Pager *pPager){
  PgHdr *pPg, *pNext;
  for(pPg=pPager->pAll; pPg; pPg=pNext){
    pNext = pPg->pNextAll;
    sqliteFree(pPg);
  }
  pPager->pFirst = 0;
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->pAll = 0;
  memset(pPager->aHash, 0, sizeof(pPager->aHash));
  pPager->nPage = 0;
  if( pPager->state>=PAGER_RESERVED ){
    sqlite3pager_rollback(pPager);
  }
  sqlite3OsUnlock(&pPager->fd, NO_LOCK);
  pPager->state = PAGER_UNLOCK;
  pPager->dbSize = -1;
  pPager->nRef = 0;
  assert( pPager->journalOpen==0 );
}

/*
** When this routine is called, the pager has the journal file open and
** a RESERVED or EXCLUSIVE lock on the database.  This routine releases
** the database lock and acquires a SHARED lock in its place.  The journal
** file is deleted and closed.
**
** TODO: Consider keeping the journal file open for temporary databases.
** This might give a performance improvement on windows where opening
** a file is an expensive operation.
*/
static int pager_unwritelock(Pager *pPager){
  PgHdr *pPg;
  int rc;
  assert( !MEMDB );
  if( pPager->state<PAGER_RESERVED ){
    return SQLITE_OK;
  }
  sqlite3pager_stmt_commit(pPager);
  if( pPager->stmtOpen ){
    sqlite3OsClose(&pPager->stfd);
    pPager->stmtOpen = 0;
  }
  if( pPager->journalOpen ){
    sqlite3OsClose(&pPager->jfd);
    pPager->journalOpen = 0;
    sqlite3OsDelete(pPager->zJournal);
    sqliteFree( pPager->aInJournal );
    pPager->aInJournal = 0;
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
      pPg->inJournal = 0;
      pPg->dirty = 0;
      pPg->needSync = 0;
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
    pPager->dirtyCache = 0;
    pPager->nRec = 0;
  }else{
    assert( pPager->dirtyCache==0 || pPager->useJournal==0 );
  }
  rc = sqlite3OsUnlock(&pPager->fd, SHARED_LOCK);
  pPager->state = PAGER_SHARED;
  pPager->origDbSize = 0;
  pPager->setMaster = 0;
  return rc;
}

/*
** Compute and return a checksum for the page of data.
**
** This is not a real checksum.  It is really just the sum of the 
** random initial value and the page number.  We experimented with
** a checksum of the entire data, but that was found to be too slow.
**
** Note that the page number is stored at the beginning of data and
** the checksum is stored at the end.  This is important.  If journal
** corruption occurs due to a power failure, the most likely scenario
** is that one end or the other of the record will be changed.  It is
** much less likely that the two ends of the journal record will be
** correct and the middle be corrupt.  Thus, this "checksum" scheme,
** though fast and simple, catches the mostly likely kind of corruption.
**
** FIX ME:  Consider adding every 200th (or so) byte of the data to the
** checksum.  That way if a single page spans 3 or more disk sectors and
** only the middle sector is corrupt, we will still have a reasonable
** chance of failing the checksum and thus detecting the problem.
*/
static u32 pager_cksum(Pager *pPager, Pgno pgno, const char *aData){
  u32 cksum = pPager->cksumInit;
  int i = pPager->pageSize-200;
  while( i>0 ){
    cksum += aData[i];
    i -= 200;
  }
  return cksum;
}

/*
** Read a single page from the journal file opened on file descriptor
** jfd.  Playback this one page.
**
** If useCksum==0 it means this journal does not use checksums.  Checksums
** are not used in statement journals because statement journals do not
** need to survive power failures.
*/
static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
  int rc;
  PgHdr *pPg;                   /* An existing page in the cache */
  Pgno pgno;                    /* The page number of a page in journal */
  u32 cksum;                    /* Checksum used for sanity checking */
  u8 aData[SQLITE_MAX_PAGE_SIZE];  /* Temp storage for a page */

  rc = read32bits(jfd, &pgno);
  if( rc!=SQLITE_OK ) return rc;
  rc = sqlite3OsRead(jfd, &aData, pPager->pageSize);
  if( rc!=SQLITE_OK ) return rc;
  pPager->journalOff += pPager->pageSize + 4;

  /* Sanity checking on the page.  This is more important that I originally
  ** thought.  If a power failure occurs while the journal is being written,
  ** it could cause invalid data to be written into the journal.  We need to
  ** detect this invalid data (with high probability) and ignore it.
  */
  if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
    return SQLITE_DONE;
  }
  if( pgno>(unsigned)pPager->dbSize ){
    return SQLITE_OK;
  }
  if( useCksum ){
    rc = read32bits(jfd, &cksum);
    if( rc ) return rc;
    pPager->journalOff += 4;
    if( pager_cksum(pPager, pgno, aData)!=cksum ){
      return SQLITE_DONE;
    }
  }

  assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );

  /* If the pager is in RESERVED state, then there must be a copy of this
  ** page in the pager cache. In this case just update the pager cache,
  ** not the database file. The page is left marked dirty in this case.
  **
  ** If in EXCLUSIVE state, then we update the pager cache if it exists
  ** and the main file. The page is then marked not dirty.
  */
  pPg = pager_lookup(pPager, pgno);
  assert( pPager->state>=PAGER_EXCLUSIVE || pPg );
  TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno);
  if( pPager->state>=PAGER_EXCLUSIVE ){
    sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);
    rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize);
  }
  if( pPg ){
    /* No page should ever be explicitly rolled back that is in use, except
    ** for page 1 which is held in use in order to keep the lock on the
    ** database active. However such a page may be rolled back as a result
    ** of an internal error resulting in an automatic call to
    ** sqlite3pager_rollback().
    */
    void *pData;
    /* assert( pPg->nRef==0 || pPg->pgno==1 ); */
    pData = PGHDR_TO_DATA(pPg);
    memcpy(pData, aData, pPager->pageSize);
    if( pPager->xDestructor ){  /*** FIX ME:  Should this be xReinit? ***/
      pPager->xDestructor(pData, pPager->pageSize);
    }
    if( pPager->state>=PAGER_EXCLUSIVE ){
      pPg->dirty = 0;
      pPg->needSync = 0;
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
    CODEC(pPager, pData, pPg->pgno, 3);
  }
  return rc;
}

/*
** Parameter zMaster is the name of a master journal file. A single journal
** file that referred to the master journal file has just been rolled back.
** This routine checks if it is possible to delete the master journal file,
** and does so if it is.
**
** The master journal file contains the names of all child journals.
** To tell if a master journal can be deleted, check to each of the
** children.  If all children are either missing or do not refer to
** a different master journal, then this master journal can be deleted.
*/
static int pager_delmaster(const char *zMaster){
  int rc;
  int master_open = 0;
  OsFile master;
  char *zMasterJournal = 0; /* Contents of master journal file */
  i64 nMasterJournal;       /* Size of master journal file */

  /* Open the master journal file exclusively in case some other process
  ** is running this routine also. Not that it makes too much difference.
  */
  memset(&master, 0, sizeof(master));
  rc = sqlite3OsOpenReadOnly(zMaster, &master);
  if( rc!=SQLITE_OK ) goto delmaster_out;
  master_open = 1;
  rc = sqlite3OsFileSize(&master, &nMasterJournal);
  if( rc!=SQLITE_OK ) goto delmaster_out;

  if( nMasterJournal>0 ){
    char *zJournal;
    char *zMasterPtr = 0;

    /* Load the entire master journal file into space obtained from
    ** sqliteMalloc() and pointed to by zMasterJournal. 
    */
    zMasterJournal = (char *)sqliteMalloc(nMasterJournal);
    if( !zMasterJournal ){
      rc = SQLITE_NOMEM;
      goto delmaster_out;
    }
    rc = sqlite3OsRead(&master, zMasterJournal, nMasterJournal);
    if( rc!=SQLITE_OK ) goto delmaster_out;

    zJournal = zMasterJournal;
    while( (zJournal-zMasterJournal)<nMasterJournal ){
      if( sqlite3OsFileExists(zJournal) ){
        /* One of the journals pointed to by the master journal exists.
        ** Open it and check if it points at the master journal. If
        ** so, return without deleting the master journal file.
        */
        OsFile journal;
        int c;

        memset(&journal, 0, sizeof(journal));
        rc = sqlite3OsOpenReadOnly(zJournal, &journal);
        if( rc!=SQLITE_OK ){
          goto delmaster_out;
        }

        rc = readMasterJournal(&journal, &zMasterPtr);
        sqlite3OsClose(&journal);
        if( rc!=SQLITE_OK ){
          goto delmaster_out;
        }

        c = zMasterPtr!=0 && strcmp(zMasterPtr, zMaster)==0;
        sqliteFree(zMasterPtr);
        if( c ){
          /* We have a match. Do not delete the master journal file. */
          goto delmaster_out;
        }
      }
      zJournal += (strlen(zJournal)+1);
    }
  }
  
  sqlite3OsDelete(zMaster);

delmaster_out:
  if( zMasterJournal ){
    sqliteFree(zMasterJournal);
  }  
  if( master_open ){
    sqlite3OsClose(&master);
  }
  return rc;
}

/*
** Make every page in the cache agree with what is on disk.  In other words,
** reread the disk to reset the state of the cache.
**
** This routine is called after a rollback in which some of the dirty cache
** pages had never been written out to disk.  We need to roll back the
** cache content and the easiest way to do that is to reread the old content
** back from the disk.
*/
static int pager_reload_cache(Pager *pPager){
  PgHdr *pPg;
  int rc = SQLITE_OK;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    char zBuf[SQLITE_MAX_PAGE_SIZE];
    if( !pPg->dirty ) continue;
    if( (int)pPg->pgno <= pPager->origDbSize ){
      sqlite3OsSeek(&pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1));
      rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);
      TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
      if( rc ) break;
      CODEC(pPager, zBuf, pPg->pgno, 2);
    }else{
      memset(zBuf, 0, pPager->pageSize);
    }
    if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){
      memcpy(PGHDR_TO_DATA(pPg), zBuf, pPager->pageSize);
      if( pPager->xReiniter ){
        pPager->xReiniter(PGHDR_TO_DATA(pPg), pPager->pageSize);
      }else{
        memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
      }
    }
    pPg->needSync = 0;
    pPg->dirty = 0;
#ifdef SQLITE_CHECK_PAGES
    pPg->pageHash = pager_pagehash(pPg);
#endif
  }
  return rc;
}

/*
** Truncate the main file of the given pager to the number of pages
** indicated.
*/
static int pager_truncate(Pager *pPager, int nPage){
  assert( pPager->state>=PAGER_EXCLUSIVE );
  return sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(i64)nPage);
}

/*
** Playback the journal and thus restore the database file to
** the state it was in before we started making changes.  
**
** The journal file format is as follows: 
**
**  (1)  8 byte prefix.  A copy of aJournalMagic[].
**  (2)  4 byte big-endian integer which is the number of valid page records
**       in the journal.  If this value is 0xffffffff, then compute the
**       number of page records from the journal size.
**  (3)  4 byte big-endian integer which is the initial value for the 
**       sanity checksum.
**  (4)  4 byte integer which is the number of pages to truncate the
**       database to during a rollback.
**  (5)  4 byte integer which is the number of bytes in the master journal
**       name.  The value may be zero (indicate that there is no master
**       journal.)
**  (6)  N bytes of the master journal name.  The name will be nul-terminated
**       and might be shorter than the value read from (5).  If the first byte
**       of the name is \000 then there is no master journal.  The master
**       journal name is stored in UTF-8.
**  (7)  Zero or more pages instances, each as follows:
**        +  4 byte page number.
**        +  pPager->pageSize bytes of data.
**        +  4 byte checksum
**
** When we speak of the journal header, we mean the first 6 items above.
** Each entry in the journal is an instance of the 7th item.
**
** Call the value from the second bullet "nRec".  nRec is the number of
** valid page entries in the journal.  In most cases, you can compute the
** value of nRec from the size of the journal file.  But if a power
** failure occurred while the journal was being written, it could be the
** case that the size of the journal file had already been increased but
** the extra entries had not yet made it safely to disk.  In such a case,
** the value of nRec computed from the file size would be too large.  For
** that reason, we always use the nRec value in the header.
**
** If the nRec value is 0xffffffff it means that nRec should be computed
** from the file size.  This value is used when the user selects the
** no-sync option for the journal.  A power failure could lead to corruption
** in this case.  But for things like temporary table (which will be
** deleted when the power is restored) we don't care.  
**
** If the file opened as the journal file is not a well-formed
** journal file then all pages up to the first corrupted page are rolled
** back (or no pages if the journal header is corrupted). The journal file
** is then deleted and SQLITE_OK returned, just as if no corruption had
** been encountered.
**
** If an I/O or malloc() error occurs, the journal-file is not deleted
** and an error code is returned.
*/
static int pager_playback(Pager *pPager){
  i64 szJ;                 /* Size of the journal file in bytes */
  u32 nRec;                /* Number of Records in the journal */
  int i;                   /* Loop counter */
  Pgno mxPg = 0;           /* Size of the original file in pages */
  int rc;                  /* Result code of a subroutine */
  char *zMaster = 0;       /* Name of master journal file if any */

  /* Figure out how many records are in the journal.  Abort early if
  ** the journal is empty.
  */
  assert( pPager->journalOpen );
  rc = sqlite3OsFileSize(&pPager->jfd, &szJ);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }

  /* Read the master journal name from the journal, if it is present.
  ** If a master journal file name is specified, but the file is not
  ** present on disk, then the journal is not hot and does not need to be
  ** played back.
  */
  rc = readMasterJournal(&pPager->jfd, &zMaster);
  assert( rc!=SQLITE_DONE );
  if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){
    sqliteFree(zMaster);
    zMaster = 0;
    if( rc==SQLITE_DONE ) rc = SQLITE_OK;
    goto end_playback;
  }
  sqlite3OsSeek(&pPager->jfd, 0);
  pPager->journalOff = 0;

  /* This loop terminates either when the readJournalHdr() call returns
  ** SQLITE_DONE or an IO error occurs. */
  while( 1 ){

    /* Read the next journal header from the journal file.  If there are
    ** not enough bytes left in the journal file for a complete header, or
    ** it is corrupted, then a process must of failed while writing it.
    ** This indicates nothing more needs to be rolled back.
    */
    rc = readJournalHdr(pPager, szJ, &nRec, &mxPg);
    if( rc!=SQLITE_OK ){ 
      if( rc==SQLITE_DONE ){
        rc = SQLITE_OK;
      }
      goto end_playback;
    }

    /* If nRec is 0xffffffff, then this journal was created by a process
    ** working in no-sync mode. This means that the rest of the journal
    ** file consists of pages, there are no more journal headers. Compute
    ** the value of nRec based on this assumption.
    */
    if( nRec==0xffffffff ){
      assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
      nRec = (szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager);
    }

    /* If this is the first header read from the journal, truncate the
    ** database file back to it's original size.
    */
    if( pPager->state>=PAGER_EXCLUSIVE && 
        pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
      assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
      rc = pager_truncate(pPager, mxPg);
      if( rc!=SQLITE_OK ){
        goto end_playback;
      }
      pPager->dbSize = mxPg;
    }

    /* rc = sqlite3OsSeek(&pPager->jfd, JOURNAL_HDR_SZ(pPager)); */
    if( rc!=SQLITE_OK ) goto end_playback;
  
    /* Copy original pages out of the journal and back into the database file.
    */
    for(i=0; i<nRec; i++){
      rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
      if( rc!=SQLITE_OK ){
        if( rc==SQLITE_DONE ){
          rc = SQLITE_OK;
          pPager->journalOff = szJ;
          break;
        }else{
          goto end_playback;
        }
      }
    }
  }

  /* Pages that have been written to the journal but never synced
  ** where not restored by the loop above.  We have to restore those
  ** pages by reading them back from the original database.
  */
  assert( rc==SQLITE_OK );
  pager_reload_cache(pPager);

end_playback:
  if( rc==SQLITE_OK ){
    rc = pager_unwritelock(pPager);
  }
  if( zMaster ){
    /* If there was a master journal and this routine will return true,
    ** see if it is possible to delete the master journal.
    */
    if( rc==SQLITE_OK ){
      rc = pager_delmaster(zMaster);
    }
    sqliteFree(zMaster);
  }

  /* The Pager.sectorSize variable may have been updated while rolling
  ** back a journal created by a process with a different PAGER_SECTOR_SIZE
  ** value. Reset it to the correct value for this process.
  */
  pPager->sectorSize = PAGER_SECTOR_SIZE;
  return rc;
}

/*
** Playback the statement journal.
**
** This is similar to playing back the transaction journal but with
** a few extra twists.
**
**    (1)  The number of pages in the database file at the start of
**         the statement is stored in pPager->stmtSize, not in the
**         journal file itself.
**
**    (2)  In addition to playing back the statement journal, also
**         playback all pages of the transaction journal beginning
**         at offset pPager->stmtJSize.
*/
static int pager_stmt_playback(Pager *pPager){
  i64 szJ;                 /* Size of the full journal */
  i64 hdrOff;
  int nRec;                /* Number of Records */
  int i;                   /* Loop counter */
  int rc;

  szJ = pPager->journalOff;
#ifndef NDEBUG 
  {
    i64 os_szJ;
    rc = sqlite3OsFileSize(&pPager->jfd, &os_szJ);
    if( rc!=SQLITE_OK ) return rc;
    assert( szJ==os_szJ );
  }
#endif

  /* Set hdrOff to be the offset to the first journal header written
  ** this statement transaction, or the end of the file if no journal
  ** header was written.
  */
  hdrOff = pPager->stmtHdrOff;
  assert( pPager->fullSync || !hdrOff );
  if( !hdrOff ){
    hdrOff = szJ;
  }
  
  /* Truncate the database back to its original size.
  */
  if( pPager->state>=PAGER_EXCLUSIVE ){
    rc = pager_truncate(pPager, pPager->stmtSize);
  }
  pPager->dbSize = pPager->stmtSize;

  /* Figure out how many records are in the statement journal.
  */
  assert( pPager->stmtInUse && pPager->journalOpen );
  sqlite3OsSeek(&pPager->stfd, 0);
  nRec = pPager->stmtNRec;
  
  /* Copy original pages out of the statement journal and back into the
  ** database file.  Note that the statement journal omits checksums from
  ** each record since power-failure recovery is not important to statement
  ** journals.
  */
  for(i=nRec-1; i>=0; i--){
    rc = pager_playback_one_page(pPager, &pPager->stfd, 0);
    assert( rc!=SQLITE_DONE );
    if( rc!=SQLITE_OK ) goto end_stmt_playback;
  }

  /* Now roll some pages back from the transaction journal. Pager.stmtJSize
  ** was the size of the journal file when this statement was started, so
  ** everything after that needs to be rolled back, either into the
  ** database, the memory cache, or both.
  **
  ** If it is not zero, then Pager.stmtHdrOff is the offset to the start
  ** of the first journal header written during this statement transaction.
  */
  rc = sqlite3OsSeek(&pPager->jfd, pPager->stmtJSize);
  if( rc!=SQLITE_OK ){
    goto end_stmt_playback;
  }
  pPager->journalOff = pPager->stmtJSize;
  pPager->cksumInit = pPager->stmtCksum;
  assert( JOURNAL_HDR_SZ(pPager)<(pPager->pageSize+8) );
  while( pPager->journalOff <= (hdrOff-(pPager->pageSize+8)) ){
    rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
    assert( rc!=SQLITE_DONE );
    if( rc!=SQLITE_OK ) goto end_stmt_playback;
  }

  while( pPager->journalOff < szJ ){
    u32 nRec;
    u32 dummy;
    rc = readJournalHdr(pPager, szJ, &nRec, &dummy);
    if( rc!=SQLITE_OK ){
      assert( rc!=SQLITE_DONE );
      goto end_stmt_playback;
    }
    if( nRec==0 ){
      nRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
    }
    for(i=nRec-1; i>=0 && pPager->journalOff < szJ; i--){
      rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
      assert( rc!=SQLITE_DONE );
      if( rc!=SQLITE_OK ) goto end_stmt_playback;
    }
  }

  pPager->journalOff = szJ;
  
end_stmt_playback:
  if( rc!=SQLITE_OK ){
    pPager->errMask |= PAGER_ERR_CORRUPT;
    rc = SQLITE_CORRUPT;  /* bkpt-CORRUPT */
  }else{
    pPager->journalOff = szJ;
    /* pager_reload_cache(pPager); */
  }
  return rc;
}

/*
** Change the maximum number of in-memory pages that are allowed.
**
** The maximum number is the absolute value of the mxPage parameter.
** If mxPage is negative, the noSync flag is also set.  noSync bypasses
** calls to sqlite3OsSync().  The pager runs much faster with noSync on,
** but if the operating system crashes or there is an abrupt power 
** failure, the database file might be left in an inconsistent and
** unrepairable state.  
*/
void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){
  if( mxPage>=0 ){
    pPager->noSync = pPager->tempFile;
    if( pPager->noSync ) pPager->needSync = 0; 
  }else{
    pPager->noSync = 1;
    mxPage = -mxPage;
  }
  if( mxPage>10 ){
    pPager->mxPage = mxPage;
  }else{
    pPager->mxPage = 10;
  }
}

/*
** Adjust the robustness of the database to damage due to OS crashes
** or power failures by changing the number of syncs()s when writing
** the rollback journal.  There are three levels:
**
**    OFF       sqlite3OsSync() is never called.  This is the default
**              for temporary and transient files.
**
**    NORMAL    The journal is synced once before writes begin on the
**              database.  This is normally adequate protection, but
**              it is theoretically possible, though very unlikely,
**              that an inopertune power failure could leave the journal
**              in a state which would cause damage to the database
**              when it is rolled back.
**
**    FULL      The journal is synced twice before writes begin on the
**              database (with some additional information - the nRec field
**              of the journal header - being written in between the two
**              syncs).  If we assume that writing a
**              single disk sector is atomic, then this mode provides
**              assurance that the journal will not be corrupted to the
**              point of causing damage to the database during rollback.
**
** Numeric values associated with these states are OFF==1, NORMAL=2,
** and FULL=3.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
void sqlite3pager_set_safety_level(Pager *pPager, int level){
  pPager->noSync =  level==1 || pPager->tempFile;
  pPager->fullSync = level==3 && !pPager->tempFile;
  if( pPager->noSync ) pPager->needSync = 0;
}
#endif

/*
** Open a temporary file.  Write the name of the file into zName
** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.)  Write
** the file descriptor into *fd.  Return SQLITE_OK on success or some
** other error code if we fail.
**
** The OS will automatically delete the temporary file when it is
** closed.
*/
static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
  int cnt = 8;
  int rc;
  do{
    cnt--;
    sqlite3OsTempFileName(zFile);
    rc = sqlite3OsOpenExclusive(zFile, fd, 1);
  }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
  return rc;
}

/*
** Create a new page cache and put a pointer to the page cache in *ppPager.
** The file to be cached need not exist.  The file is not locked until
** the first call to sqlite3pager_get() and is only held open until the
** last page is released using sqlite3pager_unref().
**
** If zFilename is NULL then a randomly-named temporary file is created
** and used as the file to be cached.  The file will be deleted
** automatically when it is closed.
**
** If zFilename is ":memory:" then all information is held in cache.
** It is never written to disk.  This can be used to implement an
** in-memory database.
*/
int sqlite3pager_open(
  Pager **ppPager,         /* Return the Pager structure here */
  const char *zFilename,   /* Name of the database file to open */
  int nExtra,              /* Extra bytes append to each in-memory page */
  int flags                /* flags controlling this file */
){
  Pager *pPager;
  char *zFullPathname = 0;
  int nameLen;
  OsFile fd;
  int rc = SQLITE_OK;
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
  char zTemp[SQLITE_TEMPNAME_SIZE];

  *ppPager = 0;
  memset(&fd, 0, sizeof(fd));
  if( sqlite3_malloc_failed ){
    return SQLITE_NOMEM;
  }
  if( zFilename && zFilename[0] ){
#ifndef SQLITE_OMIT_MEMORYDB
    if( strcmp(zFilename,":memory:")==0 ){
      memDb = 1;
      zFullPathname = sqliteStrDup("");
      rc = SQLITE_OK;
    }else
#endif
    {
      zFullPathname = sqlite3OsFullPathname(zFilename);
      if( zFullPathname ){
        rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);
      }
    }
  }else{
    rc = sqlite3pager_opentemp(zTemp, &fd);
    zFilename = zTemp;
    zFullPathname = sqlite3OsFullPathname(zFilename);
    if( rc==SQLITE_OK ){
      tempFile = 1;
    }
  }
  if( !zFullPathname ){
    sqlite3OsClose(&fd);
    return SQLITE_NOMEM;
  }
  if( rc!=SQLITE_OK ){
    sqlite3OsClose(&fd);
    sqliteFree(zFullPathname);
    return rc;
  }
  nameLen = strlen(zFullPathname);
  pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
  if( pPager==0 ){
    sqlite3OsClose(&fd);
    sqliteFree(zFullPathname);
    return SQLITE_NOMEM;
  }
  TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
  pPager->zFilename = (char*)&pPager[1];
  pPager->zDirectory = &pPager->zFilename[nameLen+1];
  pPager->zJournal = &pPager->zDirectory[nameLen+1];
  strcpy(pPager->zFilename, zFullPathname);
  strcpy(pPager->zDirectory, zFullPathname);
  for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
  if( i>0 ) pPager->zDirectory[i-1] = 0;
  strcpy(pPager->zJournal, zFullPathname);
  sqliteFree(zFullPathname);
  strcpy(&pPager->zJournal[nameLen], "-journal");
  pPager->fd = fd;
#if OS_UNIX
  pPager->fd.pPager = pPager;
#endif
  pPager->journalOpen = 0;
  pPager->useJournal = useJournal && !memDb;
  pPager->noReadlock = noReadlock && readOnly;
  pPager->stmtOpen = 0;
  pPager->stmtInUse = 0;
  pPager->nRef = 0;
  pPager->dbSize = memDb-1;
  pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
  pPager->psAligned = FORCE_ALIGNMENT(pPager->pageSize);
  pPager->stmtSize = 0;
  pPager->stmtJSize = 0;
  pPager->nPage = 0;
  pPager->mxPage = 100;
  pPager->state = PAGER_UNLOCK;
  pPager->errMask = 0;
  pPager->tempFile = tempFile;
  pPager->memDb = memDb;
  pPager->readOnly = readOnly;
  pPager->needSync = 0;
  pPager->noSync = pPager->tempFile || !useJournal;
  pPager->fullSync = (pPager->noSync?0:1);
  pPager->pFirst = 0;
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->nExtra = FORCE_ALIGNMENT(nExtra);
  pPager->sectorSize = PAGER_SECTOR_SIZE;
  pPager->pBusyHandler = 0;
  memset(pPager->aHash, 0, sizeof(pPager->aHash));
  *ppPager = pPager;
  return SQLITE_OK;
}

/*
** Set the busy handler function.
*/
void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
  pPager->pBusyHandler = pBusyHandler;
}

/*
** Set the destructor for this pager.  If not NULL, the destructor is called
** when the reference count on each page reaches zero.  The destructor can
** be used to clean up information in the extra segment appended to each page.
**
** The destructor is not called as a result sqlite3pager_close().  
** Destructors are only called by sqlite3pager_unref().
*/
void sqlite3pager_set_destructor(Pager *pPager, void (*xDesc)(void*,int)){
  pPager->xDestructor = xDesc;
}

/*
** Set the reinitializer for this pager.  If not NULL, the reinitializer
** is called when the content of a page in cache is restored to its original
** value as a result of a rollback.  The callback gives higher-level code
** an opportunity to restore the EXTRA section to agree with the restored
** page data.
*/
void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){
  pPager->xReiniter = xReinit;
}

/*
** Set the page size.
**
** The page size must only be changed when the cache is empty.
*/
void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
  assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
  pPager->pageSize = pageSize;
  pPager->psAligned = FORCE_ALIGNMENT(pageSize);
}

/*
** Read the first N bytes from the beginning of the file into memory
** that pDest points to.  No error checking is done.
*/
void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
  memset(pDest, 0, N);
  if( MEMDB==0 ){
    sqlite3OsSeek(&pPager->fd, 0);
    sqlite3OsRead(&pPager->fd, pDest, N);
  }
}

/*
** Return the total number of pages in the disk file associated with
** pPager.
*/
int sqlite3pager_pagecount(Pager *pPager){
  i64 n;
  assert( pPager!=0 );
  if( pPager->dbSize>=0 ){
    return pPager->dbSize;
  }
  if( sqlite3OsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
    pPager->errMask |= PAGER_ERR_DISK;
    return 0;
  }
  n /= pPager->pageSize;
  if( !MEMDB && n==PENDING_BYTE/pPager->pageSize ){
    n++;
  }
  if( pPager->state!=PAGER_UNLOCK ){
    pPager->dbSize = n;
  }
  return n;
}

/*
** Forward declaration
*/
static int syncJournal(Pager*);


/*
** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate
** that the page is not part of any hash chain. This is required because the
** sqlite3pager_movepage() routine can leave a page in the 
** pNextFree/pPrevFree list that is not a part of any hash-chain.
*/
static void unlinkHashChain(Pager *pPager, PgHdr *pPg){
  if( pPg->pgno==0 ){
    /* If the page number is zero, then this page is not in any hash chain. */
    return;
  }
  if( pPg->pNextHash ){
    pPg->pNextHash->pPrevHash = pPg->pPrevHash;
  }
  if( pPg->pPrevHash ){
    assert( pPager->aHash[pager_hash(pPg->pgno)]!=pPg );
    pPg->pPrevHash->pNextHash = pPg->pNextHash;
  }else{
    int h = pager_hash(pPg->pgno);
    assert( pPager->aHash[h]==pPg );
    pPager->aHash[h] = pPg->pNextHash;
  }

  pPg->pgno = 0;
  pPg->pNextHash = pPg->pPrevHash = 0;
}

/*
** Unlink a page from the free list (the list of all pages where nRef==0)
** and from its hash collision chain.
*/
static void unlinkPage(PgHdr *pPg){
  Pager *pPager = pPg->pPager;

  /* Keep the pFirstSynced pointer pointing at the first synchronized page */
  if( pPg==pPager->pFirstSynced ){
    PgHdr *p = pPg->pNextFree;
    while( p && p->needSync ){ p = p->pNextFree; }
    pPager->pFirstSynced = p;
  }

  /* Unlink from the freelist */
  if( pPg->pPrevFree ){
    pPg->pPrevFree->pNextFree = pPg->pNextFree;
  }else{
    assert( pPager->pFirst==pPg );
    pPager->pFirst = pPg->pNextFree;
  }
  if( pPg->pNextFree ){
    pPg->pNextFree->pPrevFree = pPg->pPrevFree;
  }else{
    assert( pPager->pLast==pPg );
    pPager->pLast = pPg->pPrevFree;
  }
  pPg->pNextFree = pPg->pPrevFree = 0;

  /* Unlink from the pgno hash table */
  unlinkHashChain(pPager, pPg);
}

#ifndef SQLITE_OMIT_MEMORYDB
/*
** This routine is used to truncate an in-memory database.  Delete
** all pages whose pgno is larger than pPager->dbSize and is unreferenced.
** Referenced pages larger than pPager->dbSize are zeroed.
*/
static void memoryTruncate(Pager *pPager){
  PgHdr *pPg;
  PgHdr **ppPg;
  int dbSize = pPager->dbSize;

  ppPg = &pPager->pAll;
  while( (pPg = *ppPg)!=0 ){
    if( pPg->pgno<=dbSize ){
      ppPg = &pPg->pNextAll;
    }else if( pPg->nRef>0 ){
      memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
      ppPg = &pPg->pNextAll;
    }else{
      *ppPg = pPg->pNextAll;
      unlinkPage(pPg);
      sqliteFree(pPg);
      pPager->nPage--;
    }
  }
}
#else
#define memoryTruncate(p)
#endif

/*
** Try to obtain a lock on a file.  Invoke the busy callback if the lock
** is currently not available.  Repeate until the busy callback returns
** false or until the lock succeeds.
**
** Return SQLITE_OK on success and an error code if we cannot obtain
** the lock.
*/
static int pager_wait_on_lock(Pager *pPager, int locktype){
  int rc;
  assert( PAGER_SHARED==SHARED_LOCK );
  assert( PAGER_RESERVED==RESERVED_LOCK );
  assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
  if( pPager->state>=locktype ){
    rc = SQLITE_OK;
  }else{
    int busy = 1;
    do {
      rc = sqlite3OsLock(&pPager->fd, locktype);
    }while( rc==SQLITE_BUSY && 
        pPager->pBusyHandler && 
        pPager->pBusyHandler->xFunc && 
        pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++)
    );
    if( rc==SQLITE_OK ){
      pPager->state = locktype;
    }
  }
  return rc;
}

/*
** Truncate the file to the number of pages specified.
*/
int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
  int rc;
  sqlite3pager_pagecount(pPager);
  if( pPager->errMask!=0 ){
    rc = pager_errcode(pPager);
    return rc;
  }
  if( nPage>=(unsigned)pPager->dbSize ){
    return SQLITE_OK;
  }
  if( MEMDB ){
    pPager->dbSize = nPage;
    memoryTruncate(pPager);
    return SQLITE_OK;
  }
  rc = syncJournal(pPager);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  /* Get an exclusive lock on the database before truncating. */
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  rc = pager_truncate(pPager, nPage);
  if( rc==SQLITE_OK ){
    pPager->dbSize = nPage;
  }
  return rc;
}

/*
** Shutdown the page cache.  Free all memory and close all files.
**
** If a transaction was in progress when this routine is called, that
** transaction is rolled back.  All outstanding pages are invalidated
** and their memory is freed.  Any attempt to use a page associated
** with this page cache after this function returns will likely
** result in a coredump.
*/
int sqlite3pager_close(Pager *pPager){
  PgHdr *pPg, *pNext;
  switch( pPager->state ){
    case PAGER_RESERVED:
    case PAGER_SYNCED: 
    case PAGER_EXCLUSIVE: {
      /* We ignore any IO errors that occur during the rollback
      ** operation. So disable IO error simulation so that testing
      ** works more easily.
      */
#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN))
      extern int sqlite3_io_error_pending;
      int ioerr_cnt = sqlite3_io_error_pending;
      sqlite3_io_error_pending = -1;
#endif
      sqlite3pager_rollback(pPager);
#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN))
      sqlite3_io_error_pending = ioerr_cnt;
#endif
      if( !MEMDB ){
        sqlite3OsUnlock(&pPager->fd, NO_LOCK);
      }
      assert( pPager->journalOpen==0 );
      break;
    }
    case PAGER_SHARED: {
      if( !MEMDB ){
        sqlite3OsUnlock(&pPager->fd, NO_LOCK);
      }
      break;
    }
    default: {
      /* Do nothing */
      break;
    }
  }
  for(pPg=pPager->pAll; pPg; pPg=pNext){
#ifndef NDEBUG
    if( MEMDB ){
      PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
      assert( !pPg->alwaysRollback );
      assert( !pHist->pOrig );
      assert( !pHist->pStmt );
    }
#endif
    pNext = pPg->pNextAll;
    sqliteFree(pPg);
  }
  TRACE2("CLOSE %d\n", PAGERID(pPager));
  sqlite3OsClose(&pPager->fd);
  assert( pPager->journalOpen==0 );
  /* Temp files are automatically deleted by the OS
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */

  sqliteFree(pPager);
  return SQLITE_OK;
}

/*
** Return the page number for the given page data.
*/
Pgno sqlite3pager_pagenumber(void *pData){
  PgHdr *p = DATA_TO_PGHDR(pData);
  return p->pgno;
}

/*
** The page_ref() function increments the reference count for a page.
** If the page is currently on the freelist (the reference count is zero) then
** remove it from the freelist.
**
** For non-test systems, page_ref() is a macro that calls _page_ref()
** online of the reference count is zero.  For test systems, page_ref()
** is a real function so that we can set breakpoints and trace it.
*/
static void _page_ref(PgHdr *pPg){
  if( pPg->nRef==0 ){
    /* The page is currently on the freelist.  Remove it. */
    if( pPg==pPg->pPager->pFirstSynced ){
      PgHdr *p = pPg->pNextFree;
      while( p && p->needSync ){ p = p->pNextFree; }
      pPg->pPager->pFirstSynced = p;
    }
    if( pPg->pPrevFree ){
      pPg->pPrevFree->pNextFree = pPg->pNextFree;
    }else{
      pPg->pPager->pFirst = pPg->pNextFree;
    }
    if( pPg->pNextFree ){
      pPg->pNextFree->pPrevFree = pPg->pPrevFree;
    }else{
      pPg->pPager->pLast = pPg->pPrevFree;
    }
    pPg->pPager->nRef++;
  }
  pPg->nRef++;
  REFINFO(pPg);
}
#ifdef SQLITE_DEBUG
  static void page_ref(PgHdr *pPg){
    if( pPg->nRef==0 ){
      _page_ref(pPg);
    }else{
      pPg->nRef++;
      REFINFO(pPg);
    }
  }
#else
# define page_ref(P)   ((P)->nRef==0?_page_ref(P):(void)(P)->nRef++)
#endif

/*
** Increment the reference count for a page.  The input pointer is
** a reference to the page data.
*/
int sqlite3pager_ref(void *pData){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  page_ref(pPg);
  return SQLITE_OK;
}

/*
** Sync the journal.  In other words, make sure all the pages that have
** been written to the journal have actually reached the surface of the
** disk.  It is not safe to modify the original database file until after
** the journal has been synced.  If the original database is modified before
** the journal is synced and a power failure occurs, the unsynced journal
** data would be lost and we would be unable to completely rollback the
** database changes.  Database corruption would occur.
** 
** This routine also updates the nRec field in the header of the journal.
** (See comments on the pager_playback() routine for additional information.)
** If the sync mode is FULL, two syncs will occur.  First the whole journal
** is synced, then the nRec field is updated, then a second sync occurs.
**
** For temporary databases, we do not care if we are able to rollback
** after a power failure, so sync occurs.
**
** This routine clears the needSync field of every page current held in
** memory.
*/
static int syncJournal(Pager *pPager){
  PgHdr *pPg;
  int rc = SQLITE_OK;

  /* Sync the journal before modifying the main database
  ** (assuming there is a journal and it needs to be synced.)
  */
  if( pPager->needSync ){
    if( !pPager->tempFile ){
      assert( pPager->journalOpen );
      /* assert( !pPager->noSync ); // noSync might be set if synchronous
      ** was turned off after the transaction was started.  Ticket #615 */
#ifndef NDEBUG
      {
        /* Make sure the pPager->nRec counter we are keeping agrees
        ** with the nRec computed from the size of the journal file.
        */
        i64 jSz;
        rc = sqlite3OsFileSize(&pPager->jfd, &jSz);
        if( rc!=0 ) return rc;
        assert( pPager->journalOff==jSz );
      }
#endif
      {
        /* Write the nRec value into the journal file header. If in
        ** full-synchronous mode, sync the journal first. This ensures that
        ** all data has really hit the disk before nRec is updated to mark
        ** it as a candidate for rollback. 
        */
        if( pPager->fullSync ){
          TRACE2("SYNC journal of %d\n", PAGERID(pPager));
          rc = sqlite3OsSync(&pPager->jfd);
          if( rc!=0 ) return rc;
        }
        sqlite3OsSeek(&pPager->jfd, pPager->journalHdr + sizeof(aJournalMagic));
        rc = write32bits(&pPager->jfd, pPager->nRec);
        if( rc ) return rc;

        sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
      }
      TRACE2("SYNC journal of %d\n", PAGERID(pPager));
      rc = sqlite3OsSync(&pPager->jfd);
      if( rc!=0 ) return rc;
      pPager->journalStarted = 1;
    }
    pPager->needSync = 0;

    /* Erase the needSync flag from every page.
    */
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
      pPg->needSync = 0;
    }
    pPager->pFirstSynced = pPager->pFirst;
  }

#ifndef NDEBUG
  /* If the Pager.needSync flag is clear then the PgHdr.needSync
  ** flag must also be clear for all pages.  Verify that this
  ** invariant is true.
  */
  else{
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
      assert( pPg->needSync==0 );
    }
    assert( pPager->pFirstSynced==pPager->pFirst );
  }
#endif

  return rc;
}

/*
** Given a list of pages (connected by the PgHdr.pDirty pointer) write
** every one of those pages out to the database file and mark them all
** as clean.
*/
static int pager_write_pagelist(PgHdr *pList){
  Pager *pPager;
  int rc;

  if( pList==0 ) return SQLITE_OK;
  pPager = pList->pPager;

  /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
  ** database file. If there is already an EXCLUSIVE lock, the following
  ** calls to sqlite3OsLock() are no-ops.
  **
  ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
  ** through an intermediate state PENDING.   A PENDING lock prevents new
  ** readers from attaching to the database but is unsufficient for us to
  ** write.  The idea of a PENDING lock is to prevent new readers from
  ** coming in while we wait for existing readers to clear.
  **
  ** While the pager is in the RESERVED state, the original database file
  ** is unchanged and we can rollback without having to playback the
  ** journal into the original database file.  Once we transition to
  ** EXCLUSIVE, it means the database file has been changed and any rollback
  ** will require a journal playback.
  */
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  while( pList ){
    assert( pList->dirty );
    sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize);
    /* If there are dirty pages in the page cache with page numbers greater
    ** than Pager.dbSize, this means sqlite3pager_truncate() was called to
    ** make the file smaller (presumably by auto-vacuum code). Do not write
    ** any such pages to the file.
    */
    if( pList->pgno<=pPager->dbSize ){
      CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
      TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
      rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize);
      CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
      pPager->nWrite++;
    }
#ifndef NDEBUG
    else{
      TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno);
    }
#endif
    if( rc ) return rc;
    pList->dirty = 0;
#ifdef SQLITE_CHECK_PAGES
    pList->pageHash = pager_pagehash(pList);
#endif
    pList = pList->pDirty;
  }
  return SQLITE_OK;
}

/*
** Collect every dirty page into a dirty list and
** return a pointer to the head of that list.  All pages are
** collected even if they are still in use.
*/
static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
  PgHdr *p, *pList;
  pList = 0;
  for(p=pPager->pAll; p; p=p->pNextAll){
    if( p->dirty ){
      p->pDirty = pList;
      pList = p;
    }
  }
  return pList;
}

/*
** Acquire a page.
**
** A read lock on the disk file is obtained when the first page is acquired. 
** This read lock is dropped when the last page is released.
**
** A _get works for any page number greater than 0.  If the database
** file is smaller than the requested page, then no actual disk
** read occurs and the memory image of the page is initialized to
** all zeros.  The extra data appended to a page is always initialized
** to zeros the first time a page is loaded into memory.
**
** The acquisition might fail for several reasons.  In all cases,
** an appropriate error code is returned and *ppPage is set to NULL.
**
** See also sqlite3pager_lookup().  Both this routine and _lookup() attempt
** to find a page in the in-memory cache first.  If the page is not already
** in memory, this routine goes to disk to read it in whereas _lookup()
** just returns 0.  This routine acquires a read-lock the first time it
** has to go to disk, and could also playback an old journal if necessary.
** Since _lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
  PgHdr *pPg;
  int rc, n;

  /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
  ** number greater than this, or zero, is requested.
  */
  if( pgno>PAGER_MAX_PGNO || pgno==0 ){
    return SQLITE_CORRUPT;
  }

  /* Make sure we have not hit any critical errors.
  */ 
  assert( pPager!=0 );
  *ppPage = 0;
  if( pPager->errMask & ~(PAGER_ERR_FULL) ){
    return pager_errcode(pPager);
  }

  /* If this is the first page accessed, then get a SHARED lock
  ** on the database file.
  */
  if( pPager->nRef==0 && !MEMDB ){
    if( !pPager->noReadlock ){
      rc = pager_wait_on_lock(pPager, SHARED_LOCK);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }

    /* If a journal file exists, and there is no RESERVED lock on the
    ** database file, then it either needs to be played back or deleted.
    */
    if( pPager->useJournal && 
        sqlite3OsFileExists(pPager->zJournal) &&
        !sqlite3OsCheckReservedLock(&pPager->fd) 
    ){
       int rc;

       /* Get an EXCLUSIVE lock on the database file. At this point it is
       ** important that a RESERVED lock is not obtained on the way to the
       ** EXCLUSIVE lock. If it were, another process might open the
       ** database file, detect the RESERVED lock, and conclude that the
       ** database is safe to read while this process is still rolling it 
       ** back.
       ** 
       ** Because the intermediate RESERVED lock is not requested, the
       ** second process will get to this point in the code and fail to
       ** obtain it's own EXCLUSIVE lock on the database file.
       */
       rc = sqlite3OsLock(&pPager->fd, EXCLUSIVE_LOCK);
       if( rc!=SQLITE_OK ){
         sqlite3OsUnlock(&pPager->fd, NO_LOCK);
         pPager->state = PAGER_UNLOCK;
         return rc;
       }
       pPager->state = PAGER_EXCLUSIVE;

       /* Open the journal for reading only.  Return SQLITE_BUSY if
       ** we are unable to open the journal file. 
       **
       ** The journal file does not need to be locked itself.  The
       ** journal file is never open unless the main database file holds
       ** a write lock, so there is never any chance of two or more
       ** processes opening the journal at the same time.
       */
       rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
       if( rc!=SQLITE_OK ){
         sqlite3OsUnlock(&pPager->fd, NO_LOCK);
         pPager->state = PAGER_UNLOCK;
         return SQLITE_BUSY;
       }
       pPager->journalOpen = 1;
       pPager->journalStarted = 0;
       pPager->journalOff = 0;
       pPager->setMaster = 0;
       pPager->journalHdr = 0;

       /* Playback and delete the journal.  Drop the database write
       ** lock and reacquire the read lock.
       */
       rc = pager_playback(pPager);
       if( rc!=SQLITE_OK ){
         return rc;
       }
    }
    pPg = 0;
  }else{
    /* Search for page in cache */
    pPg = pager_lookup(pPager, pgno);
    if( MEMDB && pPager->state==PAGER_UNLOCK ){
      pPager->state = PAGER_SHARED;
    }
  }
  if( pPg==0 ){
    /* The requested page is not in the page cache. */
    int h;
    pPager->nMiss++;
    if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ){
      /* Create a new page */
      pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->psAligned
                              + sizeof(u32) + pPager->nExtra
                              + MEMDB*sizeof(PgHistory) );
      if( pPg==0 ){
        if( !MEMDB ){
          pager_unwritelock(pPager);
        }
        pPager->errMask |= PAGER_ERR_MEM;
        return SQLITE_NOMEM;
      }
      memset(pPg, 0, sizeof(*pPg));
      if( MEMDB ){
        memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
      }
      pPg->pPager = pPager;
      pPg->pNextAll = pPager->pAll;
      pPager->pAll = pPg;
      pPager->nPage++;
    }else{
      /* Find a page to recycle.  Try to locate a page that does not
      ** require us to do an fsync() on the journal.
      */
      pPg = pPager->pFirstSynced;

      /* If we could not find a page that does not require an fsync()
      ** on the journal file then fsync the journal file.  This is a
      ** very slow operation, so we work hard to avoid it.  But sometimes
      ** it can't be helped.
      */
      if( pPg==0 ){
        int rc = syncJournal(pPager);
        if( rc!=0 ){
          sqlite3pager_rollback(pPager);
          return SQLITE_IOERR;
        }
        if( pPager->fullSync ){
          /* If in full-sync mode, write a new journal header into the
	  ** journal file. This is done to avoid ever modifying a journal
	  ** header that is involved in the rollback of pages that have
	  ** already been written to the database (in case the header is
	  ** trashed when the nRec field is updated).
          */
          pPager->nRec = 0;
          assert( pPager->journalOff > 0 );
          rc = writeJournalHdr(pPager);
          if( rc!=0 ){
            sqlite3pager_rollback(pPager);
            return SQLITE_IOERR;
          }
        }
        pPg = pPager->pFirst;
      }
      assert( pPg->nRef==0 );

      /* Write the page to the database file if it is dirty.
      */
      if( pPg->dirty ){
        assert( pPg->needSync==0 );
        pPg->pDirty = 0;
        rc = pager_write_pagelist( pPg );
        if( rc!=SQLITE_OK ){
          sqlite3pager_rollback(pPager);
          return SQLITE_IOERR;
        }
      }
      assert( pPg->dirty==0 );

      /* If the page we are recycling is marked as alwaysRollback, then
      ** set the global alwaysRollback flag, thus disabling the
      ** sqlite_dont_rollback() optimization for the rest of this transaction.
      ** It is necessary to do this because the page marked alwaysRollback
      ** might be reloaded at a later time but at that point we won't remember
      ** that is was marked alwaysRollback.  This means that all pages must
      ** be marked as alwaysRollback from here on out.
      */
      if( pPg->alwaysRollback ){
        pPager->alwaysRollback = 1;
      }

      /* Unlink the old page from the free list and the hash table
      */
      unlinkPage(pPg);
      pPager->nOvfl++;
    }
    pPg->pgno = pgno;
    if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
      sqlite3CheckMemory(pPager->aInJournal, pgno/8);
      assert( pPager->journalOpen );
      pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
      pPg->needSync = 0;
    }else{
      pPg->inJournal = 0;
      pPg->needSync = 0;
    }
    if( pPager->aInStmt && (int)pgno<=pPager->stmtSize
             && (pPager->aInStmt[pgno/8] & (1<<(pgno&7)))!=0 ){
      page_add_to_stmt_list(pPg);
    }else{
      page_remove_from_stmt_list(pPg);
    }
    pPg->dirty = 0;
    pPg->nRef = 1;
    REFINFO(pPg);
    pPager->nRef++;
    h = pager_hash(pgno);
    pPg->pNextHash = pPager->aHash[h];
    pPager->aHash[h] = pPg;
    if( pPg->pNextHash ){
      assert( pPg->pNextHash->pPrevHash==0 );
      pPg->pNextHash->pPrevHash = pPg;
    }
    if( pPager->nExtra>0 ){
      memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
    }
    n = sqlite3pager_pagecount(pPager);
    if( pPager->errMask!=0 ){
      sqlite3pager_unref(PGHDR_TO_DATA(pPg));
      rc = pager_errcode(pPager);
      return rc;
    }
    if( n<(int)pgno ){
      memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
    }else{
      int rc;
      assert( MEMDB==0 );
      sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);
      rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize);
      TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
      CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
      if( rc!=SQLITE_OK ){
        i64 fileSize;
        if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
               || fileSize>=pgno*pPager->pageSize ){
          sqlite3pager_unref(PGHDR_TO_DATA(pPg));
          return rc;
        }else{
          memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
        }
      }else{
        pPager->nRead++;
      }
    }
#ifdef SQLITE_CHECK_PAGES
    pPg->pageHash = pager_pagehash(pPg);
#endif
  }else{
    /* The requested page is in the page cache. */
    pPager->nHit++;
    page_ref(pPg);
  }
  *ppPage = PGHDR_TO_DATA(pPg);
  return SQLITE_OK;
}

/*
** Acquire a page if it is already in the in-memory cache.  Do
** not read the page from disk.  Return a pointer to the page,
** or 0 if the page is not in cache.
**
** See also sqlite3pager_get().  The difference between this routine
** and sqlite3pager_get() is that _get() will go to the disk and read
** in the page if the page is not already in cache.  This routine
** returns NULL if the page is not in cache or if a disk I/O error 
** has ever happened.
*/
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno){
  PgHdr *pPg;

  assert( pPager!=0 );
  assert( pgno!=0 );
  if( pPager->errMask & ~(PAGER_ERR_FULL) ){
    return 0;
  }
  pPg = pager_lookup(pPager, pgno);
  if( pPg==0 ) return 0;
  page_ref(pPg);
  return PGHDR_TO_DATA(pPg);
}

/*
** Release a page.
**
** If the number of references to the page drop to zero, then the
** page is added to the LRU list.  When all references to all pages
** are released, a rollback occurs and the lock on the database is
** removed.
*/
int sqlite3pager_unref(void *pData){
  PgHdr *pPg;

  /* Decrement the reference count for this page
  */
  pPg = DATA_TO_PGHDR(pData);
  assert( pPg->nRef>0 );
  pPg->nRef--;
  REFINFO(pPg);

  CHECK_PAGE(pPg);

  /* When the number of references to a page reach 0, call the
  ** destructor and add the page to the freelist.
  */
  if( pPg->nRef==0 ){
    Pager *pPager;
    pPager = pPg->pPager;
    pPg->pNextFree = 0;
    pPg->pPrevFree = pPager->pLast;
    pPager->pLast = pPg;
    if( pPg->pPrevFree ){
      pPg->pPrevFree->pNextFree = pPg;
    }else{
      pPager->pFirst = pPg;
    }
    if( pPg->needSync==0 && pPager->pFirstSynced==0 ){
      pPager->pFirstSynced = pPg;
    }
    if( pPager->xDestructor ){
      pPager->xDestructor(pData, pPager->pageSize);
    }
  
    /* When all pages reach the freelist, drop the read lock from
    ** the database file.
    */
    pPager->nRef--;
    assert( pPager->nRef>=0 );
    if( pPager->nRef==0 && !MEMDB ){
      pager_reset(pPager);
    }
  }
  return SQLITE_OK;
}

/*
** Create a journal file for pPager.  There should already be a RESERVED
** or EXCLUSIVE lock on the database file when this routine is called.
**
** Return SQLITE_OK if everything.  Return an error code and release the
** write lock if anything goes wrong.
*/
static int pager_open_journal(Pager *pPager){
  int rc;
  assert( !MEMDB );
  assert( pPager->state>=PAGER_RESERVED );
  assert( pPager->journalOpen==0 );
  assert( pPager->useJournal );
  sqlite3pager_pagecount(pPager);
  pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
  if( pPager->aInJournal==0 ){
    rc = SQLITE_NOMEM;
    goto failed_to_open_journal;
  }
  rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
  pPager->journalOff = 0;
  pPager->setMaster = 0;
  pPager->journalHdr = 0;
  if( rc!=SQLITE_OK ){
    goto failed_to_open_journal;
  }
  sqlite3OsOpenDirectory(pPager->zDirectory, &pPager->jfd);
  pPager->journalOpen = 1;
  pPager->journalStarted = 0;
  pPager->needSync = 0;
  pPager->alwaysRollback = 0;
  pPager->nRec = 0;
  if( pPager->errMask!=0 ){
    rc = pager_errcode(pPager);
    return rc;
  }
  pPager->origDbSize = pPager->dbSize;

  rc = writeJournalHdr(pPager);

  if( pPager->stmtAutoopen && rc==SQLITE_OK ){
    rc = sqlite3pager_stmt_begin(pPager);
  }
  if( rc!=SQLITE_OK ){
    rc = pager_unwritelock(pPager);
    if( rc==SQLITE_OK ){
      rc = SQLITE_FULL;
    }
  }
  return rc;

failed_to_open_journal:
  sqliteFree(pPager->aInJournal);
  pPager->aInJournal = 0;
  sqlite3OsUnlock(&pPager->fd, NO_LOCK);
  pPager->state = PAGER_UNLOCK;
  return rc;
}

/*
** Acquire a write-lock on the database.  The lock is removed when
** the any of the following happen:
**
**   *  sqlite3pager_commit() is called.
**   *  sqlite3pager_rollback() is called.
**   *  sqlite3pager_close() is called.
**   *  sqlite3pager_unref() is called to on every outstanding page.
**
** The first parameter to this routine is a pointer to any open page of the
** database file.  Nothing changes about the page - it is used merely to
** acquire a pointer to the Pager structure and as proof that there is
** already a read-lock on the database.
**
** The second parameter indicates how much space in bytes to reserve for a
** master journal file-name at the start of the journal when it is created.
**
** A journal file is opened if this is not a temporary file.  For temporary
** files, the opening of the journal file is deferred until there is an
** actual need to write to the journal.
**
** If the database is already reserved for writing, this routine is a no-op.
**
** If exFlag is true, go ahead and get an EXCLUSIVE lock on the file
** immediately instead of waiting until we try to flush the cache.  The
** exFlag is ignored if a transaction is already active.
*/
int sqlite3pager_begin(void *pData, int exFlag){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  Pager *pPager = pPg->pPager;
  int rc = SQLITE_OK;
  assert( pPg->nRef>0 );
  assert( pPager->state!=PAGER_UNLOCK );
  if( pPager->state==PAGER_SHARED ){
    assert( pPager->aInJournal==0 );
    if( MEMDB ){
      pPager->state = PAGER_EXCLUSIVE;
      pPager->origDbSize = pPager->dbSize;
    }else{
      if( SQLITE_BUSY_RESERVED_LOCK || exFlag ){
        rc = pager_wait_on_lock(pPager, RESERVED_LOCK);
      }else{
        rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK);
      }
      if( rc==SQLITE_OK ){
        pPager->state = PAGER_RESERVED;
        if( exFlag ){
          rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
        }
      }
      if( rc!=SQLITE_OK ){
        return rc;
      }
      pPager->dirtyCache = 0;
      TRACE2("TRANSACTION %d\n", PAGERID(pPager));
      if( pPager->useJournal && !pPager->tempFile ){
        rc = pager_open_journal(pPager);
      }
    }
  }
  return rc;
}

/*
** Mark a data page as writeable.  The page is written into the journal 
** if it is not there already.  This routine must be called before making
** changes to a page.
**
** The first time this routine is called, the pager creates a new
** journal and acquires a RESERVED lock on the database.  If the RESERVED
** lock could not be acquired, this routine returns SQLITE_BUSY.  The
** calling routine must check for that return value and be careful not to
** change any page data until this routine returns SQLITE_OK.
**
** If the journal file could not be written because the disk is full,
** then this routine returns SQLITE_FULL and does an immediate rollback.
** All subsequent write attempts also return SQLITE_FULL until there
** is a call to sqlite3pager_commit() or sqlite3pager_rollback() to
** reset.
*/
int sqlite3pager_write(void *pData){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  Pager *pPager = pPg->pPager;
  int rc = SQLITE_OK;

  /* Check for errors
  */
  if( pPager->errMask ){ 
    return pager_errcode(pPager);
  }
  if( pPager->readOnly ){
    return SQLITE_PERM;
  }

  assert( !pPager->setMaster );

  CHECK_PAGE(pPg);

  /* Mark the page as dirty.  If the page has already been written
  ** to the journal then we can return right away.
  */
  pPg->dirty = 1;
  if( pPg->inJournal && (pPg->inStmt || pPager->stmtInUse==0) ){
    pPager->dirtyCache = 1;
  }else{

    /* If we get this far, it means that the page needs to be
    ** written to the transaction journal or the ckeckpoint journal
    ** or both.
    **
    ** First check to see that the transaction journal exists and
    ** create it if it does not.
    */
    assert( pPager->state!=PAGER_UNLOCK );
    rc = sqlite3pager_begin(pData, 0);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    assert( pPager->state>=PAGER_RESERVED );
    if( !pPager->journalOpen && pPager->useJournal ){
      rc = pager_open_journal(pPager);
      if( rc!=SQLITE_OK ) return rc;
    }
    assert( pPager->journalOpen || !pPager->useJournal );
    pPager->dirtyCache = 1;
  
    /* The transaction journal now exists and we have a RESERVED or an
    ** EXCLUSIVE lock on the main database file.  Write the current page to
    ** the transaction journal if it is not there already.
    */
    if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
      if( (int)pPg->pgno <= pPager->origDbSize ){
        int szPg;
        u32 saved;
        if( MEMDB ){
          PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
          TRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
          assert( pHist->pOrig==0 );
          pHist->pOrig = sqliteMallocRaw( pPager->pageSize );
          if( pHist->pOrig ){
            memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
          }
        }else{
          u32 cksum;
          CODEC(pPager, pData, pPg->pgno, 7);
          cksum = pager_cksum(pPager, pPg->pgno, pData);
          saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
          store32bits(cksum, pPg, pPager->pageSize);
          szPg = pPager->pageSize+8;
          store32bits(pPg->pgno, pPg, -4);
          rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
          pPager->journalOff += szPg;
          TRACE4("JOURNAL %d page %d needSync=%d\n",
                  PAGERID(pPager), pPg->pgno, pPg->needSync);
          CODEC(pPager, pData, pPg->pgno, 0);
          *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
          if( rc!=SQLITE_OK ){
            sqlite3pager_rollback(pPager);
            pPager->errMask |= PAGER_ERR_FULL;
            return rc;
          }
          pPager->nRec++;
          assert( pPager->aInJournal!=0 );
          pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
          pPg->needSync = !pPager->noSync;
          if( pPager->stmtInUse ){
            pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
            page_add_to_stmt_list(pPg);
          }
        }
      }else{
        pPg->needSync = !pPager->journalStarted && !pPager->noSync;
        TRACE4("APPEND %d page %d needSync=%d\n",
                PAGERID(pPager), pPg->pgno, pPg->needSync);
      }
      if( pPg->needSync ){
        pPager->needSync = 1;
      }
      pPg->inJournal = 1;
    }
  
    /* If the statement journal is open and the page is not in it,
    ** then write the current page to the statement journal.  Note that
    ** the statement journal format differs from the standard journal format
    ** in that it omits the checksums and the header.
    */
    if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){
      assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
      if( MEMDB ){
        PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
        assert( pHist->pStmt==0 );
        pHist->pStmt = sqliteMallocRaw( pPager->pageSize );
        if( pHist->pStmt ){
          memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize);
        }
        TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
      }else{
        store32bits(pPg->pgno, pPg, -4);
        CODEC(pPager, pData, pPg->pgno, 7);
        rc = sqlite3OsWrite(&pPager->stfd,((char*)pData)-4, pPager->pageSize+4);
        TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
        CODEC(pPager, pData, pPg->pgno, 0);
        if( rc!=SQLITE_OK ){
          sqlite3pager_rollback(pPager);
          pPager->errMask |= PAGER_ERR_FULL;
          return rc;
        }
        pPager->stmtNRec++;
        assert( pPager->aInStmt!=0 );
        pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
      }
      page_add_to_stmt_list(pPg);
    }
  }

  /* Update the database size and return.
  */
  if( pPager->dbSize<(int)pPg->pgno ){
    pPager->dbSize = pPg->pgno;
    if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
      pPager->dbSize++;
    }
  }
  return rc;
}

/*
** Return TRUE if the page given in the argument was previously passed
** to sqlite3pager_write().  In other words, return TRUE if it is ok
** to change the content of the page.
*/
int sqlite3pager_iswriteable(void *pData){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  return pPg->dirty;
}

#ifndef SQLITE_OMIT_VACUUM
/*
** Replace the content of a single page with the information in the third
** argument.
*/
int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){
  void *pPage;
  int rc;

  rc = sqlite3pager_get(pPager, pgno, &pPage);
  if( rc==SQLITE_OK ){
    rc = sqlite3pager_write(pPage);
    if( rc==SQLITE_OK ){
      memcpy(pPage, pData, pPager->pageSize);
    }
    sqlite3pager_unref(pPage);
  }
  return rc;
}
#endif

/*
** A call to this routine tells the pager that it is not necessary to
** write the information on page "pgno" back to the disk, even though
** that page might be marked as dirty.
**
** The overlying software layer calls this routine when all of the data
** on the given page is unused.  The pager marks the page as clean so
** that it does not get written to disk.
**
** Tests show that this optimization, together with the
** sqlite3pager_dont_rollback() below, more than double the speed
** of large INSERT operations and quadruple the speed of large DELETEs.
**
** When this routine is called, set the alwaysRollback flag to true.
** Subsequent calls to sqlite3pager_dont_rollback() for the same page
** will thereafter be ignored.  This is necessary to avoid a problem
** where a page with data is added to the freelist during one part of
** a transaction then removed from the freelist during a later part
** of the same transaction and reused for some other purpose.  When it
** is first added to the freelist, this routine is called.  When reused,
** the dont_rollback() routine is called.  But because the page contains
** critical data, we still need to be sure it gets rolled back in spite
** of the dont_rollback() call.
*/
void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
  PgHdr *pPg;

  if( MEMDB ) return;

  pPg = pager_lookup(pPager, pgno);
  pPg->alwaysRollback = 1;
  if( pPg && pPg->dirty ){
    if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
      /* If this pages is the last page in the file and the file has grown
      ** during the current transaction, then do NOT mark the page as clean.
      ** When the database file grows, we must make sure that the last page
      ** gets written at least once so that the disk file will be the correct
      ** size. If you do not write this page and the size of the file
      ** on the disk ends up being too small, that can lead to database
      ** corruption during the next transaction.
      */
    }else{
      TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager));
      pPg->dirty = 0;
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
  }
}

/*
** A call to this routine tells the pager that if a rollback occurs,
** it is not necessary to restore the data on the given page.  This
** means that the pager does not have to record the given page in the
** rollback journal.
*/
void sqlite3pager_dont_rollback(void *pData){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  Pager *pPager = pPg->pPager;

  if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return;
  if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
  if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
    assert( pPager->aInJournal!=0 );
    pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
    pPg->inJournal = 1;
    if( pPager->stmtInUse ){
      pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
      page_add_to_stmt_list(pPg);
    }
    TRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager));
  }
  if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){
    assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
    assert( pPager->aInStmt!=0 );
    pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
    page_add_to_stmt_list(pPg);
  }
}


#ifndef SQLITE_OMIT_MEMORYDB
/*
** Clear a PgHistory block
*/
static void clearHistory(PgHistory *pHist){
  sqliteFree(pHist->pOrig);
  sqliteFree(pHist->pStmt);
  pHist->pOrig = 0;
  pHist->pStmt = 0;
}
#else
#define clearHistory(x)
#endif

/*
** Commit all changes to the database and release the write lock.
**
** If the commit fails for any reason, a rollback attempt is made
** and an error code is returned.  If the commit worked, SQLITE_OK
** is returned.
*/
int sqlite3pager_commit(Pager *pPager){
  int rc;
  PgHdr *pPg;

  if( pPager->errMask==PAGER_ERR_FULL ){
    rc = sqlite3pager_rollback(pPager);
    if( rc==SQLITE_OK ){
      rc = SQLITE_FULL;
    }
    return rc;
  }
  if( pPager->errMask!=0 ){
    rc = pager_errcode(pPager);
    return rc;
  }
  if( pPager->state<PAGER_RESERVED ){
    return SQLITE_ERROR;
  }
  TRACE2("COMMIT %d\n", PAGERID(pPager));
  if( MEMDB ){
    pPg = pager_get_all_dirty_pages(pPager);
    while( pPg ){
      clearHistory(PGHDR_TO_HIST(pPg, pPager));
      pPg->dirty = 0;
      pPg->inJournal = 0;
      pPg->inStmt = 0;
      pPg->pPrevStmt = pPg->pNextStmt = 0;
      pPg = pPg->pDirty;
    }
#ifndef NDEBUG
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
      PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
      assert( !pPg->alwaysRollback );
      assert( !pHist->pOrig );
      assert( !pHist->pStmt );
    }
#endif
    pPager->pStmt = 0;
    pPager->state = PAGER_SHARED;
    return SQLITE_OK;
  }
  if( pPager->dirtyCache==0 ){
    /* Exit early (without doing the time-consuming sqlite3OsSync() calls)
    ** if there have been no changes to the database file. */
    assert( pPager->needSync==0 );
    rc = pager_unwritelock(pPager);
    pPager->dbSize = -1;
    return rc;
  }
  assert( pPager->journalOpen );
  rc = sqlite3pager_sync(pPager, 0, 0);
  if( rc!=SQLITE_OK ){
    goto commit_abort;
  }
  rc = pager_unwritelock(pPager);
  pPager->dbSize = -1;
  return rc;

  /* Jump here if anything goes wrong during the commit process.
  */
commit_abort:
  sqlite3pager_rollback(pPager);
  return rc;
}

/*
** Rollback all changes.  The database falls back to PAGER_SHARED mode.
** All in-memory cache pages revert to their original data contents.
** The journal is deleted.
**
** This routine cannot fail unless some other process is not following
** the correct locking protocol (SQLITE_PROTOCOL) or unless some other
** process is writing trash into the journal file (SQLITE_CORRUPT) or
** unless a prior malloc() failed (SQLITE_NOMEM).  Appropriate error
** codes are returned for all these occasions.  Otherwise,
** SQLITE_OK is returned.
*/
int sqlite3pager_rollback(Pager *pPager){
  int rc;
  TRACE2("ROLLBACK %d\n", PAGERID(pPager));
  if( MEMDB ){
    PgHdr *p;
    for(p=pPager->pAll; p; p=p->pNextAll){
      PgHistory *pHist;
      assert( !p->alwaysRollback );
      if( !p->dirty ){
        assert( !((PgHistory *)PGHDR_TO_HIST(p, pPager))->pOrig );
        assert( !((PgHistory *)PGHDR_TO_HIST(p, pPager))->pStmt );
        continue;
      }

      pHist = PGHDR_TO_HIST(p, pPager);
      if( pHist->pOrig ){
        memcpy(PGHDR_TO_DATA(p), pHist->pOrig, pPager->pageSize);
        TRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, PAGERID(pPager));
      }else{
        TRACE3("PAGE %d is clean on %d\n", p->pgno, PAGERID(pPager));
      }
      clearHistory(pHist);
      p->dirty = 0;
      p->inJournal = 0;
      p->inStmt = 0;
      p->pPrevStmt = p->pNextStmt = 0;

      if( pPager->xReiniter ){
        pPager->xReiniter(PGHDR_TO_DATA(p), pPager->pageSize);
      }
      
    }
    pPager->pStmt = 0;
    pPager->dbSize = pPager->origDbSize;
    memoryTruncate(pPager);
    pPager->stmtInUse = 0;
    pPager->state = PAGER_SHARED;
    return SQLITE_OK;
  }

  if( !pPager->dirtyCache || !pPager->journalOpen ){
    rc = pager_unwritelock(pPager);
    pPager->dbSize = -1;
    return rc;
  }

  if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
    if( pPager->state>=PAGER_EXCLUSIVE ){
      pager_playback(pPager);
    }
    return pager_errcode(pPager);
  }
  if( pPager->state==PAGER_RESERVED ){
    int rc2;
    rc = pager_reload_cache(pPager);
    rc2 = pager_unwritelock(pPager);
    if( rc==SQLITE_OK ){
      rc = rc2;
    }
  }else{
    rc = pager_playback(pPager);
  }
  if( rc!=SQLITE_OK ){
    rc = SQLITE_CORRUPT;  /* bkpt-CORRUPT */
    pPager->errMask |= PAGER_ERR_CORRUPT;
  }
  pPager->dbSize = -1;
  return rc;
}

/*
** Return TRUE if the database file is opened read-only.  Return FALSE
** if the database is (in theory) writable.
*/
int sqlite3pager_isreadonly(Pager *pPager){
  return pPager->readOnly;
}

/*
** This routine is used for testing and analysis only.
*/
int *sqlite3pager_stats(Pager *pPager){
  static int a[11];
  a[0] = pPager->nRef;
  a[1] = pPager->nPage;
  a[2] = pPager->mxPage;
  a[3] = pPager->dbSize;
  a[4] = pPager->state;
  a[5] = pPager->errMask;
  a[6] = pPager->nHit;
  a[7] = pPager->nMiss;
  a[8] = pPager->nOvfl;
  a[9] = pPager->nRead;
  a[10] = pPager->nWrite;
  return a;
}

/*
** Set the statement rollback point.
**
** This routine should be called with the transaction journal already
** open.  A new statement journal is created that can be used to rollback
** changes of a single SQL command within a larger transaction.
*/
int sqlite3pager_stmt_begin(Pager *pPager){
  int rc;
  char zTemp[SQLITE_TEMPNAME_SIZE];
  assert( !pPager->stmtInUse );
  assert( pPager->dbSize>=0 );
  TRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
  if( MEMDB ){
    pPager->stmtInUse = 1;
    pPager->stmtSize = pPager->dbSize;
    return SQLITE_OK;
  }
  if( !pPager->journalOpen ){
    pPager->stmtAutoopen = 1;
    return SQLITE_OK;
  }
  assert( pPager->journalOpen );
  pPager->aInStmt = sqliteMalloc( pPager->dbSize/8 + 1 );
  if( pPager->aInStmt==0 ){
    sqlite3OsLock(&pPager->fd, SHARED_LOCK);
    return SQLITE_NOMEM;
  }
#ifndef NDEBUG
  rc = sqlite3OsFileSize(&pPager->jfd, &pPager->stmtJSize);
  if( rc ) goto stmt_begin_failed;
  assert( pPager->stmtJSize == pPager->journalOff );
#endif
  pPager->stmtJSize = pPager->journalOff;
  pPager->stmtSize = pPager->dbSize;
  pPager->stmtHdrOff = 0;
  pPager->stmtCksum = pPager->cksumInit;
  if( !pPager->stmtOpen ){
    rc = sqlite3pager_opentemp(zTemp, &pPager->stfd);
    if( rc ) goto stmt_begin_failed;
    pPager->stmtOpen = 1;
    pPager->stmtNRec = 0;
  }
  pPager->stmtInUse = 1;
  return SQLITE_OK;
 
stmt_begin_failed:
  if( pPager->aInStmt ){
    sqliteFree(pPager->aInStmt);
    pPager->aInStmt = 0;
  }
  return rc;
}

/*
** Commit a statement.
*/
int sqlite3pager_stmt_commit(Pager *pPager){
  if( pPager->stmtInUse ){
    PgHdr *pPg, *pNext;
    TRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
    if( !MEMDB ){
      sqlite3OsSeek(&pPager->stfd, 0);
      /* sqlite3OsTruncate(&pPager->stfd, 0); */
      sqliteFree( pPager->aInStmt );
      pPager->aInStmt = 0;
    }
    for(pPg=pPager->pStmt; pPg; pPg=pNext){
      pNext = pPg->pNextStmt;
      assert( pPg->inStmt );
      pPg->inStmt = 0;
      pPg->pPrevStmt = pPg->pNextStmt = 0;
      if( MEMDB ){
        PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
        sqliteFree(pHist->pStmt);
        pHist->pStmt = 0;
      }
    }
    pPager->stmtNRec = 0;
    pPager->stmtInUse = 0;
    pPager->pStmt = 0;
  }
  pPager->stmtAutoopen = 0;
  return SQLITE_OK;
}

/*
** Rollback a statement.
*/
int sqlite3pager_stmt_rollback(Pager *pPager){
  int rc;
  if( pPager->stmtInUse ){
    TRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
    if( MEMDB ){
      PgHdr *pPg;
      for(pPg=pPager->pStmt; pPg; pPg=pPg->pNextStmt){
        PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
        if( pHist->pStmt ){
          memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize);
          sqliteFree(pHist->pStmt);
          pHist->pStmt = 0;
        }
      }
      pPager->dbSize = pPager->stmtSize;
      memoryTruncate(pPager);
      rc = SQLITE_OK;
    }else{
      rc = pager_stmt_playback(pPager);
    }
    sqlite3pager_stmt_commit(pPager);
  }else{
    rc = SQLITE_OK;
  }
  pPager->stmtAutoopen = 0;
  return rc;
}

/*
** Return the full pathname of the database file.
*/
const char *sqlite3pager_filename(Pager *pPager){
  return pPager->zFilename;
}

/*
** Return the directory of the database file.
*/
const char *sqlite3pager_dirname(Pager *pPager){
  return pPager->zDirectory;
}

/*
** Return the full pathname of the journal file.
*/
const char *sqlite3pager_journalname(Pager *pPager){
  return pPager->zJournal;
}

/*
** Set the codec for this pager
*/
void sqlite3pager_set_codec(
  Pager *pPager,
  void (*xCodec)(void*,void*,Pgno,int),
  void *pCodecArg
){
  pPager->xCodec = xCodec;
  pPager->pCodecArg = pCodecArg;
}

/*
** This routine is called to increment the database file change-counter,
** stored at byte 24 of the pager file.
*/
static int pager_incr_changecounter(Pager *pPager){
  void *pPage;
  PgHdr *pPgHdr;
  u32 change_counter;
  int rc;

  /* Open page 1 of the file for writing. */
  rc = sqlite3pager_get(pPager, 1, &pPage);
  if( rc!=SQLITE_OK ) return rc;
  rc = sqlite3pager_write(pPage);
  if( rc!=SQLITE_OK ) return rc;

  /* Read the current value at byte 24. */
  pPgHdr = DATA_TO_PGHDR(pPage);
  change_counter = retrieve32bits(pPgHdr, 24);

  /* Increment the value just read and write it back to byte 24. */
  change_counter++;
  store32bits(change_counter, pPgHdr, 24);

  /* Release the page reference. */
  sqlite3pager_unref(pPage);
  return SQLITE_OK;
}

/*
** Sync the database file for the pager pPager. zMaster points to the name
** of a master journal file that should be written into the individual
** journal file. zMaster may be NULL, which is interpreted as no master
** journal (a single database transaction).
**
** This routine ensures that the journal is synced, all dirty pages written
** to the database file and the database file synced. The only thing that
** remains to commit the transaction is to delete the journal file (or
** master journal file if specified).
**
** Note that if zMaster==NULL, this does not overwrite a previous value
** passed to an sqlite3pager_sync() call.
**
** If parameter nTrunc is non-zero, then the pager file is truncated to
** nTrunc pages (this is used by auto-vacuum databases).
*/
int sqlite3pager_sync(Pager *pPager, const char *zMaster, Pgno nTrunc){
  int rc = SQLITE_OK;

  TRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", 
      pPager->zFilename, zMaster, nTrunc);

  /* If this is an in-memory db, or no pages have been written to, or this
  ** function has already been called, it is a no-op.
  */
  if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){
    PgHdr *pPg;
    assert( pPager->journalOpen );

    /* If a master journal file name has already been written to the
    ** journal file, then no sync is required. This happens when it is
    ** written, then the process fails to upgrade from a RESERVED to an
    ** EXCLUSIVE lock. The next time the process tries to commit the
    ** transaction the m-j name will have already been written.
    */
    if( !pPager->setMaster ){
      rc = pager_incr_changecounter(pPager);
      if( rc!=SQLITE_OK ) goto sync_exit;
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( nTrunc!=0 ){
        /* If this transaction has made the database smaller, then all pages
        ** being discarded by the truncation must be written to the journal
        ** file.
        */
        Pgno i;
        void *pPage;
        for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
          if( !(pPager->aInJournal[i/8] & (1<<(i&7))) ){
            rc = sqlite3pager_get(pPager, i, &pPage);
            if( rc!=SQLITE_OK ) goto sync_exit;
            rc = sqlite3pager_write(pPage);
            sqlite3pager_unref(pPage);
            if( rc!=SQLITE_OK ) goto sync_exit;
          }
        } 
      }
#endif
      rc = writeMasterJournal(pPager, zMaster);
      if( rc!=SQLITE_OK ) goto sync_exit;
      rc = syncJournal(pPager);
      if( rc!=SQLITE_OK ) goto sync_exit;
    }

#ifndef SQLITE_OMIT_AUTOVACUUM
    if( nTrunc!=0 ){
      rc = sqlite3pager_truncate(pPager, nTrunc);
      if( rc!=SQLITE_OK ) goto sync_exit;
    }
#endif

    /* Write all dirty pages to the database file */
    pPg = pager_get_all_dirty_pages(pPager);
    rc = pager_write_pagelist(pPg);
    if( rc!=SQLITE_OK ) goto sync_exit;

    /* Sync the database file. */
    if( !pPager->noSync ){
      rc = sqlite3OsSync(&pPager->fd);
    }

    pPager->state = PAGER_SYNCED;
  }

sync_exit:
  return rc;
}

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Move the page identified by pData to location pgno in the file. 
**
** There must be no references to the current page pgno. If current page
** pgno is not already in the rollback journal, it is not written there by
** by this routine. The same applies to the page pData refers to on entry to
** this routine.
**
** References to the page refered to by pData remain valid. Updating any
** meta-data associated with page pData (i.e. data stored in the nExtra bytes
** allocated along with the page) is the responsibility of the caller.
**
** A transaction must be active when this routine is called, however it is 
** illegal to call this routine if a statment transaction is active.
*/
int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  PgHdr *pPgOld; 
  int h;
  Pgno needSyncPgno = 0;

  assert( !pPager->stmtInUse );
  assert( pPg->nRef>0 );

  TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", 
      PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);

  if( pPg->needSync ){
    needSyncPgno = pPg->pgno;
    assert( pPg->inJournal );
    assert( pPg->dirty );
    assert( pPager->needSync );
  }

  /* Unlink pPg from it's hash-chain */
  unlinkHashChain(pPager, pPg);

  /* If the cache contains a page with page-number pgno, remove it
  ** from it's hash chain. Also, if the PgHdr.needSync was set for 
  ** page pgno before the 'move' operation, it needs to be retained 
  ** for the page moved there.
  */
  pPgOld = pager_lookup(pPager, pgno);
  if( pPgOld ){
    assert( pPgOld->nRef==0 );
    unlinkHashChain(pPager, pPgOld);
    pPgOld->dirty = 0;
    if( pPgOld->needSync ){
      assert( pPgOld->inJournal );
      pPg->inJournal = 1;
      pPg->needSync = 1;
      assert( pPager->needSync );
    }
  }

  /* Change the page number for pPg and insert it into the new hash-chain. */
  pPg->pgno = pgno;
  h = pager_hash(pgno);
  if( pPager->aHash[h] ){
    assert( pPager->aHash[h]->pPrevHash==0 );
    pPager->aHash[h]->pPrevHash = pPg;
  }
  pPg->pNextHash = pPager->aHash[h];
  pPager->aHash[h] = pPg;
  pPg->pPrevHash = 0;

  pPg->dirty = 1;
  pPager->dirtyCache = 1;

  if( needSyncPgno ){
    /* If needSyncPgno is non-zero, then the journal file needs to be 
    ** sync()ed before any data is written to database file page needSyncPgno.
    ** Currently, no such page exists in the page-cache and the 
    ** Pager.aInJournal bit has been set. This needs to be remedied by loading
    ** the page into the pager-cache and setting the PgHdr.needSync flag.
    **
    ** The sqlite3pager_get() call may cause the journal to sync. So make
    ** sure the Pager.needSync flag is set too.
    */
    int rc;
    void *pNeedSync;
    assert( pPager->needSync );
    rc = sqlite3pager_get(pPager, needSyncPgno, &pNeedSync);
    if( rc!=SQLITE_OK ) return rc;
    pPager->needSync = 1;
    DATA_TO_PGHDR(pNeedSync)->needSync = 1;
    DATA_TO_PGHDR(pNeedSync)->inJournal = 1;
    DATA_TO_PGHDR(pNeedSync)->dirty = 1;
    sqlite3pager_unref(pNeedSync);
  }

  return SQLITE_OK;
}
#endif

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Return the current state of the file lock for the given pager.
** The return value is one of NO_LOCK, SHARED_LOCK, RESERVED_LOCK,
** PENDING_LOCK, or EXCLUSIVE_LOCK.
*/
int sqlite3pager_lockstate(Pager *pPager){
#ifdef OS_TEST
  return pPager->fd->fd.locktype;
#else
  return pPager->fd.locktype;
#endif
}
#endif

#ifdef SQLITE_DEBUG
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlite3pager_refdump(Pager *pPager){
  PgHdr *pPg;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    if( pPg->nRef<=0 ) continue;
    sqlite3DebugPrintf("PAGE %3d addr=%p nRef=%d\n", 
       pPg->pgno, PGHDR_TO_DATA(pPg), pPg->nRef);
  }
}
#endif
Added SQLite.Interop/src/pager.h.






























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2001 September 15
**
** 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 header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.1 2005/03/01 16:04:31 rmsimpson Exp $
*/

/*
** The default size of a database page.
*/
#ifndef SQLITE_DEFAULT_PAGE_SIZE
# define SQLITE_DEFAULT_PAGE_SIZE 1024
#endif

/* Maximum page size.  The upper bound on this value is 65536 (a limit
** imposed by the 2-byte size of cell array pointers.)  The
** maximum page size determines the amount of stack space allocated
** by many of the routines in pager.c and btree.c  On embedded architectures
** or any machine where memory and especially stack memory is limited,
** one may wish to chose a smaller value for the maximum page size.
*/
#ifndef SQLITE_MAX_PAGE_SIZE
# define SQLITE_MAX_PAGE_SIZE 8192
#endif

/*
** Maximum number of pages in one database.
*/
#define SQLITE_MAX_PAGE 1073741823

/*
** The type used to represent a page number.  The first page in a file
** is called page 1.  0 is used to represent "not a page".
*/
typedef unsigned int Pgno;

/*
** Each open file is managed by a separate instance of the "Pager" structure.
*/
typedef struct Pager Pager;

/*
** Allowed values for the flags parameter to sqlite3pager_open().
**
** NOTE: This values must match the corresponding BTREE_ values in btree.h.
*/
#define PAGER_OMIT_JOURNAL  0x0001    /* Do not use a rollback journal */
#define PAGER_NO_READLOCK   0x0002    /* Omit readlocks on readonly files */


/*
** See source code comments for a detailed description of the following
** routines:
*/
int sqlite3pager_open(Pager **ppPager, const char *zFilename,
                     int nExtra, int flags);
void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler);
void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
void sqlite3pager_set_pagesize(Pager*, int);
void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
void sqlite3pager_set_cachesize(Pager*, int);
int sqlite3pager_close(Pager *pPager);
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
int sqlite3pager_ref(void*);
int sqlite3pager_unref(void*);
Pgno sqlite3pager_pagenumber(void*);
int sqlite3pager_write(void*);
int sqlite3pager_iswriteable(void*);
int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void*);
int sqlite3pager_pagecount(Pager*);
int sqlite3pager_truncate(Pager*,Pgno);
int sqlite3pager_begin(void*, int exFlag);
int sqlite3pager_commit(Pager*);
int sqlite3pager_sync(Pager*,const char *zMaster, Pgno);
int sqlite3pager_rollback(Pager*);
int sqlite3pager_isreadonly(Pager*);
int sqlite3pager_stmt_begin(Pager*);
int sqlite3pager_stmt_commit(Pager*);
int sqlite3pager_stmt_rollback(Pager*);
void sqlite3pager_dont_rollback(void*);
void sqlite3pager_dont_write(Pager*, Pgno);
int *sqlite3pager_stats(Pager*);
void sqlite3pager_set_safety_level(Pager*,int);
const char *sqlite3pager_filename(Pager*);
const char *sqlite3pager_dirname(Pager*);
const char *sqlite3pager_journalname(Pager*);
int sqlite3pager_rename(Pager*, const char *zNewName);
void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
int sqlite3pager_movepage(Pager*,void*,Pgno);

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
int sqlite3pager_lockstate(Pager*);
#endif

#ifdef SQLITE_TEST
void sqlite3pager_refdump(Pager*);
int pager3_refinfo_enable;
#endif
Added SQLite.Interop/src/parse.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
/* Driver template for the LEMON parser generator.
** The author disclaims copyright to this source code.
*/
/* First off, code is include which follows the "include" declaration
** in the input file. */
#include <stdio.h>
#line 33 "parse.y"

#include "sqliteInt.h"
#include "parse.h"

/*
** An instance of this structure holds information about the
** LIMIT clause of a SELECT statement.
*/
struct LimitVal {
  Expr *pLimit;    /* The LIMIT expression.  NULL if there is no limit */
  Expr *pOffset;   /* The OFFSET expression.  NULL if there is none */
};

/*
** An instance of this structure is used to store the LIKE,
** GLOB, NOT LIKE, and NOT GLOB operators.
*/
struct LikeOp {
  int opcode;   /* Either TK_GLOB or TK_LIKE */
  int not;      /* True if the NOT keyword is present */
};

/*
** An instance of the following structure describes the event of a
** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
** TK_DELETE, or TK_INSTEAD.  If the event is of the form
**
**      UPDATE ON (a,b,c)
**
** Then the "b" IdList records the list "a,b,c".
*/
struct TrigEvent { int a; IdList * b; };

/*
** An instance of this structure holds the ATTACH key and the key type.
*/
struct AttachKey { int type;  Token key; };

#line 48 "parse.c"
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
*/
/* 
** These constants (all generated automatically by the parser generator)
** specify the various kinds of tokens (terminals) that the parser
** understands. 
**
** Each symbol here is a terminal symbol in the grammar.
*/
/* Make sure the INTERFACE macro is defined.
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/* The next thing included is series of defines which control
** various aspects of the generated parser.
**    YYCODETYPE         is the data type used for storing terminal
**                       and nonterminal numbers.  "unsigned char" is
**                       used if there are fewer than 250 terminals
**                       and nonterminals.  "int" is used otherwise.
**    YYNOCODE           is a number of type YYCODETYPE which corresponds
**                       to no legal terminal or nonterminal number.  This
**                       number is used to fill in empty slots of the hash 
**                       table.
**    YYFALLBACK         If defined, this indicates that one or more tokens
**                       have fall-back values which should be used if the
**                       original value of the token will not parse.
**    YYACTIONTYPE       is the data type used for storing terminal
**                       and nonterminal numbers.  "unsigned char" is
**                       used if there are fewer than 250 rules and
**                       states combined.  "int" is used otherwise.
**    sqlite3ParserTOKENTYPE     is the data type used for minor tokens given 
**                       directly to the parser from the tokenizer.
**    YYMINORTYPE        is the data type used for all minor tokens.
**                       This is typically a union of many types, one of
**                       which is sqlite3ParserTOKENTYPE.  The entry in the union
**                       for base tokens is called "yy0".
**    YYSTACKDEPTH       is the maximum depth of the parser's stack.
**    sqlite3ParserARG_SDECL     A static variable declaration for the %extra_argument
**    sqlite3ParserARG_PDECL     A parameter declaration for the %extra_argument
**    sqlite3ParserARG_STORE     Code to store %extra_argument into yypParser
**    sqlite3ParserARG_FETCH     Code to extract %extra_argument from yypParser
**    YYNSTATE           the combined number of states.
**    YYNRULE            the number of rules in the grammar
**    YYERRORSYMBOL      is the code number of the error symbol.  If not
**                       defined, then do no error processing.
*/
#define YYCODETYPE unsigned char
#define YYNOCODE 239
#define YYACTIONTYPE unsigned short int
#define sqlite3ParserTOKENTYPE Token
typedef union {
  sqlite3ParserTOKENTYPE yy0;
  struct AttachKey yy40;
  int yy60;
  struct TrigEvent yy62;
  struct {int value; int mask;} yy243;
  struct LikeOp yy258;
  ExprList* yy266;
  IdList* yy272;
  Select* yy331;
  struct LimitVal yy348;
  Token yy406;
  SrcList* yy427;
  Expr* yy454;
  TriggerStep* yy455;
  int yy477;
} YYMINORTYPE;
#define YYSTACKDEPTH 100
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
#define YYNSTATE 564
#define YYNRULE 305
#define YYERRORSYMBOL 141
#define YYERRSYMDT yy477
#define YYFALLBACK 1
#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)

/* Next are that tables used to determine what action to take based on the
** current state and lookahead token.  These tables are used to implement
** functions that take a state number and lookahead value and return an
** action integer.  
**
** Suppose the action integer is N.  Then the action is determined as
** follows
**
**   0 <= N < YYNSTATE                  Shift N.  That is, push the lookahead
**                                      token onto the stack and goto state N.
**
**   YYNSTATE <= N < YYNSTATE+YYNRULE   Reduce by rule N-YYNSTATE.
**
**   N == YYNSTATE+YYNRULE              A syntax error has occurred.
**
**   N == YYNSTATE+YYNRULE+1            The parser accepts its input.
**
**   N == YYNSTATE+YYNRULE+2            No such action.  Denotes unused
**                                      slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as
**
**      yy_action[ yy_shift_ofst[S] + X ]
**
** If the index value yy_shift_ofst[S]+X is out of range or if the value
** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
** and that yy_default[S] should be used instead.  
**
** The formula above is for computing the action when the lookahead is
** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_ofst[] array is used in place of
** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
** YY_SHIFT_USE_DFLT.
**
** The following are the tables generated in this section:
**
**  yy_action[]        A single table containing all actions.
**  yy_lookahead[]     A table containing the lookahead for each entry in
**                     yy_action.  Used to detect hash collisions.
**  yy_shift_ofst[]    For each state, the offset into yy_action for
**                     shifting terminals.
**  yy_reduce_ofst[]   For each state, the offset into yy_action for
**                     shifting non-terminals after a reduce.
**  yy_default[]       Default action for each state.
*/
static const YYACTIONTYPE yy_action[] = {
 /*     0 */   263,  261,  261,  154,  124,  126,  128,  130,  132,  134,
 /*    10 */   136,  138,  140,  142,  350,  567,  145,  641,  261,  369,
 /*    20 */   144,  114,  116,  112,  118,    7,  124,  126,  128,  130,
 /*    30 */   132,  134,  136,  138,  140,  142,  136,  138,  140,  142,
 /*    40 */   110,   94,  146,  157,  162,  167,  156,  161,  120,  122,
 /*    50 */   114,  116,  112,  118,    9,  124,  126,  128,  130,  132,
 /*    60 */   134,  136,  138,  140,  142,  574,  223,  262,  262,  124,
 /*    70 */   126,  128,  130,  132,  134,  136,  138,  140,  142,   13,
 /*    80 */    96,  145,   13,    2,  262,  144,    4,   78,  371,   92,
 /*    90 */    10,  373,  380,  385,  132,  134,  136,  138,  140,  142,
 /*   100 */    75,    3,  562,  388,  296,  110,   94,  146,  157,  162,
 /*   110 */   167,  156,  161,  120,  122,  114,  116,  112,  118,   77,
 /*   120 */   124,  126,  128,  130,  132,  134,  136,  138,  140,  142,
 /*   130 */   145,   65,  573,   13,  144,   11,  371,   66,  292,  373,
 /*   140 */   380,  385,  870,    1,  563,   14,   15,    4,   14,   15,
 /*   150 */   172,  388,   51,  665,  110,   94,  146,  157,  162,  167,
 /*   160 */   156,  161,  120,  122,  114,  116,  112,  118,   72,  124,
 /*   170 */   126,  128,  130,  132,  134,  136,  138,  140,  142,   51,
 /*   180 */    37,  341,   40,   59,   67,   69,  305,  336,  107,  106,
 /*   190 */   108,  847,  572,   34,  338,   96,  366,  349,   13,   14,
 /*   200 */    15,  371,   12,  145,  373,  380,  385,  144,  564,   40,
 /*   210 */    59,   67,   69,  305,  336,   75,  388,    3,  562,  190,
 /*   220 */   345,  338,   44,   45,   95,  460,  802,  110,   94,  146,
 /*   230 */   157,  162,  167,  156,  161,  120,  122,  114,  116,  112,
 /*   240 */   118,  575,  124,  126,  128,  130,  132,  134,  136,  138,
 /*   250 */   140,  142,   20,   48,  800,  364,  362,  101,  102,  367,
 /*   260 */   499,  295,   49,  596,   14,   15,  191,   32,   33,   27,
 /*   270 */   148,  403,   96,   50,  147,  534,   46,  145,  494,  466,
 /*   280 */   456,  144,  580,  279,   36,  340,   47,  399,  309,   81,
 /*   290 */   368,  401,   75,  335,  398,  505,  176,  501,  150,  151,
 /*   300 */   197,  110,   94,  146,  157,  162,  167,  156,  161,  120,
 /*   310 */   122,  114,  116,  112,  118,   77,  124,  126,  128,  130,
 /*   320 */   132,  134,  136,  138,  140,  142,  149,  280,  258,  169,
 /*   330 */    96,   39,  281,   13,  298,  367,   96,  175,   22,  335,
 /*   340 */    28,  145,  188,  402,   33,  144,  217,    6,    5,  171,
 /*   350 */    75,  173,  174,   25,  176,  581,   75,   57,   58,  507,
 /*   360 */   235,  351,  356,  357,  265,  110,   94,  146,  157,  162,
 /*   370 */   167,  156,  161,  120,  122,  114,  116,  112,  118,  503,
 /*   380 */   124,  126,  128,  130,  132,  134,  136,  138,  140,  142,
 /*   390 */   457,   77,  243,  294,   48,  227,  236,  293,  297,   14,
 /*   400 */    15,  288,   96,   49,  217,  152,  222,  163,  168,  278,
 /*   410 */    24,   13,  687,   13,   50,  145,  518,  201,  152,  144,
 /*   420 */   163,  168,   75,  358,  582,  171,  176,  173,  174,  263,
 /*   430 */   171,  261,  173,  174,  354,  356,  357,  588,  211,  110,
 /*   440 */    94,  146,  157,  162,  167,  156,  161,  120,  122,  114,
 /*   450 */   116,  112,  118,  654,  124,  126,  128,  130,  132,  134,
 /*   460 */   136,  138,  140,  142,  303,   13,  688,   96,  250,  817,
 /*   470 */    96,   16,   17,   18,  246,   81,  216,   14,   15,   14,
 /*   480 */    15,  145,   13,  406,  435,  144,   13,   75,  487,  387,
 /*   490 */    75,  493,  248,  258,  235,  660,  358,  262,  310,  852,
 /*   500 */   171,   26,  173,  174,  253,  110,   94,  146,  157,  162,
 /*   510 */   167,  156,  161,  120,  122,  114,  116,  112,  118,  397,
 /*   520 */   124,  126,  128,  130,  132,  134,  136,  138,  140,  142,
 /*   530 */   229,   14,   15,  489,  250,  152,  252,  163,  168,  171,
 /*   540 */   839,  173,  174,  360,  361,   96,  145,  533,   14,   15,
 /*   550 */   144,  866,   14,   15,  801,  442,  312,  275,  255,  453,
 /*   560 */   850,  338,  251,  535,  536,   75,  662,  247,   13,  493,
 /*   570 */   110,   94,  146,  157,  162,  167,  156,  161,  120,  122,
 /*   580 */   114,  116,  112,  118,  845,  124,  126,  128,  130,  132,
 /*   590 */   134,  136,  138,  140,  142,  726,   96,  171,   96,  173,
 /*   600 */   174,  171,  252,  173,  174,  152,  583,  163,  168,   42,
 /*   610 */   720,  525,   96,  145,  441,  271,   75,  144,   75,  170,
 /*   620 */   302,  640,   91,   31,  358,  313,  320,  322,  251,  432,
 /*   630 */   434,  433,   75,  844,   14,   15,  176,  110,   94,  146,
 /*   640 */   157,  162,  167,  156,  161,  120,  122,  114,  116,  112,
 /*   650 */   118,   77,  124,  126,  128,  130,  132,  134,  136,  138,
 /*   660 */   140,  142,  171,   96,  173,  174,  331,   52,  171,   96,
 /*   670 */   173,  174,   96,  195,  213,  207,   29,  348,  145,   54,
 /*   680 */   310,  318,  144,   75,  455,  342,  217,   93,   83,   75,
 /*   690 */    30,  452,   75,  109,  587,  286,  111,  171,  265,  173,
 /*   700 */   174,  319,  110,   94,  146,  157,  162,  167,  156,  161,
 /*   710 */   120,  122,  114,  116,  112,  118,   77,  124,  126,  128,
 /*   720 */   130,  132,  134,  136,  138,  140,  142,  244,   96,  187,
 /*   730 */    96,   96,  810,  331,  214,  266,  215,   35,  312,   96,
 /*   740 */    96,  479,  328,  145,  623,   38,  327,  144,   75,  455,
 /*   750 */    75,   75,  113,  689,  115,  117,  315,  461,  426,   75,
 /*   760 */    75,   77,  463,  119,  121,  407,  325,  110,  165,  146,
 /*   770 */   157,  162,  167,  156,  161,  120,  122,  114,  116,  112,
 /*   780 */   118,   77,  124,  126,  128,  130,  132,  134,  136,  138,
 /*   790 */   140,  142,   42,   96,   96,   96,   96,  824,  273,  159,
 /*   800 */   415,   96,  410,  272,   96,  273,  479,   41,  145,  332,
 /*   810 */   537,   43,  144,   75,   75,   75,   75,  123,  125,  127,
 /*   820 */   129,   75,  465,   64,   75,  131,   53,  463,  133,  158,
 /*   830 */   317,  316,  265,   94,  146,  157,  162,  167,  156,  161,
 /*   840 */   120,  122,  114,  116,  112,  118,  219,  124,  126,  128,
 /*   850 */   130,  132,  134,  136,  138,  140,  142,   96,  689,   96,
 /*   860 */    96,  532,   96,  331,  299,   96,  215,   96,   96,  283,
 /*   870 */    96,  261,  219,   96,  145,   96,  840,   75,  144,   75,
 /*   880 */    75,  135,   75,  137,  139,   75,  141,   75,   75,  143,
 /*   890 */    75,  153,  155,   75,  164,   75,  376,  166,   56,  178,
 /*   900 */   146,  157,  162,  167,  156,  161,  120,  122,  114,  116,
 /*   910 */   112,  118,  652,  124,  126,  128,  130,  132,  134,  136,
 /*   920 */   138,  140,  142,   76,   96,   96,   96,   71,  438,  364,
 /*   930 */   362,  437,   96,   96,   96,   96,  331,  262,  233,  332,
 /*   940 */    96,   55,  331,  439,   75,   75,   75,  331,  180,  182,
 /*   950 */   184,  199,   75,   75,   75,   75,  196,  198,  208,  210,
 /*   960 */    75,  107,  106,  108,  212,  720,  326,  177,  327,  382,
 /*   970 */   430,  431,  107,  106,  108,  391,  548,   61,   96,   96,
 /*   980 */   449,  471,  458,   45,  183,  181,  300,   96,  476,  352,
 /*   990 */    96,  353,  179,   73,   74,  343,  346,   95,   75,   75,
 /*  1000 */   290,   96,  224,  240,  345,  275,   42,   75,   95,   76,
 /*  1010 */    75,  245,  332,   71,  277,  383,  275,  327,  332,   96,
 /*  1020 */    75,   75,  404,  332,  287,  386,   96,  392,  421,  327,
 /*  1030 */   101,  102,  103,  104,  105,  185,  189,  199,   96,   75,
 /*  1040 */    96,  101,  102,  427,  414,   60,   75,  107,  106,  108,
 /*  1050 */   474,  470,  486,  177,   77,  450,  421,  327,   75,  484,
 /*  1060 */    75,  273,  478,  436,  491,  492,  423,  490,  421,  421,
 /*  1070 */   183,  181,  421,  421,  483,  421,   77,  421,  179,   73,
 /*  1080 */    74,  476,  244,   95,   77,   81,  526,  860,  490,  421,
 /*  1090 */   689,  522,   62,   64,  500,   70,  597,   63,  523,   68,
 /*  1100 */   598,   76,   81,   79,   81,   71,  502,  504,   84,   80,
 /*  1110 */   506,  510,  244,  514,  239,  520,  101,  102,  103,  104,
 /*  1120 */   105,  185,  189,   77,  546,  241,   82,  558,   86,  199,
 /*  1130 */    85,  225,   90,   87,   97,   88,   99,  142,   89,  107,
 /*  1140 */   106,  108,  160,   98,  516,  177,  100,  218,  666,  667,
 /*  1150 */   668,  186,  209,  193,  192,  194,  200,  204,  203,  202,
 /*  1160 */   206,  205,  183,  181,  219,  220,  221,  226,  228,  232,
 /*  1170 */   179,   73,   74,  230,  233,   95,  234,  231,  237,  242,
 /*  1180 */   238,  215,  260,  249,  257,  276,  267,  254,  256,  259,
 /*  1190 */   264,  269,  270,   76,  274,  282,  301,   71,  219,  268,
 /*  1200 */   285,  291,  284,  306,  324,  307,  311,  308,  101,  102,
 /*  1210 */   103,  104,  105,  185,  189,  803,  355,  329,  375,  304,
 /*  1220 */   314,  199,  321,  337,  330,  365,  334,  372,  309,  333,
 /*  1230 */   323,  107,  106,  108,  344,  339,  347,  177,  374,  378,
 /*  1240 */   400,  359,  370,  377,  381,  379,  384,  389,  363,  390,
 /*  1250 */   393,  394,  396,   54,  183,  181,  289,  408,  395,  409,
 /*  1260 */   411,  413,  179,   73,   74,  412,  416,   95,  417,  420,
 /*  1270 */   428,  422,  832,  429,  443,  440,  444,  837,  838,   76,
 /*  1280 */   446,  445,  448,   71,  451,  808,  809,  459,  454,  447,
 /*  1290 */   418,  727,  728,  831,  464,  462,  846,  457,  469,  419,
 /*  1300 */   101,  102,  103,  104,  105,  185,  189,  199,  467,  468,
 /*  1310 */   472,  473,  475,  424,  848,  477,  480,  107,  106,  108,
 /*  1320 */   425,  482,  488,  177,  485,  849,  481,  495,  496,  851,
 /*  1330 */   659,  661,  816,  858,  497,  509,  511,  719,  513,  515,
 /*  1340 */   183,  181,  722,  517,  725,  519,  521,  524,  179,   73,
 /*  1350 */    74,  818,  528,   95,  530,  819,  820,  531,  538,  821,
 /*  1360 */     8,  822,  539,  823,  549,   19,   21,   23,  405,  541,
 /*  1370 */   542,  544,  543,  859,  547,  861,  862,  865,  545,  540,
 /*  1380 */   551,  867,  557,  555,  552,  550,  101,  102,  103,  104,
 /*  1390 */   105,  185,  189,  554,  560,  559,  561,  868,  529,  545,
 /*  1400 */   460,  545,  545,  545,  545,  527,  545,  553,  545,  545,
 /*  1410 */   545,  545,  556,  545,  545,  545,  545,  545,  545,  545,
 /*  1420 */   545,  545,  545,  545,  545,  545,  545,  545,  545,  545,
 /*  1430 */   545,  545,  545,  545,  545,  545,  545,  545,  545,  545,
 /*  1440 */   545,  545,  545,  545,  545,  545,  545,  545,  545,  545,
 /*  1450 */   545,  545,  545,  508,  512,  456,  545,  545,  545,  498,
 /*  1460 */   545,  545,  545,  545,   81,
};
static const YYCODETYPE yy_lookahead[] = {
 /*     0 */    24,   26,   26,   78,   79,   80,   81,   82,   83,   84,
 /*    10 */    85,   86,   87,   88,   22,    9,   40,   23,   26,   25,
 /*    20 */    44,   74,   75,   76,   77,    9,   79,   80,   81,   82,
 /*    30 */    83,   84,   85,   86,   87,   88,   85,   86,   87,   88,
 /*    40 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   73,
 /*    50 */    74,   75,   76,   77,  148,   79,   80,   81,   82,   83,
 /*    60 */    84,   85,   86,   87,   88,    9,   25,   92,   92,   79,
 /*    70 */    80,   81,   82,   83,   84,   85,   86,   87,   88,   26,
 /*    80 */   150,   40,   26,  144,   92,   44,  147,  157,   94,   48,
 /*    90 */   149,   97,   98,   99,   83,   84,   85,   86,   87,   88,
 /*   100 */   170,    9,   10,  109,  174,   64,   65,   66,   67,   68,
 /*   110 */    69,   70,   71,   72,   73,   74,   75,   76,   77,  189,
 /*   120 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,
 /*   130 */    40,   29,    9,   26,   44,   12,   94,   35,   85,   97,
 /*   140 */    98,   99,  142,  143,  144,   92,   93,  147,   92,   93,
 /*   150 */   112,  109,   66,  115,   64,   65,   66,   67,   68,   69,
 /*   160 */    70,   71,   72,   73,   74,   75,   76,   77,   22,   79,
 /*   170 */    80,   81,   82,   83,   84,   85,   86,   87,   88,   66,
 /*   180 */    94,   95,   96,   97,   98,   99,  100,  101,   60,   61,
 /*   190 */    62,   17,    9,  160,  108,  150,  163,  164,   26,   92,
 /*   200 */    93,   94,  150,   40,   97,   98,   99,   44,    0,   96,
 /*   210 */    97,   98,   99,  100,  101,  170,  109,    9,   10,  174,
 /*   220 */    92,  108,  186,  187,   96,   51,  136,   64,   65,   66,
 /*   230 */    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
 /*   240 */    77,    9,   79,   80,   81,   82,   83,   84,   85,   86,
 /*   250 */    87,   88,  149,   18,   17,   83,   84,  129,  130,  150,
 /*   260 */    20,   23,   27,  117,   92,   93,  221,  158,  159,   22,
 /*   270 */    40,   24,  150,   38,   44,  103,   41,   40,  104,  105,
 /*   280 */   106,   44,    9,  157,  168,  169,   51,  177,  178,  115,
 /*   290 */   181,  182,  170,  177,  184,   55,  174,   57,   68,   69,
 /*   300 */   137,   64,   65,   66,   67,   68,   69,   70,   71,   72,
 /*   310 */    73,   74,   75,   76,   77,  189,   79,   80,   81,   82,
 /*   320 */    83,   84,   85,   86,   87,   88,   96,  201,  202,   22,
 /*   330 */   150,  169,  206,   26,  212,  150,  150,   23,  149,  177,
 /*   340 */   155,   40,   23,  158,  159,   44,  224,  145,  146,  111,
 /*   350 */   170,  113,  114,  151,  174,    9,  170,   13,   14,  157,
 /*   360 */   174,  165,  166,  167,  163,   64,   65,   66,   67,   68,
 /*   370 */    69,   70,   71,   72,   73,   74,   75,   76,   77,  139,
 /*   380 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,
 /*   390 */    64,  189,  212,  112,   18,  209,  210,  116,   23,   92,
 /*   400 */    93,  200,  150,   27,  224,  217,  218,  219,  220,   22,
 /*   410 */   149,   26,   23,   26,   38,   40,  214,   41,  217,   44,
 /*   420 */   219,  220,  170,  227,    9,  111,  174,  113,  114,   24,
 /*   430 */   111,   26,  113,  114,  165,  166,  167,    9,  137,   64,
 /*   440 */    65,   66,   67,   68,   69,   70,   71,   72,   73,   74,
 /*   450 */    75,   76,   77,  127,   79,   80,   81,   82,   83,   84,
 /*   460 */    85,   86,   87,   88,   23,   26,   23,  150,   25,    9,
 /*   470 */   150,   13,   14,   15,   25,  115,  224,   92,   93,   92,
 /*   480 */    93,   40,   26,  153,   47,   44,   26,  170,  128,  171,
 /*   490 */   170,  174,  201,  202,  174,    9,  227,   92,   45,    9,
 /*   500 */   111,  152,  113,  114,  119,   64,   65,   66,   67,   68,
 /*   510 */    69,   70,   71,   72,   73,   74,   75,   76,   77,   66,
 /*   520 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,
 /*   530 */   210,   92,   93,  216,   25,  217,   93,  219,  220,  111,
 /*   540 */   103,  113,  114,  129,  130,  150,   40,  150,   92,   93,
 /*   550 */    44,    9,   92,   93,   17,  225,  103,  150,  119,  229,
 /*   560 */     9,  108,  119,  166,  167,  170,    9,  118,   26,  174,
 /*   570 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   73,
 /*   580 */    74,   75,   76,   77,   11,   79,   80,   81,   82,   83,
 /*   590 */    84,   85,   86,   87,   88,    9,  150,  111,  150,  113,
 /*   600 */   114,  111,   93,  113,  114,  217,    9,  219,  220,  103,
 /*   610 */     9,  216,  150,   40,   21,  208,  170,   44,  170,  157,
 /*   620 */   174,   23,  174,   25,  227,  104,  105,  106,  119,  104,
 /*   630 */   105,  106,  170,   11,   92,   93,  174,   64,   65,   66,
 /*   640 */    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
 /*   650 */    77,  189,   79,   80,   81,   82,   83,   84,   85,   86,
 /*   660 */    87,   88,  111,  150,  113,  114,  150,   96,  111,  150,
 /*   670 */   113,  114,  150,  136,  212,  138,  156,  162,   40,  108,
 /*   680 */    45,   32,   44,  170,  157,  170,  224,  174,  192,  170,
 /*   690 */    23,   98,  170,  174,    9,  199,  174,  111,  163,  113,
 /*   700 */   114,   52,   64,   65,   66,   67,   68,   69,   70,   71,
 /*   710 */    72,   73,   74,   75,   76,   77,  189,   79,   80,   81,
 /*   720 */    82,   83,   84,   85,   86,   87,   88,  126,  150,  157,
 /*   730 */   150,  150,  139,  150,   23,  200,   25,  161,  103,  150,
 /*   740 */   150,  214,  226,   40,   23,  150,   25,   44,  170,  157,
 /*   750 */   170,  170,  174,   24,  174,  174,  107,  230,  136,  170,
 /*   760 */   170,  189,  235,  174,  174,   20,  183,   64,   65,   66,
 /*   770 */    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
 /*   780 */    77,  189,   79,   80,   81,   82,   83,   84,   85,   86,
 /*   790 */    87,   88,  103,  150,  150,  150,  150,    9,   25,   66,
 /*   800 */    55,  150,   57,   23,  150,   25,  214,  171,   40,  226,
 /*   810 */    22,   33,   44,  170,  170,  170,  170,  174,  174,  174,
 /*   820 */   174,  170,  230,  102,  170,  174,  171,  235,  174,   96,
 /*   830 */    95,   96,  163,   65,   66,   67,   68,   69,   70,   71,
 /*   840 */    72,   73,   74,   75,   76,   77,  117,   79,   80,   81,
 /*   850 */    82,   83,   84,   85,   86,   87,   88,  150,  103,  150,
 /*   860 */   150,   73,  150,  150,   23,  150,   25,  150,  150,  200,
 /*   870 */   150,   26,  117,  150,   40,  150,  103,  170,   44,  170,
 /*   880 */   170,  174,  170,  174,  174,  170,  174,  170,  170,  174,
 /*   890 */   170,  174,  174,  170,  174,  170,  183,  174,   42,  174,
 /*   900 */    66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
 /*   910 */    76,   77,    9,   79,   80,   81,   82,   83,   84,   85,
 /*   920 */    86,   87,   88,   22,  150,  150,  150,   26,   28,   83,
 /*   930 */    84,   31,  150,  150,  150,  150,  150,   92,   26,  226,
 /*   940 */   150,  180,  150,   43,  170,  170,  170,  150,  174,  174,
 /*   950 */   174,   50,  170,  170,  170,  170,  174,  174,  174,  174,
 /*   960 */   170,   60,   61,   62,  174,    9,   23,   66,   25,  183,
 /*   970 */    53,   54,   60,   61,   62,  183,  131,  172,  150,  150,
 /*   980 */   183,   25,  186,  187,   83,   84,   85,  150,  150,   23,
 /*   990 */   150,   25,   91,   92,   93,   83,   84,   96,  170,  170,
 /*  1000 */   150,  150,  174,  174,   92,  150,  103,  170,   96,   22,
 /*  1010 */   170,  174,  226,   26,  174,   23,  150,   25,  226,  150,
 /*  1020 */   170,  170,  157,  226,  174,  174,  150,   23,  150,   25,
 /*  1030 */   129,  130,  131,  132,  133,  134,  135,   50,  150,  170,
 /*  1040 */   150,  129,  130,  174,  157,   46,  170,   60,   61,   62,
 /*  1050 */   174,  213,  157,   66,  189,   23,  150,   25,  170,   23,
 /*  1060 */   170,   25,  174,  208,  174,   23,  188,   25,  150,  150,
 /*  1070 */    83,   84,  150,  150,  208,  150,  189,  150,   91,   92,
 /*  1080 */    93,  150,  126,   96,  189,  115,   23,    9,   25,  150,
 /*  1090 */     9,  157,  171,  102,  188,   22,  117,  173,  128,  171,
 /*  1100 */   117,   22,  115,  190,  115,   26,  188,  188,  193,  189,
 /*  1110 */   188,  188,  126,  188,  124,  188,  129,  130,  131,  132,
 /*  1120 */   133,  134,  135,  189,   46,  123,  191,  188,  195,   50,
 /*  1130 */   194,  121,  125,  196,  117,  197,  117,   88,  198,   60,
 /*  1140 */    61,   62,   96,  150,  213,   66,  150,  150,  115,  115,
 /*  1150 */   115,   22,  136,  223,  222,   17,   22,   25,  187,   23,
 /*  1160 */    23,  150,   83,   84,  117,  150,  154,  122,   25,  101,
 /*  1170 */    91,   92,   93,  211,   26,   96,  162,  172,  211,  122,
 /*  1180 */   172,   25,  154,  203,  119,  103,  204,  150,  150,  150,
 /*  1190 */   150,  120,   22,   22,  150,   23,   23,   26,  117,  205,
 /*  1200 */   205,  117,  204,  150,   22,  175,  150,  176,  129,  130,
 /*  1210 */   131,  132,  133,  134,  135,  136,   23,  211,   22,  171,
 /*  1220 */   179,   50,  179,  162,  172,  163,  172,  150,  178,  211,
 /*  1230 */   179,   60,   61,   62,  170,  180,  170,   66,   46,   23,
 /*  1240 */   182,  228,  182,  173,   22,  171,  171,   46,  228,   22,
 /*  1250 */   100,  150,  176,  108,   83,   84,   85,  150,  175,  154,
 /*  1260 */   150,   24,   91,   92,   93,  154,  150,   96,  154,  103,
 /*  1270 */    39,  154,   11,   37,  139,   47,  150,  103,  103,   22,
 /*  1280 */   103,  154,   22,   26,  171,    9,  139,  185,   11,  150,
 /*  1290 */   231,  127,  127,    9,    9,   17,   17,   64,  107,  232,
 /*  1300 */   129,  130,  131,  132,  133,  134,  135,   50,  185,  150,
 /*  1310 */   150,   73,  194,  233,    9,   73,  127,   60,   61,   62,
 /*  1320 */   234,   22,   22,   66,  215,    9,  150,  118,  150,    9,
 /*  1330 */     9,    9,    9,    9,  194,  118,  194,    9,  185,  107,
 /*  1340 */    83,   84,    9,  194,    9,  127,  215,   22,   91,   92,
 /*  1350 */    93,    9,  150,   96,  150,    9,    9,  154,  150,    9,
 /*  1360 */    11,    9,   23,    9,   34,   16,   17,   18,   19,  236,
 /*  1370 */   163,  150,   24,    9,  163,    9,    9,    9,  237,   30,
 /*  1380 */   236,    9,   20,  154,  150,   36,  129,  130,  131,  132,
 /*  1390 */   133,  134,  135,  150,  140,   59,  150,    9,   49,  238,
 /*  1400 */    51,  238,  238,  238,  238,   56,  238,   58,  238,  238,
 /*  1410 */   238,  238,   63,  238,  238,  238,  238,  238,  238,  238,
 /*  1420 */   238,  238,  238,  238,  238,  238,  238,  238,  238,  238,
 /*  1430 */   238,  238,  238,  238,  238,  238,  238,  238,  238,  238,
 /*  1440 */   238,  238,  238,  238,  238,  238,  238,  238,  238,  238,
 /*  1450 */   238,  238,  238,  104,  105,  106,  238,  238,  238,  110,
 /*  1460 */   238,  238,  238,  238,  115,
};
#define YY_SHIFT_USE_DFLT (-76)
static const short yy_shift_ofst[] = {
 /*     0 */    92,  208,  -76,  -76, 1349,    6,   16,  -76,  458,  123,
 /*    10 */   183,   56,  232,  -76,  -76,  -76,  -76,  -76,  -76,  123,
 /*    20 */   273,  123,  346,  123,  415,  247,  597,  456,  598,  667,
 /*    30 */   685,  107,  -76,  -25,  -76,   86,  -76,  456,  113,  -76,
 /*    40 */   689,  -76,  778,  235,  -76,  -76,  -76,  -76,  -76,  -76,
 /*    50 */   -76,  571,  689,  -76,  856,  -76,  344,  -76,  -76,  999,
 /*    60 */   102,  689,  991,  -76,  -76,  -76,  -76,  689,  -76, 1073,
 /*    70 */  1257,  146,  901,  979,  983,  -76,  987,  -76,  238,  989,
 /*    80 */   -76,  281,  -76,  449,  986, 1002,  990, 1010, 1007,  -76,
 /*    90 */  1257,   41, 1257,  638, 1257,  -76, 1017,  456, 1019,  456,
 /*   100 */   -76,  -76,  -76,  -76,  -76,  -76,  -76,  -76,  -76,  834,
 /*   110 */  1257,  768, 1257,  -10, 1257,  -10, 1257,  -10, 1257,  -10,
 /*   120 */  1257,  -53, 1257,  -53, 1257,   11, 1257,   11, 1257,   11,
 /*   130 */  1257,   11, 1257,  -49, 1257,  -49, 1257, 1049, 1257, 1049,
 /*   140 */  1257, 1049, 1257,  -76,  -76,  -76,  230,  -76,  -76,  -76,
 /*   150 */   -76,  -76, 1257,  -75, 1257,  -10,  -76,  733,  -76, 1046,
 /*   160 */   -76,  -76,  -76, 1257,  703, 1257,  -53,  -76,  307,  987,
 /*   170 */   314,   38, 1033, 1034, 1035,  -76,  638, 1257,  834, 1257,
 /*   180 */   -76, 1257,  -76, 1257,  -76, 1129,  989,  319,  -76, 1079,
 /*   190 */    90, 1016,  537, 1138,  -76, 1257,  163, 1257,  638, 1134,
 /*   200 */   376, 1136,  -76, 1132,  456, 1137,  -76, 1257,  237, 1257,
 /*   210 */   301, 1257,  638,  711,  -76, 1257,  -76,  -76, 1047,  456,
 /*   220 */   -76,  -76,  -76, 1257,  638, 1045, 1257, 1143, 1257, 1068,
 /*   230 */   102,  -76, 1148,  -76,  -76,  638, 1068,  102,  -76, 1257,
 /*   240 */   638, 1057, 1257, 1156, 1257,  638,  -76,  -76,  509,  -76,
 /*   250 */   -76,  -76,  385,  -76,  439,  -76, 1065,  -76,  387, 1047,
 /*   260 */   405,  -76,  -76,  456,  -76,  -76, 1082, 1071,  -76, 1170,
 /*   270 */   456,  780,  -76,  456,  -76,  -76, 1257,  638,  989,  389,
 /*   280 */   443, 1172,  405, 1082, 1071,  -76, 1171,  -24,  -76,  -76,
 /*   290 */  1084,   53,  -76,  -76,  -76,  -76,  375,  -76,  841,  -76,
 /*   300 */  1173,  -76,  441,  689,  -76,  456, 1182,  -76,  635,  -76,
 /*   310 */   456,  -76,  521,  649,  -76,  735,  -76,  -76,  -76,  -76,
 /*   320 */   649,  -76,  649,  -76,  456,  943,  -76,  456, 1068,  102,
 /*   330 */   -76,  -76, 1068,  102,  -76,  -76, 1148,  -76,  856,  -76,
 /*   340 */   -76,  912,  -76,  128,  -76,  -76,  128,  -76,  -76,   -8,
 /*   350 */   846,  966,  -76,  846, 1193,  -76,  -76,  -76,  414,  -76,
 /*   360 */   -76,  -76,  414,  -76,  -76,  -76,  -76,  -76,   -6,   42,
 /*   370 */   -76,  456,  -76, 1192, 1196,  456,  721, 1216,  689,  -76,
 /*   380 */  1222,  456,  992,  689,  -76, 1257,  506,  -76, 1201, 1227,
 /*   390 */   456, 1004, 1150,  456, 1182,  -76,  453, 1145,  -76,  -76,
 /*   400 */   -76,  -76,  -76,  989,  428,  593,  745,  456, 1047,  -76,
 /*   410 */   456,  729, 1237,  989,  486,  456, 1047,  900,  525, 1166,
 /*   420 */   456, 1047,  -76, 1231,  622, 1261, 1257,  573, 1236,  917,
 /*   430 */   -76,  -76, 1174, 1175,  437,  456,  773,  -76,  -76, 1228,
 /*   440 */   -76,  -76, 1135,  456,  755, 1177,  456, 1260,  456, 1032,
 /*   450 */   903, 1276, 1147, 1277,  174,  490,  326,  235,  -76, 1164,
 /*   460 */  1165, 1278, 1284, 1285,  174, 1279, 1233,  456, 1191,  456,
 /*   470 */   956,  456, 1238, 1257,  638, 1305, 1242, 1257,  638, 1189,
 /*   480 */   456, 1299,  456, 1036,  -76,  360,  551, 1300, 1257, 1042,
 /*   490 */  1257,  638, 1316,  638, 1209,  456,  601, 1320,  240,  456,
 /*   500 */  1321,  456, 1322,  456, 1323,  456, 1324,  557, 1217,  456,
 /*   510 */   601, 1328, 1233,  456, 1232,  456,  956, 1333, 1218,  456,
 /*   520 */  1299,  970,  586, 1325, 1257, 1063, 1335,  460, 1342,  456,
 /*   530 */  1047,  788,  172, 1346, 1347, 1350, 1352,  456, 1339, 1354,
 /*   540 */  1330,  -25, 1348,  456, 1078, 1364,  845, 1366, 1367,  -76,
 /*   550 */  1330,  456, 1368,  542, 1081, 1372, 1362,  456, 1336, 1254,
 /*   560 */   456, 1388,  -76,  -76,
};
#define YY_REDUCE_USE_DFLT (-95)
static const short yy_reduce_ofst[] = {
 /*     0 */     0,  -61,  -95,  -95,  202,  -95,  -95,  -95,  -94,  -59,
 /*    10 */   -95,   52,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  103,
 /*    20 */   -95,  189,  -95,  261,  -95,  349,  -95,  185,  520,  -95,
 /*    30 */   -95,  109,  -95,   33,  576,  116,  -95,  595,  162,  -95,
 /*    40 */   636,  -95,  -95,   36,  -95,  -95,  -95,  -95,  -95,  -95,
 /*    50 */   -95,  -95,  655,  -95,  761,  -95,  -95,  -95,  -95,  -95,
 /*    60 */   805,  921,  924,  -95,  -95,  -95,  -95,  928,  -95,  -95,
 /*    70 */   446,  -95,  122,  -95,  -95,  -95,  -70,  -95,  913,  920,
 /*    80 */   -95,  935,  496,  915,  936,  933,  937,  938,  940,  -95,
 /*    90 */   448,  388,  513,  388,  519,  -95,  -95,  993,  -95,  996,
 /*   100 */   -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  388,
 /*   110 */   522,  388,  578,  388,  580,  388,  581,  388,  589,  388,
 /*   120 */   590,  388,  643,  388,  644,  388,  645,  388,  646,  388,
 /*   130 */   651,  388,  654,  388,  707,  388,  709,  388,  710,  388,
 /*   140 */   712,  388,  715,  388,  -95,  -95,  -95,  -95,  -95,  -95,
 /*   150 */   -95,  -95,  717,  188,  718,  388,  -95,  -95,  -95,  -95,
 /*   160 */   -95,  -95,  -95,  720,  388,  723,  388,  -95,  997,  462,
 /*   170 */   913,  -95,  -95,  -95,  -95,  -95,  388,  725,  388,  774,
 /*   180 */   388,  775,  388,  776,  388,  -95,  572,  913,  -95,   45,
 /*   190 */   388,  932,  930,  -95,  -95,  782,  388,  783,  388,  -95,
 /*   200 */   971,  -95,  -95,  -95, 1011,  -95,  -95,  784,  388,  785,
 /*   210 */   388,  790,  388,  -95,  -95,  252,  -95,  -95, 1012, 1015,
 /*   220 */   -95,  -95,  -95,  828,  388,  -95,  186,  -95,  320,  962,
 /*   230 */  1005,  -95, 1014,  -95,  -95,  388,  967, 1008,  -95,  829,
 /*   240 */   388,  -95,  180,  -95,  837,  388,  -95,  291,  980,  -95,
 /*   250 */   -95,  -95, 1037,  -95, 1038,  -95,  -95,  -95, 1039, 1028,
 /*   260 */   535,  -95,  -95, 1040,  -95,  -95,  982,  994,  -95,  -95,
 /*   270 */   407,  -95,  -95, 1044,  -95,  -95,  840,  388,  126,  913,
 /*   280 */   980,  -95,  669,  998,  995,  -95,  850,  201,  -95,  -95,
 /*   290 */   -95,  993,  -95,  -95,  -95,  -95,  388,  -95,  -95,  -95,
 /*   300 */   -95,  -95,  388, 1048,  -95, 1053, 1030, 1031, 1050,  -95,
 /*   310 */  1056,  -95,  -95, 1041,  -95,  -95,  -95,  -95,  -95,  -95,
 /*   320 */  1043,  -95, 1051,  -95,  583,  -95,  -95,  516, 1006, 1052,
 /*   330 */   -95,  -95, 1018, 1054,  -95,  -95, 1061,  -95, 1055,  -95,
 /*   340 */   -95,  515,  -95, 1064,  -95,  -95, 1066,  -95,  -95, 1062,
 /*   350 */   196,  -95,  -95,  269,  -95,  -95,  -95,  -95, 1013,  -95,
 /*   360 */   -95,  -95, 1020,  -95,  -95,  -95,  -95,  -95, 1058, 1060,
 /*   370 */   -95, 1077,  -95,  -95,  -95,  713, 1070,  -95, 1074,  -95,
 /*   380 */   -95,  786,  -95, 1075,  -95,  851,  318,  -95,  -95,  -95,
 /*   390 */   792,  -95,  -95, 1101, 1083, 1076,  110,  -95,  -95,  -95,
 /*   400 */   -95,  -95,  -95,  865,  913,  330,  -95, 1107, 1105,  -95,
 /*   410 */  1110, 1111,  -95,  887,  913, 1116, 1114, 1059, 1067,  -95,
 /*   420 */   878, 1117,  -95, 1080, 1086,  -95,  869,  388,  -95,  -95,
 /*   430 */   -95,  -95,  -95,  -95,  -95,  855,  -95,  -95,  -95,  -95,
 /*   440 */   -95,  -95,  -95, 1126, 1127,  -95, 1139,  -95,  797,  -95,
 /*   450 */  1113,  -95,  -95,  -95,  527,  913, 1102,  796,  -95,  -95,
 /*   460 */   -95,  -95,  -95,  -95,  592,  -95, 1123, 1159,  -95,  838,
 /*   470 */  1118, 1160,  -95,  876,  388,  -95,  -95,  888,  388,  -95,
 /*   480 */  1176, 1109,  866,  -95,  -95,  895,  913,  -95,  317,  -95,
 /*   490 */   890,  388,  -95,  388,  -95, 1178, 1140,  -95,  -95,  906,
 /*   500 */   -95,  918,  -95,  919,  -95,  922,  -95,  913,  -95,  923,
 /*   510 */  1142,  -95, 1153,  925,  -95,  931, 1149,  -95,  -95,  927,
 /*   520 */  1131,  934,  913,  -95,  395,  -95,  -95, 1202,  -95, 1204,
 /*   530 */  1203,  -95,  397,  -95,  -95,  -95,  -95, 1208,  -95,  -95,
 /*   540 */  1133, 1207,  -95, 1221, 1141,  -95, 1211,  -95,  -95,  -95,
 /*   550 */  1144, 1234,  -95, 1243, 1229,  -95,  -95,  939,  -95,  -95,
 /*   560 */  1246,  -95,  -95,  -95,
};
static const YYACTIONTYPE yy_default[] = {
 /*     0 */   570,  570,  565,  568,  869,  869,  869,  569,  576,  869,
 /*    10 */   869,  869,  869,  596,  597,  598,  577,  578,  579,  869,
 /*    20 */   869,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*    30 */   869,  869,  589,  599,  608,  591,  607,  869,  869,  609,
 /*    40 */   652,  615,  869,  869,  653,  656,  657,  658,  855,  856,
 /*    50 */   857,  869,  652,  616,  637,  635,  869,  638,  639,  869,
 /*    60 */   708,  652,  623,  617,  624,  706,  707,  652,  618,  869,
 /*    70 */   869,  738,  807,  744,  739,  735,  869,  663,  869,  869,
 /*    80 */   664,  672,  674,  681,  720,  711,  713,  701,  715,  669,
 /*    90 */   869,  716,  869,  717,  869,  737,  869,  869,  740,  869,
 /*   100 */   741,  742,  743,  745,  746,  747,  750,  751,  752,  753,
 /*   110 */   869,  754,  869,  755,  869,  756,  869,  757,  869,  758,
 /*   120 */   869,  759,  869,  760,  869,  761,  869,  762,  869,  763,
 /*   130 */   869,  764,  869,  765,  869,  766,  869,  767,  869,  768,
 /*   140 */   869,  769,  869,  770,  771,  772,  869,  773,  774,  781,
 /*   150 */   788,  791,  869,  776,  869,  775,  778,  869,  779,  869,
 /*   160 */   782,  780,  787,  869,  869,  869,  789,  790,  869,  807,
 /*   170 */   869,  869,  869,  869,  869,  794,  806,  869,  783,  869,
 /*   180 */   784,  869,  785,  869,  786,  869,  869,  869,  796,  869,
 /*   190 */   869,  869,  869,  869,  797,  869,  869,  869,  798,  869,
 /*   200 */   869,  869,  853,  869,  869,  869,  854,  869,  869,  869,
 /*   210 */   869,  869,  799,  869,  792,  807,  804,  805,  689,  869,
 /*   220 */   690,  795,  777,  869,  718,  869,  869,  702,  869,  709,
 /*   230 */   708,  703,  869,  593,  710,  705,  709,  708,  704,  869,
 /*   240 */   714,  869,  807,  712,  869,  721,  673,  684,  682,  683,
 /*   250 */   692,  693,  869,  694,  869,  695,  869,  696,  869,  689,
 /*   260 */   680,  594,  595,  869,  678,  679,  698,  700,  685,  869,
 /*   270 */   869,  869,  699,  869,  733,  734,  869,  697,  684,  869,
 /*   280 */   869,  869,  680,  698,  700,  686,  869,  680,  675,  676,
 /*   290 */   869,  869,  677,  670,  671,  793,  869,  736,  869,  748,
 /*   300 */   869,  749,  869,  652,  619,  869,  811,  625,  620,  626,
 /*   310 */   869,  627,  869,  869,  628,  869,  631,  632,  633,  634,
 /*   320 */   869,  629,  869,  630,  869,  869,  812,  869,  709,  708,
 /*   330 */   813,  815,  709,  708,  814,  621,  869,  622,  637,  636,
 /*   340 */   610,  869,  611,  869,  612,  744,  869,  613,  614,  600,
 /*   350 */   830,  869,  601,  830,  869,  602,  605,  606,  869,  825,
 /*   360 */   827,  828,  869,  826,  829,  604,  603,  592,  869,  869,
 /*   370 */   642,  869,  645,  869,  869,  869,  869,  869,  652,  646,
 /*   380 */   869,  869,  869,  652,  647,  869,  652,  648,  869,  869,
 /*   390 */   869,  869,  869,  869,  811,  625,  650,  869,  649,  651,
 /*   400 */   643,  644,  590,  869,  869,  586,  869,  869,  689,  584,
 /*   410 */   869,  869,  869,  869,  869,  869,  689,  836,  869,  869,
 /*   420 */   869,  689,  691,  841,  869,  869,  869,  869,  869,  869,
 /*   430 */   842,  843,  869,  869,  869,  869,  869,  833,  834,  869,
 /*   440 */   835,  585,  869,  869,  869,  869,  869,  869,  869,  869,
 /*   450 */   869,  869,  869,  869,  869,  869,  869,  869,  655,  869,
 /*   460 */   869,  869,  869,  869,  869,  869,  654,  869,  869,  869,
 /*   470 */   869,  869,  869,  869,  723,  869,  869,  869,  724,  869,
 /*   480 */   869,  731,  869,  869,  732,  869,  869,  869,  869,  869,
 /*   490 */   869,  729,  869,  730,  869,  869,  869,  869,  869,  869,
 /*   500 */   869,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*   510 */   869,  869,  654,  869,  869,  869,  869,  869,  869,  869,
 /*   520 */   731,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*   530 */   689,  869,  830,  869,  869,  869,  869,  869,  869,  869,
 /*   540 */   864,  869,  869,  869,  869,  869,  869,  869,  869,  863,
 /*   550 */   864,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*   560 */   869,  869,  571,  566,
};
#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))

/* The next table maps tokens into fallback tokens.  If a construct
** like the following:
** 
**      %fallback ID X Y Z.
**
** appears in the grammer, then ID becomes a fallback token for X, Y,
** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
    0,  /*          $ => nothing */
    0,  /* END_OF_FILE => nothing */
    0,  /*    ILLEGAL => nothing */
    0,  /*      SPACE => nothing */
    0,  /* UNCLOSED_STRING => nothing */
    0,  /*    COMMENT => nothing */
    0,  /*   FUNCTION => nothing */
    0,  /*     COLUMN => nothing */
    0,  /* AGG_FUNCTION => nothing */
    0,  /*       SEMI => nothing */
   26,  /*    EXPLAIN => ID */
   26,  /*      BEGIN => ID */
    0,  /* TRANSACTION => nothing */
   26,  /*   DEFERRED => ID */
   26,  /*  IMMEDIATE => ID */
   26,  /*  EXCLUSIVE => ID */
    0,  /*     COMMIT => nothing */
   26,  /*        END => ID */
    0,  /*   ROLLBACK => nothing */
    0,  /*     CREATE => nothing */
    0,  /*      TABLE => nothing */
   26,  /*       TEMP => ID */
    0,  /*         LP => nothing */
    0,  /*         RP => nothing */
    0,  /*         AS => nothing */
    0,  /*      COMMA => nothing */
    0,  /*         ID => nothing */
   26,  /*      ABORT => ID */
   26,  /*      AFTER => ID */
   26,  /*        ASC => ID */
   26,  /*     ATTACH => ID */
   26,  /*     BEFORE => ID */
   26,  /*    CASCADE => ID */
   26,  /*   CONFLICT => ID */
   26,  /*   DATABASE => ID */
   26,  /*       DESC => ID */
   26,  /*     DETACH => ID */
   26,  /*       EACH => ID */
   26,  /*       FAIL => ID */
   26,  /*        FOR => ID */
   26,  /*       GLOB => ID */
   26,  /*     IGNORE => ID */
   26,  /*  INITIALLY => ID */
   26,  /*    INSTEAD => ID */
   26,  /*       LIKE => ID */
   26,  /*      MATCH => ID */
   26,  /*        KEY => ID */
   26,  /*         OF => ID */
   26,  /*     OFFSET => ID */
   26,  /*     PRAGMA => ID */
   26,  /*      RAISE => ID */
   26,  /*    REPLACE => ID */
   26,  /*   RESTRICT => ID */
   26,  /*        ROW => ID */
   26,  /*  STATEMENT => ID */
   26,  /*    TRIGGER => ID */
   26,  /*     VACUUM => ID */
   26,  /*       VIEW => ID */
   26,  /*    REINDEX => ID */
   26,  /*     RENAME => ID */
   26,  /*      CDATE => ID */
   26,  /*      CTIME => ID */
   26,  /* CTIMESTAMP => ID */
   26,  /*      ALTER => ID */
    0,  /*         OR => nothing */
    0,  /*        AND => nothing */
    0,  /*        NOT => nothing */
    0,  /*         IS => nothing */
    0,  /*    BETWEEN => nothing */
    0,  /*         IN => nothing */
    0,  /*     ISNULL => nothing */
    0,  /*    NOTNULL => nothing */
    0,  /*         NE => nothing */
    0,  /*         EQ => nothing */
    0,  /*         GT => nothing */
    0,  /*         LE => nothing */
    0,  /*         LT => nothing */
    0,  /*         GE => nothing */
    0,  /*     ESCAPE => nothing */
    0,  /*     BITAND => nothing */
    0,  /*      BITOR => nothing */
    0,  /*     LSHIFT => nothing */
    0,  /*     RSHIFT => nothing */
    0,  /*       PLUS => nothing */
    0,  /*      MINUS => nothing */
    0,  /*       STAR => nothing */
    0,  /*      SLASH => nothing */
    0,  /*        REM => nothing */
    0,  /*     CONCAT => nothing */
    0,  /*     UMINUS => nothing */
    0,  /*      UPLUS => nothing */
    0,  /*     BITNOT => nothing */
    0,  /*     STRING => nothing */
    0,  /*    JOIN_KW => nothing */
    0,  /* CONSTRAINT => nothing */
    0,  /*    DEFAULT => nothing */
    0,  /*       NULL => nothing */
    0,  /*    PRIMARY => nothing */
    0,  /*     UNIQUE => nothing */
    0,  /*      CHECK => nothing */
    0,  /* REFERENCES => nothing */
    0,  /*    COLLATE => nothing */
    0,  /*   AUTOINCR => nothing */
    0,  /*         ON => nothing */
    0,  /*     DELETE => nothing */
    0,  /*     UPDATE => nothing */
    0,  /*     INSERT => nothing */
    0,  /*        SET => nothing */
    0,  /* DEFERRABLE => nothing */
    0,  /*    FOREIGN => nothing */
    0,  /*       DROP => nothing */
    0,  /*      UNION => nothing */
    0,  /*        ALL => nothing */
    0,  /*  INTERSECT => nothing */
    0,  /*     EXCEPT => nothing */
    0,  /*     SELECT => nothing */
    0,  /*   DISTINCT => nothing */
    0,  /*        DOT => nothing */
    0,  /*       FROM => nothing */
    0,  /*       JOIN => nothing */
    0,  /*      USING => nothing */
    0,  /*      ORDER => nothing */
    0,  /*         BY => nothing */
    0,  /*      GROUP => nothing */
    0,  /*     HAVING => nothing */
    0,  /*      LIMIT => nothing */
    0,  /*      WHERE => nothing */
    0,  /*       INTO => nothing */
    0,  /*     VALUES => nothing */
    0,  /*    INTEGER => nothing */
    0,  /*      FLOAT => nothing */
    0,  /*       BLOB => nothing */
    0,  /*   REGISTER => nothing */
    0,  /*   VARIABLE => nothing */
    0,  /*     EXISTS => nothing */
    0,  /*       CASE => nothing */
    0,  /*       WHEN => nothing */
    0,  /*       THEN => nothing */
    0,  /*       ELSE => nothing */
    0,  /*      INDEX => nothing */
    0,  /*         TO => nothing */
};
#endif /* YYFALLBACK */

/* The following structure represents a single element of the
** parser's stack.  Information stored includes:
**
**   +  The state number for the parser at this level of the stack.
**
**   +  The value of the token stored at this level of the stack.
**      (In other words, the "major" token.)
**
**   +  The semantic value stored at this level of the stack.  This is
**      the information used by the action routines in the grammar.
**      It is sometimes called the "minor" token.
*/
struct yyStackEntry {
  int stateno;       /* The state-number */
  int major;         /* The major token value.  This is the code
                     ** number for the token at this stack level */
  YYMINORTYPE minor; /* The user-supplied minor token value.  This
                     ** is the value of the token  */
};
typedef struct yyStackEntry yyStackEntry;

/* The state of the parser is completely contained in an instance of
** the following structure */
struct yyParser {
  int yyidx;                    /* Index of top element in stack */
  int yyerrcnt;                 /* Shifts left before out of the error */
  sqlite3ParserARG_SDECL                /* A place to hold %extra_argument */
  yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
};
typedef struct yyParser yyParser;

#ifndef NDEBUG
#include <stdio.h>
static FILE *yyTraceFILE = 0;
static char *yyTracePrompt = 0;
#endif /* NDEBUG */

#ifndef NDEBUG
/* 
** Turn parser tracing on by giving a stream to which to write the trace
** and a prompt to preface each trace message.  Tracing is turned off
** by making either argument NULL 
**
** Inputs:
** <ul>
** <li> A FILE* to which trace output should be written.
**      If NULL, then tracing is turned off.
** <li> A prefix string written at the beginning of every
**      line of trace output.  If NULL, then tracing is
**      turned off.
** </ul>
**
** Outputs:
** None.
*/
void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){
  yyTraceFILE = TraceFILE;
  yyTracePrompt = zTracePrompt;
  if( yyTraceFILE==0 ) yyTracePrompt = 0;
  else if( yyTracePrompt==0 ) yyTraceFILE = 0;
}
#endif /* NDEBUG */

#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required.  The following table supplies these names */
static const char *const yyTokenName[] = { 
  "$",             "END_OF_FILE",   "ILLEGAL",       "SPACE",       
  "UNCLOSED_STRING",  "COMMENT",       "FUNCTION",      "COLUMN",      
  "AGG_FUNCTION",  "SEMI",          "EXPLAIN",       "BEGIN",       
  "TRANSACTION",   "DEFERRED",      "IMMEDIATE",     "EXCLUSIVE",   
  "COMMIT",        "END",           "ROLLBACK",      "CREATE",      
  "TABLE",         "TEMP",          "LP",            "RP",          
  "AS",            "COMMA",         "ID",            "ABORT",       
  "AFTER",         "ASC",           "ATTACH",        "BEFORE",      
  "CASCADE",       "CONFLICT",      "DATABASE",      "DESC",        
  "DETACH",        "EACH",          "FAIL",          "FOR",         
  "GLOB",          "IGNORE",        "INITIALLY",     "INSTEAD",     
  "LIKE",          "MATCH",         "KEY",           "OF",          
  "OFFSET",        "PRAGMA",        "RAISE",         "REPLACE",     
  "RESTRICT",      "ROW",           "STATEMENT",     "TRIGGER",     
  "VACUUM",        "VIEW",          "REINDEX",       "RENAME",      
  "CDATE",         "CTIME",         "CTIMESTAMP",    "ALTER",       
  "OR",            "AND",           "NOT",           "IS",          
  "BETWEEN",       "IN",            "ISNULL",        "NOTNULL",     
  "NE",            "EQ",            "GT",            "LE",          
  "LT",            "GE",            "ESCAPE",        "BITAND",      
  "BITOR",         "LSHIFT",        "RSHIFT",        "PLUS",        
  "MINUS",         "STAR",          "SLASH",         "REM",         
  "CONCAT",        "UMINUS",        "UPLUS",         "BITNOT",      
  "STRING",        "JOIN_KW",       "CONSTRAINT",    "DEFAULT",     
  "NULL",          "PRIMARY",       "UNIQUE",        "CHECK",       
  "REFERENCES",    "COLLATE",       "AUTOINCR",      "ON",          
  "DELETE",        "UPDATE",        "INSERT",        "SET",         
  "DEFERRABLE",    "FOREIGN",       "DROP",          "UNION",       
  "ALL",           "INTERSECT",     "EXCEPT",        "SELECT",      
  "DISTINCT",      "DOT",           "FROM",          "JOIN",        
  "USING",         "ORDER",         "BY",            "GROUP",       
  "HAVING",        "LIMIT",         "WHERE",         "INTO",        
  "VALUES",        "INTEGER",       "FLOAT",         "BLOB",        
  "REGISTER",      "VARIABLE",      "EXISTS",        "CASE",        
  "WHEN",          "THEN",          "ELSE",          "INDEX",       
  "TO",            "error",         "input",         "cmdlist",     
  "ecmd",          "cmdx",          "cmd",           "explain",     
  "transtype",     "trans_opt",     "nm",            "create_table",
  "create_table_args",  "temp",          "dbnm",          "columnlist",  
  "conslist_opt",  "select",        "column",        "columnid",    
  "type",          "carglist",      "id",            "ids",         
  "typename",      "signed",        "plus_num",      "minus_num",   
  "carg",          "ccons",         "term",          "onconf",      
  "sortorder",     "autoinc",       "expr",          "idxlist_opt", 
  "refargs",       "defer_subclause",  "refarg",        "refact",      
  "init_deferred_pred_opt",  "conslist",      "tcons",         "idxlist",     
  "defer_subclause_opt",  "orconf",        "resolvetype",   "raisetype",   
  "fullname",      "oneselect",     "multiselect_op",  "distinct",    
  "selcollist",    "from",          "where_opt",     "groupby_opt", 
  "having_opt",    "orderby_opt",   "limit_opt",     "sclp",        
  "as",            "seltablist",    "stl_prefix",    "joinop",      
  "on_opt",        "using_opt",     "seltablist_paren",  "joinop2",     
  "inscollist",    "sortlist",      "sortitem",      "collate",     
  "exprlist",      "setlist",       "insert_cmd",    "inscollist_opt",
  "itemlist",      "likeop",        "escape",        "between_op",  
  "in_op",         "case_operand",  "case_exprlist",  "case_else",   
  "expritem",      "uniqueflag",    "idxitem",       "plus_opt",    
  "number",        "trigger_decl",  "trigger_cmd_list",  "trigger_time",
  "trigger_event",  "foreach_clause",  "when_clause",   "trigger_cmd", 
  "database_kw_opt",  "key_opt",     
};
#endif /* NDEBUG */

#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
 /*   0 */ "input ::= cmdlist",
 /*   1 */ "cmdlist ::= cmdlist ecmd",
 /*   2 */ "cmdlist ::= ecmd",
 /*   3 */ "cmdx ::= cmd",
 /*   4 */ "ecmd ::= SEMI",
 /*   5 */ "ecmd ::= explain cmdx SEMI",
 /*   6 */ "explain ::=",
 /*   7 */ "explain ::= EXPLAIN",
 /*   8 */ "cmd ::= BEGIN transtype trans_opt",
 /*   9 */ "trans_opt ::=",
 /*  10 */ "trans_opt ::= TRANSACTION",
 /*  11 */ "trans_opt ::= TRANSACTION nm",
 /*  12 */ "transtype ::=",
 /*  13 */ "transtype ::= DEFERRED",
 /*  14 */ "transtype ::= IMMEDIATE",
 /*  15 */ "transtype ::= EXCLUSIVE",
 /*  16 */ "cmd ::= COMMIT trans_opt",
 /*  17 */ "cmd ::= END trans_opt",
 /*  18 */ "cmd ::= ROLLBACK trans_opt",
 /*  19 */ "cmd ::= create_table create_table_args",
 /*  20 */ "create_table ::= CREATE temp TABLE nm dbnm",
 /*  21 */ "temp ::= TEMP",
 /*  22 */ "temp ::=",
 /*  23 */ "create_table_args ::= LP columnlist conslist_opt RP",
 /*  24 */ "create_table_args ::= AS select",
 /*  25 */ "columnlist ::= columnlist COMMA column",
 /*  26 */ "columnlist ::= column",
 /*  27 */ "column ::= columnid type carglist",
 /*  28 */ "columnid ::= nm",
 /*  29 */ "id ::= ID",
 /*  30 */ "ids ::= ID",
 /*  31 */ "ids ::= STRING",
 /*  32 */ "nm ::= ID",
 /*  33 */ "nm ::= STRING",
 /*  34 */ "nm ::= JOIN_KW",
 /*  35 */ "type ::=",
 /*  36 */ "type ::= typename",
 /*  37 */ "type ::= typename LP signed RP",
 /*  38 */ "type ::= typename LP signed COMMA signed RP",
 /*  39 */ "typename ::= ids",
 /*  40 */ "typename ::= typename ids",
 /*  41 */ "signed ::= plus_num",
 /*  42 */ "signed ::= minus_num",
 /*  43 */ "carglist ::= carglist carg",
 /*  44 */ "carglist ::=",
 /*  45 */ "carg ::= CONSTRAINT nm ccons",
 /*  46 */ "carg ::= ccons",
 /*  47 */ "carg ::= DEFAULT term",
 /*  48 */ "carg ::= DEFAULT PLUS term",
 /*  49 */ "carg ::= DEFAULT MINUS term",
 /*  50 */ "carg ::= DEFAULT id",
 /*  51 */ "ccons ::= NULL onconf",
 /*  52 */ "ccons ::= NOT NULL onconf",
 /*  53 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
 /*  54 */ "ccons ::= UNIQUE onconf",
 /*  55 */ "ccons ::= CHECK LP expr RP onconf",
 /*  56 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
 /*  57 */ "ccons ::= defer_subclause",
 /*  58 */ "ccons ::= COLLATE id",
 /*  59 */ "autoinc ::=",
 /*  60 */ "autoinc ::= AUTOINCR",
 /*  61 */ "refargs ::=",
 /*  62 */ "refargs ::= refargs refarg",
 /*  63 */ "refarg ::= MATCH nm",
 /*  64 */ "refarg ::= ON DELETE refact",
 /*  65 */ "refarg ::= ON UPDATE refact",
 /*  66 */ "refarg ::= ON INSERT refact",
 /*  67 */ "refact ::= SET NULL",
 /*  68 */ "refact ::= SET DEFAULT",
 /*  69 */ "refact ::= CASCADE",
 /*  70 */ "refact ::= RESTRICT",
 /*  71 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
 /*  72 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
 /*  73 */ "init_deferred_pred_opt ::=",
 /*  74 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
 /*  75 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
 /*  76 */ "conslist_opt ::=",
 /*  77 */ "conslist_opt ::= COMMA conslist",
 /*  78 */ "conslist ::= conslist COMMA tcons",
 /*  79 */ "conslist ::= conslist tcons",
 /*  80 */ "conslist ::= tcons",
 /*  81 */ "tcons ::= CONSTRAINT nm",
 /*  82 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
 /*  83 */ "tcons ::= UNIQUE LP idxlist RP onconf",
 /*  84 */ "tcons ::= CHECK expr onconf",
 /*  85 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
 /*  86 */ "defer_subclause_opt ::=",
 /*  87 */ "defer_subclause_opt ::= defer_subclause",
 /*  88 */ "onconf ::=",
 /*  89 */ "onconf ::= ON CONFLICT resolvetype",
 /*  90 */ "orconf ::=",
 /*  91 */ "orconf ::= OR resolvetype",
 /*  92 */ "resolvetype ::= raisetype",
 /*  93 */ "resolvetype ::= IGNORE",
 /*  94 */ "resolvetype ::= REPLACE",
 /*  95 */ "cmd ::= DROP TABLE fullname",
 /*  96 */ "cmd ::= CREATE temp VIEW nm dbnm AS select",
 /*  97 */ "cmd ::= DROP VIEW fullname",
 /*  98 */ "cmd ::= select",
 /*  99 */ "select ::= oneselect",
 /* 100 */ "select ::= select multiselect_op oneselect",
 /* 101 */ "multiselect_op ::= UNION",
 /* 102 */ "multiselect_op ::= UNION ALL",
 /* 103 */ "multiselect_op ::= INTERSECT",
 /* 104 */ "multiselect_op ::= EXCEPT",
 /* 105 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
 /* 106 */ "distinct ::= DISTINCT",
 /* 107 */ "distinct ::= ALL",
 /* 108 */ "distinct ::=",
 /* 109 */ "sclp ::= selcollist COMMA",
 /* 110 */ "sclp ::=",
 /* 111 */ "selcollist ::= sclp expr as",
 /* 112 */ "selcollist ::= sclp STAR",
 /* 113 */ "selcollist ::= sclp nm DOT STAR",
 /* 114 */ "as ::= AS nm",
 /* 115 */ "as ::= ids",
 /* 116 */ "as ::=",
 /* 117 */ "from ::=",
 /* 118 */ "from ::= FROM seltablist",
 /* 119 */ "stl_prefix ::= seltablist joinop",
 /* 120 */ "stl_prefix ::=",
 /* 121 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt",
 /* 122 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt",
 /* 123 */ "seltablist_paren ::= select",
 /* 124 */ "seltablist_paren ::= seltablist",
 /* 125 */ "dbnm ::=",
 /* 126 */ "dbnm ::= DOT nm",
 /* 127 */ "fullname ::= nm dbnm",
 /* 128 */ "joinop ::= COMMA",
 /* 129 */ "joinop ::= JOIN",
 /* 130 */ "joinop ::= JOIN_KW JOIN",
 /* 131 */ "joinop ::= JOIN_KW nm JOIN",
 /* 132 */ "joinop ::= JOIN_KW nm nm JOIN",
 /* 133 */ "on_opt ::= ON expr",
 /* 134 */ "on_opt ::=",
 /* 135 */ "using_opt ::= USING LP inscollist RP",
 /* 136 */ "using_opt ::=",
 /* 137 */ "orderby_opt ::=",
 /* 138 */ "orderby_opt ::= ORDER BY sortlist",
 /* 139 */ "sortlist ::= sortlist COMMA sortitem collate sortorder",
 /* 140 */ "sortlist ::= sortitem collate sortorder",
 /* 141 */ "sortitem ::= expr",
 /* 142 */ "sortorder ::= ASC",
 /* 143 */ "sortorder ::= DESC",
 /* 144 */ "sortorder ::=",
 /* 145 */ "collate ::=",
 /* 146 */ "collate ::= COLLATE id",
 /* 147 */ "groupby_opt ::=",
 /* 148 */ "groupby_opt ::= GROUP BY exprlist",
 /* 149 */ "having_opt ::=",
 /* 150 */ "having_opt ::= HAVING expr",
 /* 151 */ "limit_opt ::=",
 /* 152 */ "limit_opt ::= LIMIT expr",
 /* 153 */ "limit_opt ::= LIMIT expr OFFSET expr",
 /* 154 */ "limit_opt ::= LIMIT expr COMMA expr",
 /* 155 */ "cmd ::= DELETE FROM fullname where_opt",
 /* 156 */ "where_opt ::=",
 /* 157 */ "where_opt ::= WHERE expr",
 /* 158 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt",
 /* 159 */ "setlist ::= setlist COMMA nm EQ expr",
 /* 160 */ "setlist ::= nm EQ expr",
 /* 161 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
 /* 162 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
 /* 163 */ "insert_cmd ::= INSERT orconf",
 /* 164 */ "insert_cmd ::= REPLACE",
 /* 165 */ "itemlist ::= itemlist COMMA expr",
 /* 166 */ "itemlist ::= expr",
 /* 167 */ "inscollist_opt ::=",
 /* 168 */ "inscollist_opt ::= LP inscollist RP",
 /* 169 */ "inscollist ::= inscollist COMMA nm",
 /* 170 */ "inscollist ::= nm",
 /* 171 */ "expr ::= term",
 /* 172 */ "expr ::= LP expr RP",
 /* 173 */ "term ::= NULL",
 /* 174 */ "expr ::= ID",
 /* 175 */ "expr ::= JOIN_KW",
 /* 176 */ "expr ::= nm DOT nm",
 /* 177 */ "expr ::= nm DOT nm DOT nm",
 /* 178 */ "term ::= INTEGER",
 /* 179 */ "term ::= FLOAT",
 /* 180 */ "term ::= STRING",
 /* 181 */ "expr ::= BLOB",
 /* 182 */ "expr ::= REGISTER",
 /* 183 */ "expr ::= VARIABLE",
 /* 184 */ "expr ::= ID LP exprlist RP",
 /* 185 */ "expr ::= ID LP STAR RP",
 /* 186 */ "term ::= CTIME",
 /* 187 */ "term ::= CDATE",
 /* 188 */ "term ::= CTIMESTAMP",
 /* 189 */ "expr ::= expr AND expr",
 /* 190 */ "expr ::= expr OR expr",
 /* 191 */ "expr ::= expr LT expr",
 /* 192 */ "expr ::= expr GT expr",
 /* 193 */ "expr ::= expr LE expr",
 /* 194 */ "expr ::= expr GE expr",
 /* 195 */ "expr ::= expr NE expr",
 /* 196 */ "expr ::= expr EQ expr",
 /* 197 */ "expr ::= expr BITAND expr",
 /* 198 */ "expr ::= expr BITOR expr",
 /* 199 */ "expr ::= expr LSHIFT expr",
 /* 200 */ "expr ::= expr RSHIFT expr",
 /* 201 */ "expr ::= expr PLUS expr",
 /* 202 */ "expr ::= expr MINUS expr",
 /* 203 */ "expr ::= expr STAR expr",
 /* 204 */ "expr ::= expr SLASH expr",
 /* 205 */ "expr ::= expr REM expr",
 /* 206 */ "expr ::= expr CONCAT expr",
 /* 207 */ "likeop ::= LIKE",
 /* 208 */ "likeop ::= GLOB",
 /* 209 */ "likeop ::= NOT LIKE",
 /* 210 */ "likeop ::= NOT GLOB",
 /* 211 */ "escape ::= ESCAPE expr",
 /* 212 */ "escape ::=",
 /* 213 */ "expr ::= expr likeop expr escape",
 /* 214 */ "expr ::= expr ISNULL",
 /* 215 */ "expr ::= expr IS NULL",
 /* 216 */ "expr ::= expr NOTNULL",
 /* 217 */ "expr ::= expr NOT NULL",
 /* 218 */ "expr ::= expr IS NOT NULL",
 /* 219 */ "expr ::= NOT expr",
 /* 220 */ "expr ::= BITNOT expr",
 /* 221 */ "expr ::= MINUS expr",
 /* 222 */ "expr ::= PLUS expr",
 /* 223 */ "between_op ::= BETWEEN",
 /* 224 */ "between_op ::= NOT BETWEEN",
 /* 225 */ "expr ::= expr between_op expr AND expr",
 /* 226 */ "in_op ::= IN",
 /* 227 */ "in_op ::= NOT IN",
 /* 228 */ "expr ::= expr in_op LP exprlist RP",
 /* 229 */ "expr ::= LP select RP",
 /* 230 */ "expr ::= expr in_op LP select RP",
 /* 231 */ "expr ::= expr in_op nm dbnm",
 /* 232 */ "expr ::= EXISTS LP select RP",
 /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END",
 /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
 /* 235 */ "case_exprlist ::= WHEN expr THEN expr",
 /* 236 */ "case_else ::= ELSE expr",
 /* 237 */ "case_else ::=",
 /* 238 */ "case_operand ::= expr",
 /* 239 */ "case_operand ::=",
 /* 240 */ "exprlist ::= exprlist COMMA expritem",
 /* 241 */ "exprlist ::= expritem",
 /* 242 */ "expritem ::= expr",
 /* 243 */ "expritem ::=",
 /* 244 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf",
 /* 245 */ "uniqueflag ::= UNIQUE",
 /* 246 */ "uniqueflag ::=",
 /* 247 */ "idxlist_opt ::=",
 /* 248 */ "idxlist_opt ::= LP idxlist RP",
 /* 249 */ "idxlist ::= idxlist COMMA idxitem collate sortorder",
 /* 250 */ "idxlist ::= idxitem collate sortorder",
 /* 251 */ "idxitem ::= nm",
 /* 252 */ "cmd ::= DROP INDEX fullname",
 /* 253 */ "cmd ::= VACUUM",
 /* 254 */ "cmd ::= VACUUM nm",
 /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nm",
 /* 256 */ "cmd ::= PRAGMA nm dbnm EQ ON",
 /* 257 */ "cmd ::= PRAGMA nm dbnm EQ plus_num",
 /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
 /* 259 */ "cmd ::= PRAGMA nm dbnm LP nm RP",
 /* 260 */ "cmd ::= PRAGMA nm dbnm",
 /* 261 */ "plus_num ::= plus_opt number",
 /* 262 */ "minus_num ::= MINUS number",
 /* 263 */ "number ::= INTEGER",
 /* 264 */ "number ::= FLOAT",
 /* 265 */ "plus_opt ::= PLUS",
 /* 266 */ "plus_opt ::=",
 /* 267 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
 /* 268 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
 /* 269 */ "trigger_time ::= BEFORE",
 /* 270 */ "trigger_time ::= AFTER",
 /* 271 */ "trigger_time ::= INSTEAD OF",
 /* 272 */ "trigger_time ::=",
 /* 273 */ "trigger_event ::= DELETE",
 /* 274 */ "trigger_event ::= INSERT",
 /* 275 */ "trigger_event ::= UPDATE",
 /* 276 */ "trigger_event ::= UPDATE OF inscollist",
 /* 277 */ "foreach_clause ::=",
 /* 278 */ "foreach_clause ::= FOR EACH ROW",
 /* 279 */ "foreach_clause ::= FOR EACH STATEMENT",
 /* 280 */ "when_clause ::=",
 /* 281 */ "when_clause ::= WHEN expr",
 /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list",
 /* 283 */ "trigger_cmd_list ::=",
 /* 284 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
 /* 285 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
 /* 286 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
 /* 287 */ "trigger_cmd ::= DELETE FROM nm where_opt",
 /* 288 */ "trigger_cmd ::= select",
 /* 289 */ "expr ::= RAISE LP IGNORE RP",
 /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP",
 /* 291 */ "raisetype ::= ROLLBACK",
 /* 292 */ "raisetype ::= ABORT",
 /* 293 */ "raisetype ::= FAIL",
 /* 294 */ "cmd ::= DROP TRIGGER fullname",
 /* 295 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt",
 /* 296 */ "key_opt ::=",
 /* 297 */ "key_opt ::= KEY ids",
 /* 298 */ "key_opt ::= KEY BLOB",
 /* 299 */ "database_kw_opt ::= DATABASE",
 /* 300 */ "database_kw_opt ::=",
 /* 301 */ "cmd ::= DETACH database_kw_opt nm",
 /* 302 */ "cmd ::= REINDEX",
 /* 303 */ "cmd ::= REINDEX nm dbnm",
 /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
};
#endif /* NDEBUG */

/*
** This function returns the symbolic name associated with a token
** value.
*/
const char *sqlite3ParserTokenName(int tokenType){
#ifndef NDEBUG
  if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
    return yyTokenName[tokenType];
  }else{
    return "Unknown";
  }
#else
  return "";
#endif
}

/* 
** This function allocates a new parser.
** The only argument is a pointer to a function which works like
** malloc.
**
** Inputs:
** A pointer to the function used to allocate memory.
**
** Outputs:
** A pointer to a parser.  This pointer is used in subsequent calls
** to sqlite3Parser and sqlite3ParserFree.
*/
void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){
  yyParser *pParser;
  pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
  if( pParser ){
    pParser->yyidx = -1;
  }
  return pParser;
}

/* The following function deletes the value associated with a
** symbol.  The symbol can be either a terminal or nonterminal.
** "yymajor" is the symbol code, and "yypminor" is a pointer to
** the value.
*/
static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
  switch( yymajor ){
    /* Here is inserted the actions which take place when a
    ** terminal or non-terminal is destroyed.  This can happen
    ** when the symbol is popped from the stack during a
    ** reduce or during error processing or when a parser is 
    ** being destroyed before it is finished parsing.
    **
    ** Note: during a reduce, the only symbols destroyed are those
    ** which appear on the RHS of the rule, but which are not used
    ** inside the C code.
    */
    case 157:
    case 189:
    case 206:
#line 325 "parse.y"
{sqlite3SelectDelete((yypminor->yy331));}
#line 1315 "parse.c"
      break;
    case 170:
    case 174:
    case 194:
    case 196:
    case 204:
    case 210:
    case 224:
#line 584 "parse.y"
{sqlite3ExprDelete((yypminor->yy454));}
#line 1326 "parse.c"
      break;
    case 175:
    case 183:
    case 192:
    case 195:
    case 197:
    case 199:
    case 209:
    case 212:
    case 213:
    case 216:
    case 222:
#line 796 "parse.y"
{sqlite3ExprListDelete((yypminor->yy266));}
#line 1341 "parse.c"
      break;
    case 188:
    case 193:
    case 201:
    case 202:
#line 454 "parse.y"
{sqlite3SrcListDelete((yypminor->yy427));}
#line 1349 "parse.c"
      break;
    case 198:
#line 516 "parse.y"
{
  sqlite3ExprDelete((yypminor->yy348).pLimit);
  sqlite3ExprDelete((yypminor->yy348).pOffset);
}
#line 1357 "parse.c"
      break;
    case 205:
    case 208:
    case 215:
#line 472 "parse.y"
{sqlite3IdListDelete((yypminor->yy272));}
#line 1364 "parse.c"
      break;
    case 230:
    case 235:
#line 889 "parse.y"
{sqlite3DeleteTriggerStep((yypminor->yy455));}
#line 1370 "parse.c"
      break;
    case 232:
#line 873 "parse.y"
{sqlite3IdListDelete((yypminor->yy62).b);}
#line 1375 "parse.c"
      break;
    default:  break;   /* If no destructor action specified: do nothing */
  }
}

/*
** Pop the parser's stack once.
**
** If there is a destructor routine associated with the token which
** is popped from the stack, then call it.
**
** Return the major token number for the symbol popped.
*/
static int yy_pop_parser_stack(yyParser *pParser){
  YYCODETYPE yymajor;
  yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];

  if( pParser->yyidx<0 ) return 0;
#ifndef NDEBUG
  if( yyTraceFILE && pParser->yyidx>=0 ){
    fprintf(yyTraceFILE,"%sPopping %s\n",
      yyTracePrompt,
      yyTokenName[yytos->major]);
  }
#endif
  yymajor = yytos->major;
  yy_destructor( yymajor, &yytos->minor);
  pParser->yyidx--;
  return yymajor;
}

/* 
** Deallocate and destroy a parser.  Destructors are all called for
** all stack elements before shutting the parser down.
**
** Inputs:
** <ul>
** <li>  A pointer to the parser.  This should be a pointer
**       obtained from sqlite3ParserAlloc.
** <li>  A pointer to a function used to reclaim memory obtained
**       from malloc.
** </ul>
*/
void sqlite3ParserFree(
  void *p,                    /* The parser to be deleted */
  void (*freeProc)(void*)     /* Function used to reclaim memory */
){
  yyParser *pParser = (yyParser*)p;
  if( pParser==0 ) return;
  while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
  (*freeProc)((void*)pParser);
}

/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
**
** If the look-ahead token is YYNOCODE, then check to see if the action is
** independent of the look-ahead.  If it is, return the action, otherwise
** return YY_NO_ACTION.
*/
static int yy_find_shift_action(
  yyParser *pParser,        /* The parser */
  int iLookAhead            /* The look-ahead token */
){
  int i;
  int stateno = pParser->yystack[pParser->yyidx].stateno;
 
  /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
  i = yy_shift_ofst[stateno];
  if( i==YY_SHIFT_USE_DFLT ){
    return yy_default[stateno];
  }
  if( iLookAhead==YYNOCODE ){
    return YY_NO_ACTION;
  }
  i += iLookAhead;
  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
    int iFallback;            /* Fallback token */
    if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
           && (iFallback = yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
      if( yyTraceFILE ){
        fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
           yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
      }
#endif
      return yy_find_shift_action(pParser, iFallback);
    }
#endif
    return yy_default[stateno];
  }else{
    return yy_action[i];
  }
}

/*
** Find the appropriate action for a parser given the non-terminal
** look-ahead token iLookAhead.
**
** If the look-ahead token is YYNOCODE, then check to see if the action is
** independent of the look-ahead.  If it is, return the action, otherwise
** return YY_NO_ACTION.
*/
static int yy_find_reduce_action(
  int stateno,              /* Current state number */
  int iLookAhead            /* The look-ahead token */
){
  int i;
  /* int stateno = pParser->yystack[pParser->yyidx].stateno; */
 
  i = yy_reduce_ofst[stateno];
  if( i==YY_REDUCE_USE_DFLT ){
    return yy_default[stateno];
  }
  if( iLookAhead==YYNOCODE ){
    return YY_NO_ACTION;
  }
  i += iLookAhead;
  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
    return yy_default[stateno];
  }else{
    return yy_action[i];
  }
}

/*
** Perform a shift action.
*/
static void yy_shift(
  yyParser *yypParser,          /* The parser to be shifted */
  int yyNewState,               /* The new state to shift in */
  int yyMajor,                  /* The major token to shift in */
  YYMINORTYPE *yypMinor         /* Pointer ot the minor token to shift in */
){
  yyStackEntry *yytos;
  yypParser->yyidx++;
  if( yypParser->yyidx>=YYSTACKDEPTH ){
     sqlite3ParserARG_FETCH;
     yypParser->yyidx--;
#ifndef NDEBUG
     if( yyTraceFILE ){
       fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
     }
#endif
     while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
     /* Here code is inserted which will execute if the parser
     ** stack every overflows */
     sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
     return;
  }
  yytos = &yypParser->yystack[yypParser->yyidx];
  yytos->stateno = yyNewState;
  yytos->major = yyMajor;
  yytos->minor = *yypMinor;
#ifndef NDEBUG
  if( yyTraceFILE && yypParser->yyidx>0 ){
    int i;
    fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
    fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
    for(i=1; i<=yypParser->yyidx; i++)
      fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
    fprintf(yyTraceFILE,"\n");
  }
#endif
}

/* The following table contains information about every rule that
** is used during the reduce.
*/
static const struct {
  YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
  unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
  { 142, 1 },
  { 143, 2 },
  { 143, 1 },
  { 145, 1 },
  { 144, 1 },
  { 144, 3 },
  { 147, 0 },
  { 147, 1 },
  { 146, 3 },
  { 149, 0 },
  { 149, 1 },
  { 149, 2 },
  { 148, 0 },
  { 148, 1 },
  { 148, 1 },
  { 148, 1 },
  { 146, 2 },
  { 146, 2 },
  { 146, 2 },
  { 146, 2 },
  { 151, 5 },
  { 153, 1 },
  { 153, 0 },
  { 152, 4 },
  { 152, 2 },
  { 155, 3 },
  { 155, 1 },
  { 158, 3 },
  { 159, 1 },
  { 162, 1 },
  { 163, 1 },
  { 163, 1 },
  { 150, 1 },
  { 150, 1 },
  { 150, 1 },
  { 160, 0 },
  { 160, 1 },
  { 160, 4 },
  { 160, 6 },
  { 164, 1 },
  { 164, 2 },
  { 165, 1 },
  { 165, 1 },
  { 161, 2 },
  { 161, 0 },
  { 168, 3 },
  { 168, 1 },
  { 168, 2 },
  { 168, 3 },
  { 168, 3 },
  { 168, 2 },
  { 169, 2 },
  { 169, 3 },
  { 169, 5 },
  { 169, 2 },
  { 169, 5 },
  { 169, 4 },
  { 169, 1 },
  { 169, 2 },
  { 173, 0 },
  { 173, 1 },
  { 176, 0 },
  { 176, 2 },
  { 178, 2 },
  { 178, 3 },
  { 178, 3 },
  { 178, 3 },
  { 179, 2 },
  { 179, 2 },
  { 179, 1 },
  { 179, 1 },
  { 177, 3 },
  { 177, 2 },
  { 180, 0 },
  { 180, 2 },
  { 180, 2 },
  { 156, 0 },
  { 156, 2 },
  { 181, 3 },
  { 181, 2 },
  { 181, 1 },
  { 182, 2 },
  { 182, 7 },
  { 182, 5 },
  { 182, 3 },
  { 182, 10 },
  { 184, 0 },
  { 184, 1 },
  { 171, 0 },
  { 171, 3 },
  { 185, 0 },
  { 185, 2 },
  { 186, 1 },
  { 186, 1 },
  { 186, 1 },
  { 146, 3 },
  { 146, 7 },
  { 146, 3 },
  { 146, 1 },
  { 157, 1 },
  { 157, 3 },
  { 190, 1 },
  { 190, 2 },
  { 190, 1 },
  { 190, 1 },
  { 189, 9 },
  { 191, 1 },
  { 191, 1 },
  { 191, 0 },
  { 199, 2 },
  { 199, 0 },
  { 192, 3 },
  { 192, 2 },
  { 192, 4 },
  { 200, 2 },
  { 200, 1 },
  { 200, 0 },
  { 193, 0 },
  { 193, 2 },
  { 202, 2 },
  { 202, 0 },
  { 201, 6 },
  { 201, 7 },
  { 206, 1 },
  { 206, 1 },
  { 154, 0 },
  { 154, 2 },
  { 188, 2 },
  { 203, 1 },
  { 203, 1 },
  { 203, 2 },
  { 203, 3 },
  { 203, 4 },
  { 204, 2 },
  { 204, 0 },
  { 205, 4 },
  { 205, 0 },
  { 197, 0 },
  { 197, 3 },
  { 209, 5 },
  { 209, 3 },
  { 210, 1 },
  { 172, 1 },
  { 172, 1 },
  { 172, 0 },
  { 211, 0 },
  { 211, 2 },
  { 195, 0 },
  { 195, 3 },
  { 196, 0 },
  { 196, 2 },
  { 198, 0 },
  { 198, 2 },
  { 198, 4 },
  { 198, 4 },
  { 146, 4 },
  { 194, 0 },
  { 194, 2 },
  { 146, 6 },
  { 213, 5 },
  { 213, 3 },
  { 146, 8 },
  { 146, 5 },
  { 214, 2 },
  { 214, 1 },
  { 216, 3 },
  { 216, 1 },
  { 215, 0 },
  { 215, 3 },
  { 208, 3 },
  { 208, 1 },
  { 174, 1 },
  { 174, 3 },
  { 170, 1 },
  { 174, 1 },
  { 174, 1 },
  { 174, 3 },
  { 174, 5 },
  { 170, 1 },
  { 170, 1 },
  { 170, 1 },
  { 174, 1 },
  { 174, 1 },
  { 174, 1 },
  { 174, 4 },
  { 174, 4 },
  { 170, 1 },
  { 170, 1 },
  { 170, 1 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 217, 1 },
  { 217, 1 },
  { 217, 2 },
  { 217, 2 },
  { 218, 2 },
  { 218, 0 },
  { 174, 4 },
  { 174, 2 },
  { 174, 3 },
  { 174, 2 },
  { 174, 3 },
  { 174, 4 },
  { 174, 2 },
  { 174, 2 },
  { 174, 2 },
  { 174, 2 },
  { 219, 1 },
  { 219, 2 },
  { 174, 5 },
  { 220, 1 },
  { 220, 2 },
  { 174, 5 },
  { 174, 3 },
  { 174, 5 },
  { 174, 4 },
  { 174, 4 },
  { 174, 5 },
  { 222, 5 },
  { 222, 4 },
  { 223, 2 },
  { 223, 0 },
  { 221, 1 },
  { 221, 0 },
  { 212, 3 },
  { 212, 1 },
  { 224, 1 },
  { 224, 0 },
  { 146, 11 },
  { 225, 1 },
  { 225, 0 },
  { 175, 0 },
  { 175, 3 },
  { 183, 5 },
  { 183, 3 },
  { 226, 1 },
  { 146, 3 },
  { 146, 1 },
  { 146, 2 },
  { 146, 5 },
  { 146, 5 },
  { 146, 5 },
  { 146, 5 },
  { 146, 6 },
  { 146, 3 },
  { 166, 2 },
  { 167, 2 },
  { 228, 1 },
  { 228, 1 },
  { 227, 1 },
  { 227, 0 },
  { 146, 5 },
  { 229, 10 },
  { 231, 1 },
  { 231, 1 },
  { 231, 2 },
  { 231, 0 },
  { 232, 1 },
  { 232, 1 },
  { 232, 1 },
  { 232, 3 },
  { 233, 0 },
  { 233, 3 },
  { 233, 3 },
  { 234, 0 },
  { 234, 2 },
  { 230, 3 },
  { 230, 0 },
  { 235, 6 },
  { 235, 8 },
  { 235, 5 },
  { 235, 4 },
  { 235, 1 },
  { 174, 4 },
  { 174, 6 },
  { 187, 1 },
  { 187, 1 },
  { 187, 1 },
  { 146, 3 },
  { 146, 6 },
  { 237, 0 },
  { 237, 2 },
  { 237, 2 },
  { 236, 1 },
  { 236, 0 },
  { 146, 3 },
  { 146, 1 },
  { 146, 3 },
  { 146, 6 },
};

static void yy_accept(yyParser*);  /* Forward Declaration */

/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
*/
static void yy_reduce(
  yyParser *yypParser,         /* The parser */
  int yyruleno                 /* Number of the rule by which to reduce */
){
  int yygoto;                     /* The next state */
  int yyact;                      /* The next action */
  YYMINORTYPE yygotominor;        /* The LHS of the rule reduced */
  yyStackEntry *yymsp;            /* The top of the parser's stack */
  int yysize;                     /* Amount to pop the stack */
  sqlite3ParserARG_FETCH;
  yymsp = &yypParser->yystack[yypParser->yyidx];
#ifndef NDEBUG
  if( yyTraceFILE && yyruleno>=0 
        && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
    fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
      yyRuleName[yyruleno]);
  }
#endif /* NDEBUG */

#ifndef NDEBUG
  /* Silence complaints from purify about yygotominor being uninitialized
  ** in some cases when it is copied into the stack after the following
  ** switch.  yygotominor is uninitialized when a rule reduces that does
  ** not set the value of its left-hand side nonterminal.  Leaving the
  ** value of the nonterminal uninitialized is utterly harmless as long
  ** as the value is never used.  So really the only thing this code
  ** accomplishes is to quieten purify.  
  */
  memset(&yygotominor, 0, sizeof(yygotominor));
#endif

  switch( yyruleno ){
  /* Beginning here are the reduction cases.  A typical example
  ** follows:
  **   case 0:
  **  #line <lineno> <grammarfile>
  **     { ... }           // User supplied code
  **  #line <lineno> <thisfile>
  **     break;
  */
      case 3:
#line 84 "parse.y"
{ sqlite3FinishCoding(pParse); }
#line 1907 "parse.c"
        break;
      case 6:
#line 87 "parse.y"
{ sqlite3BeginParse(pParse, 0); }
#line 1912 "parse.c"
        break;
      case 7:
#line 89 "parse.y"
{ sqlite3BeginParse(pParse, 1); }
#line 1917 "parse.c"
        break;
      case 8:
#line 95 "parse.y"
{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy60);}
#line 1922 "parse.c"
        break;
      case 12:
#line 100 "parse.y"
{yygotominor.yy60 = TK_DEFERRED;}
#line 1927 "parse.c"
        break;
      case 13:
      case 14:
      case 15:
      case 101:
      case 103:
      case 104:
#line 101 "parse.y"
{yygotominor.yy60 = yymsp[0].major;}
#line 1937 "parse.c"
        break;
      case 16:
      case 17:
#line 104 "parse.y"
{sqlite3CommitTransaction(pParse);}
#line 1943 "parse.c"
        break;
      case 18:
#line 106 "parse.y"
{sqlite3RollbackTransaction(pParse);}
#line 1948 "parse.c"
        break;
      case 20:
#line 111 "parse.y"
{
   sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406,yymsp[-3].minor.yy60,0);
}
#line 1955 "parse.c"
        break;
      case 21:
      case 60:
      case 74:
      case 106:
      case 224:
      case 227:
#line 115 "parse.y"
{yygotominor.yy60 = 1;}
#line 1965 "parse.c"
        break;
      case 22:
      case 59:
      case 73:
      case 75:
      case 86:
      case 107:
      case 108:
      case 223:
      case 226:
#line 116 "parse.y"
{yygotominor.yy60 = 0;}
#line 1978 "parse.c"
        break;
      case 23:
#line 117 "parse.y"
{
  sqlite3EndTable(pParse,&yymsp[0].minor.yy0,0);
}
#line 1985 "parse.c"
        break;
      case 24:
#line 120 "parse.y"
{
  sqlite3EndTable(pParse,0,yymsp[0].minor.yy331);
  sqlite3SelectDelete(yymsp[0].minor.yy331);
}
#line 1993 "parse.c"
        break;
      case 28:
#line 132 "parse.y"
{sqlite3AddColumn(pParse,&yymsp[0].minor.yy406);}
#line 1998 "parse.c"
        break;
      case 29:
      case 30:
      case 31:
      case 32:
      case 33:
      case 34:
      case 263:
      case 264:
#line 138 "parse.y"
{yygotominor.yy406 = yymsp[0].minor.yy0;}
#line 2010 "parse.c"
        break;
      case 36:
#line 193 "parse.y"
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy406,&yymsp[0].minor.yy406);}
#line 2015 "parse.c"
        break;
      case 37:
#line 194 "parse.y"
{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy406,&yymsp[0].minor.yy0);}
#line 2020 "parse.c"
        break;
      case 38:
#line 196 "parse.y"
{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy406,&yymsp[0].minor.yy0);}
#line 2025 "parse.c"
        break;
      case 39:
      case 114:
      case 115:
      case 126:
      case 146:
      case 251:
      case 261:
      case 262:
#line 198 "parse.y"
{yygotominor.yy406 = yymsp[0].minor.yy406;}
#line 2037 "parse.c"
        break;
      case 40:
#line 199 "parse.y"
{yygotominor.yy406.z=yymsp[-1].minor.yy406.z; yygotominor.yy406.n=yymsp[0].minor.yy406.n+(yymsp[0].minor.yy406.z-yymsp[-1].minor.yy406.z);}
#line 2042 "parse.c"
        break;
      case 41:
#line 201 "parse.y"
{ yygotominor.yy60 = atoi(yymsp[0].minor.yy406.z); }
#line 2047 "parse.c"
        break;
      case 42:
#line 202 "parse.y"
{ yygotominor.yy60 = -atoi(yymsp[0].minor.yy406.z); }
#line 2052 "parse.c"
        break;
      case 47:
      case 48:
#line 207 "parse.y"
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454);}
#line 2058 "parse.c"
        break;
      case 49:
#line 209 "parse.y"
{
  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy454, 0, 0);
  sqlite3AddDefaultValue(pParse,p);
}
#line 2066 "parse.c"
        break;
      case 50:
#line 213 "parse.y"
{
  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy406);
  sqlite3AddDefaultValue(pParse,p);
}
#line 2074 "parse.c"
        break;
      case 52:
#line 222 "parse.y"
{sqlite3AddNotNull(pParse, yymsp[0].minor.yy60);}
#line 2079 "parse.c"
        break;
      case 53:
#line 224 "parse.y"
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy60,yymsp[0].minor.yy60);}
#line 2084 "parse.c"
        break;
      case 54:
#line 225 "parse.y"
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy60,0,0);}
#line 2089 "parse.c"
        break;
      case 56:
#line 228 "parse.y"
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy406,yymsp[-1].minor.yy266,yymsp[0].minor.yy60);}
#line 2094 "parse.c"
        break;
      case 57:
#line 229 "parse.y"
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy60);}
#line 2099 "parse.c"
        break;
      case 58:
#line 230 "parse.y"
{sqlite3AddCollateType(pParse, yymsp[0].minor.yy406.z, yymsp[0].minor.yy406.n);}
#line 2104 "parse.c"
        break;
      case 61:
#line 243 "parse.y"
{ yygotominor.yy60 = OE_Restrict * 0x010101; }
#line 2109 "parse.c"
        break;
      case 62:
#line 244 "parse.y"
{ yygotominor.yy60 = (yymsp[-1].minor.yy60 & yymsp[0].minor.yy243.mask) | yymsp[0].minor.yy243.value; }
#line 2114 "parse.c"
        break;
      case 63:
#line 246 "parse.y"
{ yygotominor.yy243.value = 0;     yygotominor.yy243.mask = 0x000000; }
#line 2119 "parse.c"
        break;
      case 64:
#line 247 "parse.y"
{ yygotominor.yy243.value = yymsp[0].minor.yy60;     yygotominor.yy243.mask = 0x0000ff; }
#line 2124 "parse.c"
        break;
      case 65:
#line 248 "parse.y"
{ yygotominor.yy243.value = yymsp[0].minor.yy60<<8;  yygotominor.yy243.mask = 0x00ff00; }
#line 2129 "parse.c"
        break;
      case 66:
#line 249 "parse.y"
{ yygotominor.yy243.value = yymsp[0].minor.yy60<<16; yygotominor.yy243.mask = 0xff0000; }
#line 2134 "parse.c"
        break;
      case 67:
#line 251 "parse.y"
{ yygotominor.yy60 = OE_SetNull; }
#line 2139 "parse.c"
        break;
      case 68:
#line 252 "parse.y"
{ yygotominor.yy60 = OE_SetDflt; }
#line 2144 "parse.c"
        break;
      case 69:
#line 253 "parse.y"
{ yygotominor.yy60 = OE_Cascade; }
#line 2149 "parse.c"
        break;
      case 70:
#line 254 "parse.y"
{ yygotominor.yy60 = OE_Restrict; }
#line 2154 "parse.c"
        break;
      case 71:
      case 72:
      case 87:
      case 89:
      case 91:
      case 92:
      case 163:
#line 256 "parse.y"
{yygotominor.yy60 = yymsp[0].minor.yy60;}
#line 2165 "parse.c"
        break;
      case 82:
#line 273 "parse.y"
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy266,yymsp[0].minor.yy60,yymsp[-2].minor.yy60);}
#line 2170 "parse.c"
        break;
      case 83:
#line 275 "parse.y"
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy266,yymsp[0].minor.yy60,0,0);}
#line 2175 "parse.c"
        break;
      case 85:
#line 278 "parse.y"
{
    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy266, &yymsp[-3].minor.yy406, yymsp[-2].minor.yy266, yymsp[-1].minor.yy60);
    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy60);
}
#line 2183 "parse.c"
        break;
      case 88:
      case 90:
#line 292 "parse.y"
{yygotominor.yy60 = OE_Default;}
#line 2189 "parse.c"
        break;
      case 93:
#line 297 "parse.y"
{yygotominor.yy60 = OE_Ignore;}
#line 2194 "parse.c"
        break;
      case 94:
      case 164:
#line 298 "parse.y"
{yygotominor.yy60 = OE_Replace;}
#line 2200 "parse.c"
        break;
      case 95:
#line 302 "parse.y"
{
  sqlite3DropTable(pParse, yymsp[0].minor.yy427, 0);
}
#line 2207 "parse.c"
        break;
      case 96:
#line 309 "parse.y"
{
  sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy406, &yymsp[-2].minor.yy406, yymsp[0].minor.yy331, yymsp[-5].minor.yy60);
}
#line 2214 "parse.c"
        break;
      case 97:
#line 312 "parse.y"
{
  sqlite3DropTable(pParse, yymsp[0].minor.yy427, 1);
}
#line 2221 "parse.c"
        break;
      case 98:
#line 319 "parse.y"
{
  sqlite3Select(pParse, yymsp[0].minor.yy331, SRT_Callback, 0, 0, 0, 0, 0);
  sqlite3SelectDelete(yymsp[0].minor.yy331);
}
#line 2229 "parse.c"
        break;
      case 99:
      case 123:
#line 329 "parse.y"
{yygotominor.yy331 = yymsp[0].minor.yy331;}
#line 2235 "parse.c"
        break;
      case 100:
#line 331 "parse.y"
{
  if( yymsp[0].minor.yy331 ){
    yymsp[0].minor.yy331->op = yymsp[-1].minor.yy60;
    yymsp[0].minor.yy331->pPrior = yymsp[-2].minor.yy331;
  }
  yygotominor.yy331 = yymsp[0].minor.yy331;
}
#line 2246 "parse.c"
        break;
      case 102:
#line 340 "parse.y"
{yygotominor.yy60 = TK_ALL;}
#line 2251 "parse.c"
        break;
      case 105:
#line 345 "parse.y"
{
  yygotominor.yy331 = sqlite3SelectNew(yymsp[-6].minor.yy266,yymsp[-5].minor.yy427,yymsp[-4].minor.yy454,yymsp[-3].minor.yy266,yymsp[-2].minor.yy454,yymsp[-1].minor.yy266,yymsp[-7].minor.yy60,yymsp[0].minor.yy348.pLimit,yymsp[0].minor.yy348.pOffset);
}
#line 2258 "parse.c"
        break;
      case 109:
      case 248:
#line 366 "parse.y"
{yygotominor.yy266 = yymsp[-1].minor.yy266;}
#line 2264 "parse.c"
        break;
      case 110:
      case 137:
      case 147:
      case 247:
#line 367 "parse.y"
{yygotominor.yy266 = 0;}
#line 2272 "parse.c"
        break;
      case 111:
#line 368 "parse.y"
{
   yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-2].minor.yy266,yymsp[-1].minor.yy454,yymsp[0].minor.yy406.n?&yymsp[0].minor.yy406:0);
}
#line 2279 "parse.c"
        break;
      case 112:
#line 371 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-1].minor.yy266, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
}
#line 2286 "parse.c"
        break;
      case 113:
#line 374 "parse.y"
{
  Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0);
  Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406);
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-3].minor.yy266, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
}
#line 2295 "parse.c"
        break;
      case 116:
#line 386 "parse.y"
{yygotominor.yy406.n = 0;}
#line 2300 "parse.c"
        break;
      case 117:
#line 398 "parse.y"
{yygotominor.yy427 = sqliteMalloc(sizeof(*yygotominor.yy427));}
#line 2305 "parse.c"
        break;
      case 118:
#line 399 "parse.y"
{yygotominor.yy427 = yymsp[0].minor.yy427;}
#line 2310 "parse.c"
        break;
      case 119:
#line 404 "parse.y"
{
   yygotominor.yy427 = yymsp[-1].minor.yy427;
   if( yygotominor.yy427 && yygotominor.yy427->nSrc>0 ) yygotominor.yy427->a[yygotominor.yy427->nSrc-1].jointype = yymsp[0].minor.yy60;
}
#line 2318 "parse.c"
        break;
      case 120:
#line 408 "parse.y"
{yygotominor.yy427 = 0;}
#line 2323 "parse.c"
        break;
      case 121:
#line 409 "parse.y"
{
  yygotominor.yy427 = sqlite3SrcListAppend(yymsp[-5].minor.yy427,&yymsp[-4].minor.yy406,&yymsp[-3].minor.yy406);
  if( yymsp[-2].minor.yy406.n ) sqlite3SrcListAddAlias(yygotominor.yy427,&yymsp[-2].minor.yy406);
  if( yymsp[-1].minor.yy454 ){
    if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pOn = yymsp[-1].minor.yy454; }
    else { sqlite3ExprDelete(yymsp[-1].minor.yy454); }
  }
  if( yymsp[0].minor.yy272 ){
    if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pUsing = yymsp[0].minor.yy272; }
    else { sqlite3IdListDelete(yymsp[0].minor.yy272); }
  }
}
#line 2339 "parse.c"
        break;
      case 122:
#line 423 "parse.y"
{
    yygotominor.yy427 = sqlite3SrcListAppend(yymsp[-6].minor.yy427,0,0);
    yygotominor.yy427->a[yygotominor.yy427->nSrc-1].pSelect = yymsp[-4].minor.yy331;
    if( yymsp[-2].minor.yy406.n ) sqlite3SrcListAddAlias(yygotominor.yy427,&yymsp[-2].minor.yy406);
    if( yymsp[-1].minor.yy454 ){
      if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pOn = yymsp[-1].minor.yy454; }
      else { sqlite3ExprDelete(yymsp[-1].minor.yy454); }
    }
    if( yymsp[0].minor.yy272 ){
      if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pUsing = yymsp[0].minor.yy272; }
      else { sqlite3IdListDelete(yymsp[0].minor.yy272); }
    }
  }
#line 2356 "parse.c"
        break;
      case 124:
#line 444 "parse.y"
{
     yygotominor.yy331 = sqlite3SelectNew(0,yymsp[0].minor.yy427,0,0,0,0,0,0,0);
  }
#line 2363 "parse.c"
        break;
      case 125:
#line 450 "parse.y"
{yygotominor.yy406.z=0; yygotominor.yy406.n=0;}
#line 2368 "parse.c"
        break;
      case 127:
#line 455 "parse.y"
{yygotominor.yy427 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406);}
#line 2373 "parse.c"
        break;
      case 128:
      case 129:
#line 459 "parse.y"
{ yygotominor.yy60 = JT_INNER; }
#line 2379 "parse.c"
        break;
      case 130:
#line 461 "parse.y"
{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
#line 2384 "parse.c"
        break;
      case 131:
#line 462 "parse.y"
{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy406,0); }
#line 2389 "parse.c"
        break;
      case 132:
#line 464 "parse.y"
{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy406,&yymsp[-1].minor.yy406); }
#line 2394 "parse.c"
        break;
      case 133:
      case 141:
      case 150:
      case 157:
      case 171:
      case 211:
      case 236:
      case 238:
      case 242:
#line 468 "parse.y"
{yygotominor.yy454 = yymsp[0].minor.yy454;}
#line 2407 "parse.c"
        break;
      case 134:
      case 149:
      case 156:
      case 212:
      case 237:
      case 239:
      case 243:
#line 469 "parse.y"
{yygotominor.yy454 = 0;}
#line 2418 "parse.c"
        break;
      case 135:
      case 168:
#line 473 "parse.y"
{yygotominor.yy272 = yymsp[-1].minor.yy272;}
#line 2424 "parse.c"
        break;
      case 136:
      case 167:
#line 474 "parse.y"
{yygotominor.yy272 = 0;}
#line 2430 "parse.c"
        break;
      case 138:
      case 148:
#line 485 "parse.y"
{yygotominor.yy266 = yymsp[0].minor.yy266;}
#line 2436 "parse.c"
        break;
      case 139:
#line 486 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266,yymsp[-2].minor.yy454,yymsp[-1].minor.yy406.n>0?&yymsp[-1].minor.yy406:0);
  if( yygotominor.yy266 ) yygotominor.yy266->a[yygotominor.yy266->nExpr-1].sortOrder = yymsp[0].minor.yy60;
}
#line 2444 "parse.c"
        break;
      case 140:
#line 490 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy454,yymsp[-1].minor.yy406.n>0?&yymsp[-1].minor.yy406:0);
  if( yygotominor.yy266 && yygotominor.yy266->a ) yygotominor.yy266->a[0].sortOrder = yymsp[0].minor.yy60;
}
#line 2452 "parse.c"
        break;
      case 142:
      case 144:
#line 499 "parse.y"
{yygotominor.yy60 = SQLITE_SO_ASC;}
#line 2458 "parse.c"
        break;
      case 143:
#line 500 "parse.y"
{yygotominor.yy60 = SQLITE_SO_DESC;}
#line 2463 "parse.c"
        break;
      case 145:
#line 502 "parse.y"
{yygotominor.yy406.z = 0; yygotominor.yy406.n = 0;}
#line 2468 "parse.c"
        break;
      case 151:
#line 520 "parse.y"
{yygotominor.yy348.pLimit = 0; yygotominor.yy348.pOffset = 0;}
#line 2473 "parse.c"
        break;
      case 152:
#line 521 "parse.y"
{yygotominor.yy348.pLimit = yymsp[0].minor.yy454; yygotominor.yy348.pOffset = 0;}
#line 2478 "parse.c"
        break;
      case 153:
#line 523 "parse.y"
{yygotominor.yy348.pLimit = yymsp[-2].minor.yy454; yygotominor.yy348.pOffset = yymsp[0].minor.yy454;}
#line 2483 "parse.c"
        break;
      case 154:
#line 525 "parse.y"
{yygotominor.yy348.pOffset = yymsp[-2].minor.yy454; yygotominor.yy348.pLimit = yymsp[0].minor.yy454;}
#line 2488 "parse.c"
        break;
      case 155:
#line 529 "parse.y"
{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy427,yymsp[0].minor.yy454);}
#line 2493 "parse.c"
        break;
      case 158:
#line 543 "parse.y"
{sqlite3Update(pParse,yymsp[-3].minor.yy427,yymsp[-1].minor.yy266,yymsp[0].minor.yy454,yymsp[-4].minor.yy60);}
#line 2498 "parse.c"
        break;
      case 159:
#line 546 "parse.y"
{yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266,yymsp[0].minor.yy454,&yymsp[-2].minor.yy406);}
#line 2503 "parse.c"
        break;
      case 160:
#line 547 "parse.y"
{yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[0].minor.yy454,&yymsp[-2].minor.yy406);}
#line 2508 "parse.c"
        break;
      case 161:
#line 553 "parse.y"
{sqlite3Insert(pParse, yymsp[-5].minor.yy427, yymsp[-1].minor.yy266, 0, yymsp[-4].minor.yy272, yymsp[-7].minor.yy60);}
#line 2513 "parse.c"
        break;
      case 162:
#line 555 "parse.y"
{sqlite3Insert(pParse, yymsp[-2].minor.yy427, 0, yymsp[0].minor.yy331, yymsp[-1].minor.yy272, yymsp[-4].minor.yy60);}
#line 2518 "parse.c"
        break;
      case 165:
      case 240:
#line 565 "parse.y"
{yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-2].minor.yy266,yymsp[0].minor.yy454,0);}
#line 2524 "parse.c"
        break;
      case 166:
      case 241:
#line 566 "parse.y"
{yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[0].minor.yy454,0);}
#line 2530 "parse.c"
        break;
      case 169:
#line 575 "parse.y"
{yygotominor.yy272 = sqlite3IdListAppend(yymsp[-2].minor.yy272,&yymsp[0].minor.yy406);}
#line 2535 "parse.c"
        break;
      case 170:
#line 576 "parse.y"
{yygotominor.yy272 = sqlite3IdListAppend(0,&yymsp[0].minor.yy406);}
#line 2540 "parse.c"
        break;
      case 172:
#line 587 "parse.y"
{yygotominor.yy454 = yymsp[-1].minor.yy454; sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
#line 2545 "parse.c"
        break;
      case 173:
      case 178:
      case 179:
      case 180:
      case 181:
#line 588 "parse.y"
{yygotominor.yy454 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
#line 2554 "parse.c"
        break;
      case 174:
      case 175:
#line 589 "parse.y"
{yygotominor.yy454 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
#line 2560 "parse.c"
        break;
      case 176:
#line 591 "parse.y"
{
  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406);
  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy406);
  yygotominor.yy454 = sqlite3Expr(TK_DOT, temp1, temp2, 0);
}
#line 2569 "parse.c"
        break;
      case 177:
#line 596 "parse.y"
{
  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy406);
  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406);
  Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy406);
  Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
  yygotominor.yy454 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
}
#line 2580 "parse.c"
        break;
      case 182:
#line 607 "parse.y"
{yygotominor.yy454 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
#line 2585 "parse.c"
        break;
      case 183:
#line 608 "parse.y"
{
  Token *pToken = &yymsp[0].minor.yy0;
  Expr *pExpr = yygotominor.yy454 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
  sqlite3ExprAssignVarNumber(pParse, pExpr);
}
#line 2594 "parse.c"
        break;
      case 184:
#line 613 "parse.y"
{
  yygotominor.yy454 = sqlite3ExprFunction(yymsp[-1].minor.yy266, &yymsp[-3].minor.yy0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
#line 2602 "parse.c"
        break;
      case 185:
#line 617 "parse.y"
{
  yygotominor.yy454 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
#line 2610 "parse.c"
        break;
      case 186:
      case 187:
      case 188:
#line 621 "parse.y"
{yygotominor.yy454 = sqlite3Expr(yymsp[0].major,0,0,0);}
#line 2617 "parse.c"
        break;
      case 189:
      case 190:
      case 191:
      case 192:
      case 193:
      case 194:
      case 195:
      case 196:
      case 197:
      case 198:
      case 199:
      case 200:
      case 201:
      case 202:
      case 203:
      case 204:
      case 205:
      case 206:
#line 624 "parse.y"
{yygotominor.yy454 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy454, yymsp[0].minor.yy454, 0);}
#line 2639 "parse.c"
        break;
      case 207:
#line 643 "parse.y"
{yygotominor.yy258.opcode = TK_LIKE; yygotominor.yy258.not = 0;}
#line 2644 "parse.c"
        break;
      case 208:
#line 644 "parse.y"
{yygotominor.yy258.opcode = TK_GLOB; yygotominor.yy258.not = 0;}
#line 2649 "parse.c"
        break;
      case 209:
#line 645 "parse.y"
{yygotominor.yy258.opcode = TK_LIKE; yygotominor.yy258.not = 1;}
#line 2654 "parse.c"
        break;
      case 210:
#line 646 "parse.y"
{yygotominor.yy258.opcode = TK_GLOB; yygotominor.yy258.not = 1;}
#line 2659 "parse.c"
        break;
      case 213:
#line 650 "parse.y"
{
  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy454, 0);
  pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy454, 0);
  if( yymsp[0].minor.yy454 ){
    pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy454, 0);
  }
  yygotominor.yy454 = sqlite3ExprFunction(pList, 0);
  if( yygotominor.yy454 ) yygotominor.yy454->op = yymsp[-2].minor.yy258.opcode;
  if( yymsp[-2].minor.yy258.not ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454, &yymsp[-3].minor.yy454->span, &yymsp[-1].minor.yy454->span);
}
#line 2674 "parse.c"
        break;
      case 214:
#line 662 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2682 "parse.c"
        break;
      case 215:
#line 666 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2690 "parse.c"
        break;
      case 216:
#line 670 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2698 "parse.c"
        break;
      case 217:
#line 674 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2706 "parse.c"
        break;
      case 218:
#line 678 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2714 "parse.c"
        break;
      case 219:
      case 220:
#line 682 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span);
}
#line 2723 "parse.c"
        break;
      case 221:
#line 690 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span);
}
#line 2731 "parse.c"
        break;
      case 222:
#line 694 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span);
}
#line 2739 "parse.c"
        break;
      case 225:
#line 701 "parse.y"
{
  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy454, 0);
  pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy454, 0);
  yygotominor.yy454 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy454, 0, 0);
  if( yygotominor.yy454 ) yygotominor.yy454->pList = pList;
  if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy454->span);
}
#line 2751 "parse.c"
        break;
      case 228:
#line 713 "parse.y"
{
    yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy454, 0, 0);
    if( yygotominor.yy454 ) yygotominor.yy454->pList = yymsp[-1].minor.yy266;
    if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);
    sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy0);
  }
#line 2761 "parse.c"
        break;
      case 229:
#line 719 "parse.y"
{
    yygotominor.yy454 = sqlite3Expr(TK_SELECT, 0, 0, 0);
    if( yygotominor.yy454 ) yygotominor.yy454->pSelect = yymsp[-1].minor.yy331;
    sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
  }
#line 2770 "parse.c"
        break;
      case 230:
#line 724 "parse.y"
{
    yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy454, 0, 0);
    if( yygotominor.yy454 ) yygotominor.yy454->pSelect = yymsp[-1].minor.yy331;
    if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);
    sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy0);
  }
#line 2780 "parse.c"
        break;
      case 231:
#line 730 "parse.y"
{
    SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406);
    yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy454, 0, 0);
    if( yygotominor.yy454 ) yygotominor.yy454->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0);
    if( yymsp[-2].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);
    sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy454->span,yymsp[0].minor.yy406.z?&yymsp[0].minor.yy406:&yymsp[-1].minor.yy406);
  }
#line 2791 "parse.c"
        break;
      case 232:
#line 737 "parse.y"
{
    Expr *p = yygotominor.yy454 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
    if( p ){
      p->pSelect = yymsp[-1].minor.yy331;
      sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
    }
  }
#line 2802 "parse.c"
        break;
      case 233:
#line 747 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, 0);
  if( yygotominor.yy454 ) yygotominor.yy454->pList = yymsp[-2].minor.yy266;
  sqlite3ExprSpan(yygotominor.yy454, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
}
#line 2811 "parse.c"
        break;
      case 234:
#line 754 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266, yymsp[-2].minor.yy454, 0);
  yygotominor.yy266 = sqlite3ExprListAppend(yygotominor.yy266, yymsp[0].minor.yy454, 0);
}
#line 2819 "parse.c"
        break;
      case 235:
#line 758 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy454, 0);
  yygotominor.yy266 = sqlite3ExprListAppend(yygotominor.yy266, yymsp[0].minor.yy454, 0);
}
#line 2827 "parse.c"
        break;
      case 244:
#line 783 "parse.y"
{
  if( yymsp[-9].minor.yy60!=OE_None ) yymsp[-9].minor.yy60 = yymsp[0].minor.yy60;
  if( yymsp[-9].minor.yy60==OE_Default) yymsp[-9].minor.yy60 = OE_Abort;
  sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy406, &yymsp[-6].minor.yy406, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy406,0),yymsp[-2].minor.yy266,yymsp[-9].minor.yy60, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0);
}
#line 2836 "parse.c"
        break;
      case 245:
      case 292:
#line 790 "parse.y"
{yygotominor.yy60 = OE_Abort;}
#line 2842 "parse.c"
        break;
      case 246:
#line 791 "parse.y"
{yygotominor.yy60 = OE_None;}
#line 2847 "parse.c"
        break;
      case 249:
#line 801 "parse.y"
{
  Expr *p = 0;
  if( yymsp[-1].minor.yy406.n>0 ){
    p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy406.z, yymsp[-1].minor.yy406.n);
  }
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266, p, &yymsp[-2].minor.yy406);
}
#line 2859 "parse.c"
        break;
      case 250:
#line 809 "parse.y"
{
  Expr *p = 0;
  if( yymsp[-1].minor.yy406.n>0 ){
    p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy406.z, yymsp[-1].minor.yy406.n);
  }
  yygotominor.yy266 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy406);
}
#line 2871 "parse.c"
        break;
      case 252:
#line 822 "parse.y"
{sqlite3DropIndex(pParse, yymsp[0].minor.yy427);}
#line 2876 "parse.c"
        break;
      case 253:
      case 254:
#line 826 "parse.y"
{sqlite3Vacuum(pParse,0);}
#line 2882 "parse.c"
        break;
      case 255:
      case 257:
#line 832 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy406,0);}
#line 2888 "parse.c"
        break;
      case 256:
#line 833 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy0,0);}
#line 2893 "parse.c"
        break;
      case 258:
#line 835 "parse.y"
{
  sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy406,1);
}
#line 2900 "parse.c"
        break;
      case 259:
#line 838 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy406,&yymsp[-3].minor.yy406,&yymsp[-1].minor.yy406,0);}
#line 2905 "parse.c"
        break;
      case 260:
#line 839 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406,0,0);}
#line 2910 "parse.c"
        break;
      case 267:
#line 852 "parse.y"
{
  Token all;
  all.z = yymsp[-3].minor.yy406.z;
  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy406.z) + yymsp[0].minor.yy0.n;
  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy455, &all);
}
#line 2920 "parse.c"
        break;
      case 268:
#line 861 "parse.y"
{
  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy406, &yymsp[-6].minor.yy406, yymsp[-5].minor.yy60, yymsp[-4].minor.yy62.a, yymsp[-4].minor.yy62.b, yymsp[-2].minor.yy427, yymsp[-1].minor.yy60, yymsp[0].minor.yy454, yymsp[-9].minor.yy60);
  yygotominor.yy406 = (yymsp[-6].minor.yy406.n==0?yymsp[-7].minor.yy406:yymsp[-6].minor.yy406);
}
#line 2928 "parse.c"
        break;
      case 269:
      case 272:
#line 867 "parse.y"
{ yygotominor.yy60 = TK_BEFORE; }
#line 2934 "parse.c"
        break;
      case 270:
#line 868 "parse.y"
{ yygotominor.yy60 = TK_AFTER;  }
#line 2939 "parse.c"
        break;
      case 271:
#line 869 "parse.y"
{ yygotominor.yy60 = TK_INSTEAD;}
#line 2944 "parse.c"
        break;
      case 273:
      case 274:
      case 275:
#line 874 "parse.y"
{yygotominor.yy62.a = yymsp[0].major; yygotominor.yy62.b = 0;}
#line 2951 "parse.c"
        break;
      case 276:
#line 877 "parse.y"
{yygotominor.yy62.a = TK_UPDATE; yygotominor.yy62.b = yymsp[0].minor.yy272;}
#line 2956 "parse.c"
        break;
      case 277:
      case 278:
#line 880 "parse.y"
{ yygotominor.yy60 = TK_ROW; }
#line 2962 "parse.c"
        break;
      case 279:
#line 882 "parse.y"
{ yygotominor.yy60 = TK_STATEMENT; }
#line 2967 "parse.c"
        break;
      case 280:
#line 885 "parse.y"
{ yygotominor.yy454 = 0; }
#line 2972 "parse.c"
        break;
      case 281:
#line 886 "parse.y"
{ yygotominor.yy454 = yymsp[0].minor.yy454; }
#line 2977 "parse.c"
        break;
      case 282:
#line 890 "parse.y"
{
  yymsp[-2].minor.yy455->pNext = yymsp[0].minor.yy455;
  yygotominor.yy455 = yymsp[-2].minor.yy455;
}
#line 2985 "parse.c"
        break;
      case 283:
#line 894 "parse.y"
{ yygotominor.yy455 = 0; }
#line 2990 "parse.c"
        break;
      case 284:
#line 900 "parse.y"
{ yygotominor.yy455 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy406, yymsp[-1].minor.yy266, yymsp[0].minor.yy454, yymsp[-4].minor.yy60); }
#line 2995 "parse.c"
        break;
      case 285:
#line 905 "parse.y"
{yygotominor.yy455 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy406, yymsp[-4].minor.yy272, yymsp[-1].minor.yy266, 0, yymsp[-7].minor.yy60);}
#line 3000 "parse.c"
        break;
      case 286:
#line 908 "parse.y"
{yygotominor.yy455 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy406, yymsp[-1].minor.yy272, 0, yymsp[0].minor.yy331, yymsp[-4].minor.yy60);}
#line 3005 "parse.c"
        break;
      case 287:
#line 912 "parse.y"
{yygotominor.yy455 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy406, yymsp[0].minor.yy454);}
#line 3010 "parse.c"
        break;
      case 288:
#line 915 "parse.y"
{yygotominor.yy455 = sqlite3TriggerSelectStep(yymsp[0].minor.yy331); }
#line 3015 "parse.c"
        break;
      case 289:
#line 918 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_RAISE, 0, 0, 0); 
  yygotominor.yy454->iColumn = OE_Ignore;
  sqlite3ExprSpan(yygotominor.yy454, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
}
#line 3024 "parse.c"
        break;
      case 290:
#line 923 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy406); 
  yygotominor.yy454->iColumn = yymsp[-3].minor.yy60;
  sqlite3ExprSpan(yygotominor.yy454, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
}
#line 3033 "parse.c"
        break;
      case 291:
#line 931 "parse.y"
{yygotominor.yy60 = OE_Rollback;}
#line 3038 "parse.c"
        break;
      case 293:
#line 933 "parse.y"
{yygotominor.yy60 = OE_Fail;}
#line 3043 "parse.c"
        break;
      case 294:
#line 938 "parse.y"
{
  sqlite3DropTrigger(pParse,yymsp[0].minor.yy427);
}
#line 3050 "parse.c"
        break;
      case 295:
#line 944 "parse.y"
{
  sqlite3Attach(pParse, &yymsp[-3].minor.yy406, &yymsp[-1].minor.yy406, yymsp[0].minor.yy40.type, &yymsp[0].minor.yy40.key);
}
#line 3057 "parse.c"
        break;
      case 296:
#line 948 "parse.y"
{ yygotominor.yy40.type = 0; }
#line 3062 "parse.c"
        break;
      case 297:
#line 949 "parse.y"
{ yygotominor.yy40.type=1; yygotominor.yy40.key = yymsp[0].minor.yy406; }
#line 3067 "parse.c"
        break;
      case 298:
#line 950 "parse.y"
{ yygotominor.yy40.type=2; yygotominor.yy40.key = yymsp[0].minor.yy0; }
#line 3072 "parse.c"
        break;
      case 301:
#line 956 "parse.y"
{
  sqlite3Detach(pParse, &yymsp[0].minor.yy406);
}
#line 3079 "parse.c"
        break;
      case 302:
#line 962 "parse.y"
{sqlite3Reindex(pParse, 0, 0);}
#line 3084 "parse.c"
        break;
      case 303:
#line 963 "parse.y"
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy406, &yymsp[0].minor.yy406);}
#line 3089 "parse.c"
        break;
      case 304:
#line 968 "parse.y"
{
  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy427,&yymsp[0].minor.yy406);
}
#line 3096 "parse.c"
        break;
  };
  yygoto = yyRuleInfo[yyruleno].lhs;
  yysize = yyRuleInfo[yyruleno].nrhs;
  yypParser->yyidx -= yysize;
  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
  if( yyact < YYNSTATE ){
#ifdef NDEBUG
    /* If we are not debugging and the reduce action popped at least
    ** one element off the stack, then we can push the new element back
    ** onto the stack here, and skip the stack overflow test in yy_shift().
    ** That gives a significant speed improvement. */
    if( yysize ){
      yypParser->yyidx++;
      yymsp -= yysize-1;
      yymsp->stateno = yyact;
      yymsp->major = yygoto;
      yymsp->minor = yygotominor;
    }else
#endif
    {
      yy_shift(yypParser,yyact,yygoto,&yygotominor);
    }
  }else if( yyact == YYNSTATE + YYNRULE + 1 ){
    yy_accept(yypParser);
  }
}

/*
** The following code executes when the parse fails
*/
static void yy_parse_failed(
  yyParser *yypParser           /* The parser */
){
  sqlite3ParserARG_FETCH;
#ifndef NDEBUG
  if( yyTraceFILE ){
    fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
  }
#endif
  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
  /* Here code is inserted which will be executed whenever the
  ** parser fails */
  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}

/*
** The following code executes when a syntax error first occurs.
*/
static void yy_syntax_error(
  yyParser *yypParser,           /* The parser */
  int yymajor,                   /* The major type of the error token */
  YYMINORTYPE yyminor            /* The minor type of the error token */
){
  sqlite3ParserARG_FETCH;
#define TOKEN (yyminor.yy0)
#line 23 "parse.y"

  if( pParse->zErrMsg==0 ){
    if( TOKEN.z[0] ){
      sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
    }else{
      sqlite3ErrorMsg(pParse, "incomplete SQL statement");
    }
  }
#line 3163 "parse.c"
  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}

/*
** The following is executed when the parser accepts
*/
static void yy_accept(
  yyParser *yypParser           /* The parser */
){
  sqlite3ParserARG_FETCH;
#ifndef NDEBUG
  if( yyTraceFILE ){
    fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
  }
#endif
  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
  /* Here code is inserted which will be executed whenever the
  ** parser accepts */
  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}

/* The main parser program.
** The first argument is a pointer to a structure obtained from
** "sqlite3ParserAlloc" which describes the current state of the parser.
** The second argument is the major token number.  The third is
** the minor token.  The fourth optional argument is whatever the
** user wants (and specified in the grammar) and is available for
** use by the action routines.
**
** Inputs:
** <ul>
** <li> A pointer to the parser (an opaque structure.)
** <li> The major token number.
** <li> The minor token number.
** <li> An option argument of a grammar-specified type.
** </ul>
**
** Outputs:
** None.
*/
void sqlite3Parser(
  void *yyp,                   /* The parser */
  int yymajor,                 /* The major token code number */
  sqlite3ParserTOKENTYPE yyminor       /* The value for the token */
  sqlite3ParserARG_PDECL               /* Optional %extra_argument parameter */
){
  YYMINORTYPE yyminorunion;
  int yyact;            /* The parser action. */
  int yyendofinput;     /* True if we are at the end of input */
  int yyerrorhit = 0;   /* True if yymajor has invoked an error */
  yyParser *yypParser;  /* The parser */

  /* (re)initialize the parser, if necessary */
  yypParser = (yyParser*)yyp;
  if( yypParser->yyidx<0 ){
    if( yymajor==0 ) return;
    yypParser->yyidx = 0;
    yypParser->yyerrcnt = -1;
    yypParser->yystack[0].stateno = 0;
    yypParser->yystack[0].major = 0;
  }
  yyminorunion.yy0 = yyminor;
  yyendofinput = (yymajor==0);
  sqlite3ParserARG_STORE;

#ifndef NDEBUG
  if( yyTraceFILE ){
    fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
  }
#endif

  do{
    yyact = yy_find_shift_action(yypParser,yymajor);
    if( yyact<YYNSTATE ){
      yy_shift(yypParser,yyact,yymajor,&yyminorunion);
      yypParser->yyerrcnt--;
      if( yyendofinput && yypParser->yyidx>=0 ){
        yymajor = 0;
      }else{
        yymajor = YYNOCODE;
      }
    }else if( yyact < YYNSTATE + YYNRULE ){
      yy_reduce(yypParser,yyact-YYNSTATE);
    }else if( yyact == YY_ERROR_ACTION ){
      int yymx;
#ifndef NDEBUG
      if( yyTraceFILE ){
        fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
      }
#endif
#ifdef YYERRORSYMBOL
      /* A syntax error has occurred.
      ** The response to an error depends upon whether or not the
      ** grammar defines an error token "ERROR".  
      **
      ** This is what we do if the grammar does define ERROR:
      **
      **  * Call the %syntax_error function.
      **
      **  * Begin popping the stack until we enter a state where
      **    it is legal to shift the error symbol, then shift
      **    the error symbol.
      **
      **  * Set the error count to three.
      **
      **  * Begin accepting and shifting new tokens.  No new error
      **    processing will occur until three tokens have been
      **    shifted successfully.
      **
      */
      if( yypParser->yyerrcnt<0 ){
        yy_syntax_error(yypParser,yymajor,yyminorunion);
      }
      yymx = yypParser->yystack[yypParser->yyidx].major;
      if( yymx==YYERRORSYMBOL || yyerrorhit ){
#ifndef NDEBUG
        if( yyTraceFILE ){
          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
             yyTracePrompt,yyTokenName[yymajor]);
        }
#endif
        yy_destructor(yymajor,&yyminorunion);
        yymajor = YYNOCODE;
      }else{
         while(
          yypParser->yyidx >= 0 &&
          yymx != YYERRORSYMBOL &&
          (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE
        ){
          yy_pop_parser_stack(yypParser);
        }
        if( yypParser->yyidx < 0 || yymajor==0 ){
          yy_destructor(yymajor,&yyminorunion);
          yy_parse_failed(yypParser);
          yymajor = YYNOCODE;
        }else if( yymx!=YYERRORSYMBOL ){
          YYMINORTYPE u2;
          u2.YYERRSYMDT = 0;
          yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
        }
      }
      yypParser->yyerrcnt = 3;
      yyerrorhit = 1;
#else  /* YYERRORSYMBOL is not defined */
      /* This is what we do if the grammar does not define ERROR:
      **
      **  * Report an error message, and throw away the input token.
      **
      **  * If the input token is $, then fail the parse.
      **
      ** As before, subsequent error messages are suppressed until
      ** three input tokens have been successfully shifted.
      */
      if( yypParser->yyerrcnt<=0 ){
        yy_syntax_error(yypParser,yymajor,yyminorunion);
      }
      yypParser->yyerrcnt = 3;
      yy_destructor(yymajor,&yyminorunion);
      if( yyendofinput ){
        yy_parse_failed(yypParser);
      }
      yymajor = YYNOCODE;
#endif
    }else{
      yy_accept(yypParser);
      yymajor = YYNOCODE;
    }
  }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
  return;
}
Added SQLite.Interop/src/parse.h.
























































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#define TK_END_OF_FILE                     1
#define TK_ILLEGAL                         2
#define TK_SPACE                           3
#define TK_UNCLOSED_STRING                 4
#define TK_COMMENT                         5
#define TK_FUNCTION                        6
#define TK_COLUMN                          7
#define TK_AGG_FUNCTION                    8
#define TK_SEMI                            9
#define TK_EXPLAIN                        10
#define TK_BEGIN                          11
#define TK_TRANSACTION                    12
#define TK_DEFERRED                       13
#define TK_IMMEDIATE                      14
#define TK_EXCLUSIVE                      15
#define TK_COMMIT                         16
#define TK_END                            17
#define TK_ROLLBACK                       18
#define TK_CREATE                         19
#define TK_TABLE                          20
#define TK_TEMP                           21
#define TK_LP                             22
#define TK_RP                             23
#define TK_AS                             24
#define TK_COMMA                          25
#define TK_ID                             26
#define TK_ABORT                          27
#define TK_AFTER                          28
#define TK_ASC                            29
#define TK_ATTACH                         30
#define TK_BEFORE                         31
#define TK_CASCADE                        32
#define TK_CONFLICT                       33
#define TK_DATABASE                       34
#define TK_DESC                           35
#define TK_DETACH                         36
#define TK_EACH                           37
#define TK_FAIL                           38
#define TK_FOR                            39
#define TK_GLOB                           40
#define TK_IGNORE                         41
#define TK_INITIALLY                      42
#define TK_INSTEAD                        43
#define TK_LIKE                           44
#define TK_MATCH                          45
#define TK_KEY                            46
#define TK_OF                             47
#define TK_OFFSET                         48
#define TK_PRAGMA                         49
#define TK_RAISE                          50
#define TK_REPLACE                        51
#define TK_RESTRICT                       52
#define TK_ROW                            53
#define TK_STATEMENT                      54
#define TK_TRIGGER                        55
#define TK_VACUUM                         56
#define TK_VIEW                           57
#define TK_REINDEX                        58
#define TK_RENAME                         59
#define TK_CDATE                          60
#define TK_CTIME                          61
#define TK_CTIMESTAMP                     62
#define TK_ALTER                          63
#define TK_OR                             64
#define TK_AND                            65
#define TK_NOT                            66
#define TK_IS                             67
#define TK_BETWEEN                        68
#define TK_IN                             69
#define TK_ISNULL                         70
#define TK_NOTNULL                        71
#define TK_NE                             72
#define TK_EQ                             73
#define TK_GT                             74
#define TK_LE                             75
#define TK_LT                             76
#define TK_GE                             77
#define TK_ESCAPE                         78
#define TK_BITAND                         79
#define TK_BITOR                          80
#define TK_LSHIFT                         81
#define TK_RSHIFT                         82
#define TK_PLUS                           83
#define TK_MINUS                          84
#define TK_STAR                           85
#define TK_SLASH                          86
#define TK_REM                            87
#define TK_CONCAT                         88
#define TK_UMINUS                         89
#define TK_UPLUS                          90
#define TK_BITNOT                         91
#define TK_STRING                         92
#define TK_JOIN_KW                        93
#define TK_CONSTRAINT                     94
#define TK_DEFAULT                        95
#define TK_NULL                           96
#define TK_PRIMARY                        97
#define TK_UNIQUE                         98
#define TK_CHECK                          99
#define TK_REFERENCES                     100
#define TK_COLLATE                        101
#define TK_AUTOINCR                       102
#define TK_ON                             103
#define TK_DELETE                         104
#define TK_UPDATE                         105
#define TK_INSERT                         106
#define TK_SET                            107
#define TK_DEFERRABLE                     108
#define TK_FOREIGN                        109
#define TK_DROP                           110
#define TK_UNION                          111
#define TK_ALL                            112
#define TK_INTERSECT                      113
#define TK_EXCEPT                         114
#define TK_SELECT                         115
#define TK_DISTINCT                       116
#define TK_DOT                            117
#define TK_FROM                           118
#define TK_JOIN                           119
#define TK_USING                          120
#define TK_ORDER                          121
#define TK_BY                             122
#define TK_GROUP                          123
#define TK_HAVING                         124
#define TK_LIMIT                          125
#define TK_WHERE                          126
#define TK_INTO                           127
#define TK_VALUES                         128
#define TK_INTEGER                        129
#define TK_FLOAT                          130
#define TK_BLOB                           131
#define TK_REGISTER                       132
#define TK_VARIABLE                       133
#define TK_EXISTS                         134
#define TK_CASE                           135
#define TK_WHEN                           136
#define TK_THEN                           137
#define TK_ELSE                           138
#define TK_INDEX                          139
#define TK_TO                             140
Added SQLite.Interop/src/pragma.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
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
/*
** 2003 April 6
**
** 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 file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.1 2005/03/01 16:04:34 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#ifndef SQLITE_OMIT_PRAGMA

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
#endif

/*
** Interpret the given string as a safety level.  Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
** unrecognized string argument.
**
** Note that the values returned are one less that the values that
** should be passed into sqlite3BtreeSetSafetyLevel().  The is done
** to support legacy SQL code.  The safety level used to be boolean
** and older scripts may have used numbers 0 for OFF and 1 for ON.
*/
static int getSafetyLevel(const u8 *z){
                             /* 123456789 123456789 */
  static const char zText[] = "onoffalseyestruefull";
  static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
  static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
  static const u8 iValue[] =  {1, 0, 0, 0, 1, 1, 2};
  int i, n;
  if( isdigit(*z) ){
    return atoi(z);
  }
  n = strlen(z);
  for(i=0; i<sizeof(iLength); i++){
    if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
      return iValue[i];
    }
  }
  return 1;
}

/*
** Interpret the given string as a boolean value.
*/
static int getBoolean(const u8 *z){
  return getSafetyLevel(z)&1;
}

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Interpret the given string as a temp db location. Return 1 for file
** backed temporary databases, 2 for the Red-Black tree in memory database
** and 0 to use the compile-time default.
*/
static int getTempStore(const char *z){
  if( z[0]>='0' && z[0]<='2' ){
    return z[0] - '0';
  }else if( sqlite3StrICmp(z, "file")==0 ){
    return 1;
  }else if( sqlite3StrICmp(z, "memory")==0 ){
    return 2;
  }else{
    return 0;
  }
}

/*
** Invalidate temp storage, either when the temp storage is changed
** from default, or when 'file' and the temp_store_directory has changed
*/
static int invalidateTempStorage(Parse *pParse){
  sqlite3 *db = pParse->db;
  if( db->aDb[1].pBt!=0 ){
    if( db->flags & SQLITE_InTrans ){
      sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
        "from within a transaction");
      return SQLITE_ERROR;
    }
    sqlite3BtreeClose(db->aDb[1].pBt);
    db->aDb[1].pBt = 0;
    sqlite3ResetInternalSchema(db, 0);
  }
  return SQLITE_OK;
}

/*
** If the TEMP database is open, close it and mark the database schema
** as needing reloading.  This must be done when using the TEMP_STORE
** or DEFAULT_TEMP_STORE pragmas.
*/
static int changeTempStorage(Parse *pParse, const char *zStorageType){
  int ts = getTempStore(zStorageType);
  sqlite3 *db = pParse->db;
  if( db->temp_store==ts ) return SQLITE_OK;
  if( invalidateTempStorage( pParse ) != SQLITE_OK ){
    return SQLITE_ERROR;
  }
  db->temp_store = ts;
  return SQLITE_OK;
}
#endif

/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
  Vdbe *v = sqlite3GetVdbe(pParse);
  sqlite3VdbeAddOp(v, OP_Integer, value, 0);
  if( pParse->explain==0 ){
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
  }
  sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
}

/*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
** Also, implement the pragma.
*/
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
  static const struct sPragmaType {
    const char *zName;  /* Name of the pragma */
    int mask;           /* Mask for the db->flags value */
  } aPragma[] = {
    { "vdbe_trace",               SQLITE_VdbeTrace     },
    { "sql_trace",                SQLITE_SqlTrace      },
    { "vdbe_listing",             SQLITE_VdbeListing   },
    { "full_column_names",        SQLITE_FullColNames  },
    { "short_column_names",       SQLITE_ShortColNames },
    { "count_changes",            SQLITE_CountRows     },
    { "empty_result_callbacks",   SQLITE_NullCallback  },
    /* The following is VERY experimental */
    { "writable_schema",          SQLITE_WriteSchema   },
    { "omit_readlock",            SQLITE_NoReadlock    },
  };
  int i;
  const struct sPragmaType *p;
  for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
    if( sqlite3StrICmp(zLeft, p->zName)==0 ){
      sqlite3 *db = pParse->db;
      Vdbe *v;
      v = sqlite3GetVdbe(pParse);
      if( v ){
        if( zRight==0 ){
          returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
        }else{
          if( getBoolean(zRight) ){
            db->flags |= p->mask;
          }else{
            db->flags &= ~p->mask;
          }
        }
        /* If one of these pragmas is executed, any prepared statements
        ** need to be recompiled.
        */
        sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
      }
      return 1;
    }
  }
  return 0;
}

/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA [database.]id [= value]
**
** The identifier might also be a string.  The value is a string, and
** identifier, or a number.  If minusFlag is true, then the value is
** a number that was preceded by a minus sign.
**
** If the left side is "database.id" then pId1 is the database name
** and pId2 is the id.  If the left side is just "id" then pId1 is the
** id and pId2 is any empty string.
*/
void sqlite3Pragma(
  Parse *pParse, 
  Token *pId1,        /* First part of [database.]id field */
  Token *pId2,        /* Second part of [database.]id field, or NULL */
  Token *pValue,      /* Token for <value>, or NULL */
  int minusFlag       /* True if a '-' sign preceded <value> */
){
  char *zLeft = 0;       /* Nul-terminated UTF-8 string <id> */
  char *zRight = 0;      /* Nul-terminated UTF-8 string <value>, or NULL */
  const char *zDb = 0;   /* The database name */
  Token *pId;            /* Pointer to <id> token */
  int iDb;               /* Database index for <database> */
  sqlite3 *db = pParse->db;
  Db *pDb;
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;

  /* Interpret the [database.] part of the pragma statement. iDb is the
  ** index of the database this pragma is being applied to in db.aDb[]. */
  iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
  if( iDb<0 ) return;
  pDb = &db->aDb[iDb];

  zLeft = sqlite3NameFromToken(pId);
  if( !zLeft ) return;
  if( minusFlag ){
    zRight = sqlite3MPrintf("-%T", pValue);
  }else{
    zRight = sqlite3NameFromToken(pValue);
  }

  zDb = ((iDb>0)?pDb->zName:0);
  if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
    goto pragma_out;
  }
 
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
  /*
  **  PRAGMA [database.]default_cache_size
  **  PRAGMA [database.]default_cache_size=N
  **
  ** The first form reports the current persistent setting for the
  ** page cache size.  The value returned is the maximum number of
  ** pages in the page cache.  The second form sets both the current
  ** page cache size value and the persistent page cache size value
  ** stored in the database file.
  **
  ** The default cache size is stored in meta-value 2 of page 1 of the
  ** database file.  The cache size is actually the absolute value of
  ** this memory location.  The sign of meta-value 2 determines the
  ** synchronous setting.  A negative value means synchronous is off
  ** and a positive value means synchronous is on.
  */
  if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
    static const VdbeOpList getCacheSize[] = {
      { OP_ReadCookie,  0, 2,        0},  /* 0 */
      { OP_AbsValue,    0, 0,        0},
      { OP_Dup,         0, 0,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 6,        0},
      { OP_Integer,     0, 0,        0},  /* 5 */
      { OP_Callback,    1, 0,        0},
    };
    int addr;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      sqlite3BeginWriteOperation(pParse, 0, iDb);
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
      addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
      sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
      sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
      pDb->cache_size = size;
      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
    }
  }else

  /*
  **  PRAGMA [database.]page_size
  **  PRAGMA [database.]page_size=N
  **
  ** The first form reports the current setting for the
  ** database page size in bytes.  The second form sets the
  ** database page size value.  The value can only be set if
  ** the database has not yet been created.
  */
  if( sqlite3StrICmp(zLeft,"page_size")==0 ){
    Btree *pBt = pDb->pBt;
    if( !zRight ){
      int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;
      returnSingleInt(pParse, "page_size", size);
    }else{
      sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1);
    }
  }else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

  /*
  **  PRAGMA [database.]auto_vacuum
  **  PRAGMA [database.]auto_vacuum=N
  **
  ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.
  */
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
    Btree *pBt = pDb->pBt;
    if( !zRight ){
      int auto_vacuum = 
          pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM;
      returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
    }else{
      sqlite3BtreeSetAutoVacuum(pBt, getBoolean(zRight));
    }
  }else
#endif

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
  /*
  **  PRAGMA [database.]cache_size
  **  PRAGMA [database.]cache_size=N
  **
  ** The first form reports the current local setting for the
  ** page cache size.  The local setting can be different from
  ** the persistent cache size value that is stored in the database
  ** file itself.  The value returned is the maximum number of
  ** pages in the page cache.  The second form sets the local
  ** page cache size value.  It does not change the persistent
  ** cache size stored on the disk so the cache size will revert
  ** to its default value when the database is closed and reopened.
  ** N should be a positive integer.
  */
  if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      returnSingleInt(pParse, "cache_size", pDb->cache_size);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      pDb->cache_size = size;
      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
    }
  }else

  /*
  **   PRAGMA temp_store
  **   PRAGMA temp_store = "default"|"memory"|"file"
  **
  ** Return or set the local value of the temp_store flag.  Changing
  ** the local value does not make changes to the disk file and the default
  ** value will be restored the next time the database is opened.
  **
  ** Note that it is possible for the library compile-time options to
  ** override this setting
  */
  if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
    if( !zRight ){
      returnSingleInt(pParse, "temp_store", db->temp_store);
    }else{
      changeTempStorage(pParse, zRight);
    }
  }else

  /*
  **   PRAGMA temp_store_directory
  **   PRAGMA temp_store_directory = ""|"directory_name"
  **
  ** Return or set the local value of the temp_store_directory flag.  Changing
  ** the value sets a specific directory to be used for temporary files.
  ** Setting to a null string reverts to the default temporary directory search.
  ** If temporary directory is changed, then invalidateTempStorage.
  **
  */
  if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){
    if( !zRight ){
      if( sqlite3_temp_directory ){
        sqlite3VdbeSetNumCols(v, 1);
        sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC);
        sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
        sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
      }
    }else{
      if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){
        sqlite3ErrorMsg(pParse, "not a writable directory");
        goto pragma_out;
      }
      if( TEMP_STORE==0
       || (TEMP_STORE==1 && db->temp_store<=1)
       || (TEMP_STORE==2 && db->temp_store==1)
      ){
        invalidateTempStorage(pParse);
      }
      sqliteFree(sqlite3_temp_directory);
      if( zRight[0] ){
        sqlite3_temp_directory = zRight;
        zRight = 0;
      }else{
        sqlite3_temp_directory = 0;
      }
    }
  }else

  /*
  **   PRAGMA [database.]synchronous
  **   PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
  **
  ** Return or set the local value of the synchronous flag.  Changing
  ** the local value does not make changes to the disk file and the
  ** default value will be restored the next time the database is
  ** opened.
  */
  if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
    }else{
      if( !db->autoCommit ){
        sqlite3ErrorMsg(pParse, 
            "Safety level may not be changed inside a transaction");
      }else{
        pDb->safety_level = getSafetyLevel(zRight)+1;
        sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
      }
    }
  }else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

  if( flagPragma(pParse, zLeft, zRight) ){
    /* The flagPragma() subroutine also generates any necessary code
    ** there is nothing more to do here */
  }else

#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
  /*
  **   PRAGMA table_info(<table>)
  **
  ** Return a single row for each column of the named table. The columns of
  ** the returned data set are:
  **
  ** cid:        Column id (numbered from left to right, starting at 0)
  ** name:       Column name
  ** type:       Column declaration type.
  ** notnull:    True if 'NOT NULL' is part of column declaration
  ** dflt_value: The default value for the column, if any.
  */
  if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
    Table *pTab;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, zDb);
    if( pTab ){
      int i;
      sqlite3VdbeSetNumCols(v, 6);
      sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
      sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
      sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
      sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
      sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
      sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
      sqlite3ViewGetColumnNames(pParse, pTab);
      for(i=0; i<pTab->nCol; i++){
        sqlite3VdbeAddOp(v, OP_Integer, i, 0);
        sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zName, 0);
        sqlite3VdbeOp3(v, OP_String8, 0, 0,
           pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
        sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
        sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
        sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
    Index *pIdx;
    Table *pTab;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pIdx = sqlite3FindIndex(db, zRight, zDb);
    if( pIdx ){
      int i;
      pTab = pIdx->pTable;
      sqlite3VdbeSetNumCols(v, 3);
      sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
      sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
      sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
      for(i=0; i<pIdx->nColumn; i++){
        int cnum = pIdx->aiColumn[i];
        sqlite3VdbeAddOp(v, OP_Integer, i, 0);
        sqlite3VdbeAddOp(v, OP_Integer, cnum, 0);
        assert( pTab->nCol>cnum );
        sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[cnum].zName, 0);
        sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
    Index *pIdx;
    Table *pTab;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, zDb);
    if( pTab ){
      v = sqlite3GetVdbe(pParse);
      pIdx = pTab->pIndex;
      if( pIdx ){
        int i = 0; 
        sqlite3VdbeSetNumCols(v, 3);
        sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
        sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
        sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
        while(pIdx){
          sqlite3VdbeAddOp(v, OP_Integer, i, 0);
          sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
          sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
          sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
          ++i;
          pIdx = pIdx->pNext;
        }
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "database_list")==0 ){
    int i;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeSetNumCols(v, 3);
    sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
    sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
    sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
    for(i=0; i<db->nDb; i++){
      if( db->aDb[i].pBt==0 ) continue;
      assert( db->aDb[i].zName!=0 );
      sqlite3VdbeAddOp(v, OP_Integer, i, 0);
      sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
           sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
      sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
    }
  }else

  if( sqlite3StrICmp(zLeft, "collation_list")==0 ){
    int i = 0;
    HashElem *p;
    sqlite3VdbeSetNumCols(v, 2);
    sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
    sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
    for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
      CollSeq *pColl = (CollSeq *)sqliteHashData(p);
      sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
      sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0);
      sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
    }
  }else
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */

#ifndef SQLITE_OMIT_FOREIGN_KEY
  if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
    FKey *pFK;
    Table *pTab;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, zDb);
    if( pTab ){
      v = sqlite3GetVdbe(pParse);
      pFK = pTab->pFKey;
      if( pFK ){
        int i = 0; 
        sqlite3VdbeSetNumCols(v, 5);
        sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
        sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
        sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
        sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
        sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
        while(pFK){
          int j;
          for(j=0; j<pFK->nCol; j++){
            sqlite3VdbeAddOp(v, OP_Integer, i, 0);
            sqlite3VdbeAddOp(v, OP_Integer, j, 0);
            sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0);
            sqlite3VdbeOp3(v, OP_String8, 0, 0,
                             pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
            sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->aCol[j].zCol, 0);
            sqlite3VdbeAddOp(v, OP_Callback, 5, 0);
          }
          ++i;
          pFK = pFK->pNextFrom;
        }
      }
    }
  }else
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */

#ifndef NDEBUG
  if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
    extern void sqlite3ParserTrace(FILE*, char *);
    if( getBoolean(zRight) ){
      sqlite3ParserTrace(stdout, "parser: ");
    }else{
      sqlite3ParserTrace(0, 0);
    }
  }else
#endif

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
  if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
    int i, j, addr;

    /* Code that initializes the integrity check program.  Set the
    ** error count 0
    */
    static const VdbeOpList initCode[] = {
      { OP_Integer,     0, 0,        0},
      { OP_MemStore,    0, 1,        0},
    };

    /* Code that appears at the end of the integrity check.  If no error
    ** messages have been generated, output OK.  Otherwise output the
    ** error message
    */
    static const VdbeOpList endCode[] = {
      { OP_MemLoad,     0, 0,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 0,        0},    /* 2 */
      { OP_String8,     0, 0,        "ok"},
      { OP_Callback,    1, 0,        0},
    };

    /* Initialize the VDBE program */
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
    sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);

    /* Do an integrity check on each database file */
    for(i=0; i<db->nDb; i++){
      HashElem *x;
      int cnt = 0;

      sqlite3CodeVerifySchema(pParse, i);

      /* Do an integrity check of the B-Tree
      */
      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
        cnt++;
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
          sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
          cnt++;
        }
      }
      assert( cnt>0 );
      sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
         P3_DYNAMIC);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);

      /* Make sure all the indices are constructed correctly.
      */
      sqlite3CodeVerifySchema(pParse, i);
      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
        sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
        sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);
        loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
        sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          int jmp2;
          static const VdbeOpList idxErr[] = {
            { OP_MemIncr,     0,  0,  0},
            { OP_String8,     0,  0,  "rowid "},
            { OP_Recno,       1,  0,  0},
            { OP_String8,     0,  0,  " missing from index "},
            { OP_String8,     0,  0,  0},    /* 4 */
            { OP_Concat,      2,  0,  0},
            { OP_Callback,    1,  0,  0},
          };
          sqlite3GenerateIndexKey(v, pIdx, 1);
          jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
          sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
        }
        sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
        sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          static const VdbeOpList cntIdx[] = {
             { OP_Integer,      0,  0,  0},
             { OP_MemStore,     2,  1,  0},
             { OP_Rewind,       0,  0,  0},  /* 2 */
             { OP_MemIncr,      2,  0,  0},
             { OP_Next,         0,  0,  0},  /* 4 */
             { OP_MemLoad,      1,  0,  0},
             { OP_MemLoad,      2,  0,  0},
             { OP_Eq,           0,  0,  0},  /* 7 */
             { OP_MemIncr,      0,  0,  0},
             { OP_String8,      0,  0,  "wrong # of entries in index "},
             { OP_String8,      0,  0,  0},  /* 10 */
             { OP_Concat,       0,  0,  0},
             { OP_Callback,     1,  0,  0},
          };
          if( pIdx->tnum==0 ) continue;
          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
          sqlite3VdbeChangeP1(v, addr+2, j+2);
          sqlite3VdbeChangeP2(v, addr+2, addr+5);
          sqlite3VdbeChangeP1(v, addr+4, j+2);
          sqlite3VdbeChangeP2(v, addr+4, addr+3);
          sqlite3VdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
          sqlite3VdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
        }
      } 
    }
    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
    sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
  }else
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_UTF16
  /*
  **   PRAGMA encoding
  **   PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
  **
  ** In it's first form, this pragma returns the encoding of the main
  ** database. If the database is not initialized, it is initialized now.
  **
  ** The second form of this pragma is a no-op if the main database file
  ** has not already been initialized. In this case it sets the default
  ** encoding that will be used for the main database file if a new file
  ** is created. If an existing main database file is opened, then the
  ** default text encoding for the existing database is used.
  ** 
  ** In all cases new databases created using the ATTACH command are
  ** created to use the same default text encoding as the main database. If
  ** the main database has not been initialized and/or created when ATTACH
  ** is executed, this is done before the ATTACH operation.
  **
  ** In the second form this pragma sets the text encoding to be used in
  ** new database files created using this database handle. It is only
  ** useful if invoked immediately after the main database i
  */
  if( sqlite3StrICmp(zLeft, "encoding")==0 ){
    static struct EncName {
      char *zName;
      u8 enc;
    } encnames[] = {
      { "UTF-8",    SQLITE_UTF8        },
      { "UTF8",     SQLITE_UTF8        },
      { "UTF-16le", SQLITE_UTF16LE     },
      { "UTF16le",  SQLITE_UTF16LE     },
      { "UTF-16be", SQLITE_UTF16BE     },
      { "UTF16be",  SQLITE_UTF16BE     },
      { "UTF-16",   0 /* Filled in at run-time */ },
      { "UTF16",    0 /* Filled in at run-time */ },
      { 0, 0 }
    };
    struct EncName *pEnc;
    encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
    if( !zRight ){    /* "PRAGMA encoding" */
      if( sqlite3ReadSchema(pParse) ) goto pragma_out;
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
        if( pEnc->enc==pParse->db->enc ){
          sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
          break;
        }
      }
      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
    }else{                        /* "PRAGMA encoding = XXX" */
      /* Only change the value of sqlite.enc if the database handle is not
      ** initialized. If the main database exists, the new sqlite.enc value
      ** will be overwritten when the schema is next loaded. If it does not
      ** already exists, it will be created to use the new encoding value.
      */
      if( !(pParse->db->flags&SQLITE_Initialized) ){
        for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
          if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
            pParse->db->enc = pEnc->enc;
            break;
          }
        }
        if( !pEnc->zName ){
          sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
        }
      }
    }
  }else
#endif /* SQLITE_OMIT_UTF16 */

#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
  /*
  **   PRAGMA [database.]schema_version
  **   PRAGMA [database.]schema_version = <integer>
  **
  **   PRAGMA [database.]user_version
  **   PRAGMA [database.]user_version = <integer>
  **
  ** The pragma's schema_version and user_version are used to set or get
  ** the value of the schema-version and user-version, respectively. Both
  ** the schema-version and the user-version are 32-bit signed integers
  ** stored in the database header.
  **
  ** The schema-cookie is usually only manipulated internally by SQLite. It
  ** is incremented by SQLite whenever the database schema is modified (by
  ** creating or dropping a table or index). The schema version is used by
  ** SQLite each time a query is executed to ensure that the internal cache
  ** of the schema used when compiling the SQL query matches the schema of
  ** the database against which the compiled query is actually executed.
  ** Subverting this mechanism by using "PRAGMA schema_version" to modify
  ** the schema-version is potentially dangerous and may lead to program
  ** crashes or database corruption. Use with caution!
  **
  ** The user-version is not used internally by SQLite. It may be used by
  ** applications for any purpose.
  */
  if( sqlite3StrICmp(zLeft, "schema_version")==0 ||
      sqlite3StrICmp(zLeft, "user_version")==0 ){

    int iCookie;   /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */
    if( zLeft[0]=='s' || zLeft[0]=='S' ){
      iCookie = 0;
    }else{
      iCookie = 5;
    }

    if( zRight ){
      /* Write the specified cookie value */
      static const VdbeOpList setCookie[] = {
        { OP_Transaction,    0,  1,  0},    /* 0 */
        { OP_Integer,        0,  0,  0},    /* 1 */
        { OP_SetCookie,      0,  0,  0},    /* 2 */
      };
      int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));
      sqlite3VdbeChangeP1(v, addr+2, iDb);
      sqlite3VdbeChangeP2(v, addr+2, iCookie);
    }else{
      /* Read the specified cookie value */
      static const VdbeOpList readCookie[] = {
        { OP_ReadCookie,      0,  0,  0},    /* 0 */
        { OP_Callback,        1,  0,  0}
      };
      int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP2(v, addr, iCookie);
      sqlite3VdbeSetNumCols(v, 1);
    }
  }
#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
  /*
  ** Report the current state of file logs for all databases
  */
  if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
    static const char *const azLockName[] = {
      "unlocked", "shared", "reserved", "pending", "exclusive"
    };
    int i;
    Vdbe *v = sqlite3GetVdbe(pParse);
    sqlite3VdbeSetNumCols(v, 2);
    sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
    sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
    for(i=0; i<db->nDb; i++){
      Btree *pBt;
      Pager *pPager;
      if( db->aDb[i].zName==0 ) continue;
      sqlite3VdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, P3_STATIC);
      pBt = db->aDb[i].pBt;
      if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
        sqlite3VdbeOp3(v, OP_String, 0, 0, "closed", P3_STATIC);
      }else{
        int j = sqlite3pager_lockstate(pPager);
        sqlite3VdbeOp3(v, OP_String, 0, 0, 
            (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC);
      }
      sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
    }
  }else
#endif

  {}

  if( v ){
    /* Code an OP_Expire at the end of each PRAGMA program to cause
    ** the VDBE implementing the pragma to expire. Most (all?) pragmas
    ** are only valid for a single execution.
    */
    sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
  }
pragma_out:
  sqliteFree(zLeft);
  sqliteFree(zRight);
}

#endif /* SQLITE_OMIT_PRAGMA */
Added SQLite.Interop/src/printf.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
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
/*
** The "printf" code that follows dates from the 1980's.  It is in
** the public domain.  The original comments are included here for
** completeness.  They are very out-of-date but might be useful as
** an historical reference.  Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
**************************************************************************
**
** The following modules is an enhanced replacement for the "printf" subroutines
** found in the standard C library.  The following enhancements are
** supported:
**
**      +  Additional functions.  The standard set of "printf" functions
**         includes printf, fprintf, sprintf, vprintf, vfprintf, and
**         vsprintf.  This module adds the following:
**
**           *  snprintf -- Works like sprintf, but has an extra argument
**                          which is the size of the buffer written to.
**
**           *  mprintf --  Similar to sprintf.  Writes output to memory
**                          obtained from malloc.
**
**           *  xprintf --  Calls a function to dispose of output.
**
**           *  nprintf --  No output, but returns the number of characters
**                          that would have been output by printf.
**
**           *  A v- version (ex: vsnprintf) of every function is also
**              supplied.
**
**      +  A few extensions to the formatting notation are supported:
**
**           *  The "=" flag (similar to "-") causes the output to be
**              be centered in the appropriately sized field.
**
**           *  The %b field outputs an integer in binary notation.
**
**           *  The %c field now accepts a precision.  The character output
**              is repeated by the number of times the precision specifies.
**
**           *  The %' field works like %c, but takes as its character the
**              next character of the format string, instead of the next
**              argument.  For example,  printf("%.78'-")  prints 78 minus
**              signs, the same as  printf("%.78c",'-').
**
**      +  When compiled using GCC on a SPARC, this version of printf is
**         faster than the library printf for SUN OS 4.1.
**
**      +  All functions are fully reentrant.
**
*/
#include "sqliteInt.h"

/*
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
#define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
#define etFLOAT       2 /* Floating point.  %f */
#define etEXP         3 /* Exponentional notation. %e and %E */
#define etGENERIC     4 /* Floating or exponential, depending on exponent. %g */
#define etSIZE        5 /* Return number of characters processed so far. %n */
#define etSTRING      6 /* Strings. %s */
#define etDYNSTRING   7 /* Dynamically allocated strings. %z */
#define etPERCENT     8 /* Percent symbol. %% */
#define etCHARX       9 /* Characters. %c */
#define etERROR      10 /* Used to indicate no such conversion type */
/* The rest are extensions, not normally found in printf() */
#define etCHARLIT    11 /* Literal characters.  %' */
#define etSQLESCAPE  12 /* Strings with '\'' doubled.  %q */
#define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
                          NULL pointers replaced by SQL NULL.  %Q */
#define etTOKEN      14 /* a pointer to a Token structure */
#define etSRCLIST    15 /* a pointer to a SrcList */
#define etPOINTER    16 /* The %p conversion */


/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;

/*
** Each builtin conversion character (ex: the 'd' in "%d") is described
** by an instance of the following structure
*/
typedef struct et_info {   /* Information about each format field */
  char fmttype;            /* The format field code letter */
  etByte base;             /* The base for radix conversion */
  etByte flags;            /* One or more of FLAG_ constants below */
  etByte type;             /* Conversion paradigm */
  etByte charset;          /* Offset into aDigits[] of the digits string */
  etByte prefix;           /* Offset into aPrefix[] of the prefix string */
} et_info;

/*
** Allowed values for et_info.flags
*/
#define FLAG_SIGNED  1     /* True if the value to convert is signed */
#define FLAG_INTERN  2     /* True if for internal use only */
#define FLAG_STRING  4     /* Allow infinity precision */


/*
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
  {  'd', 10, 1, etRADIX,      0,  0 },
  {  's',  0, 4, etSTRING,     0,  0 },
  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
  {  'o',  8, 0, etRADIX,      0,  2 },
  {  'u', 10, 0, etRADIX,      0,  0 },
  {  'x', 16, 0, etRADIX,      16, 1 },
  {  'X', 16, 0, etRADIX,      0,  4 },
  {  'f',  0, 1, etFLOAT,      0,  0 },
  {  'e',  0, 1, etEXP,        30, 0 },
  {  'E',  0, 1, etEXP,        14, 0 },
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'G',  0, 1, etGENERIC,    14, 0 },
  {  'i', 10, 1, etRADIX,      0,  0 },
  {  'n',  0, 0, etSIZE,       0,  0 },
  {  '%',  0, 0, etPERCENT,    0,  0 },
  {  'p', 16, 0, etPOINTER,    0,  1 },
  {  'T',  0, 2, etTOKEN,      0,  0 },
  {  'S',  0, 2, etSRCLIST,    0,  0 },
};
#define etNINFO  (sizeof(fmtinfo)/sizeof(fmtinfo[0]))

/*
** If NOFLOATINGPOINT is defined, then none of the floating point
** conversions will work.
*/
#ifndef etNOFLOATINGPOINT
/*
** "*val" is a double such that 0.1 <= *val < 10.0
** Return the ascii code for the leading digit of *val, then
** multiply "*val" by 10.0 to renormalize.
**
** Example:
**     input:     *val = 3.14159
**     output:    *val = 1.4159    function return = '3'
**
** The counter *cnt is incremented each time.  After counter exceeds
** 16 (the number of significant digits in a 64-bit float) '0' is
** always returned.
*/
static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
  int digit;
  LONGDOUBLE_TYPE d;
  if( (*cnt)++ >= 16 ) return '0';
  digit = (int)*val;
  d = digit;
  digit += '0';
  *val = (*val - d)*10.0;
  return digit;
}
#endif

#define etBUFSIZE 1000  /* Size of the output buffer */

/*
** The root program.  All variations call this core.
**
** INPUTS:
**   func   This is a pointer to a function taking three arguments
**            1. A pointer to anything.  Same as the "arg" parameter.
**            2. A pointer to the list of characters to be output
**               (Note, this list is NOT null terminated.)
**            3. An integer number of characters to be output.
**               (Note: This number might be zero.)
**
**   arg    This is the pointer to anything which will be passed as the
**          first argument to "func".  Use it for whatever you like.
**
**   fmt    This is the format string, as in the usual print.
**
**   ap     This is a pointer to a list of arguments.  Same as in
**          vfprint.
**
** OUTPUTS:
**          The return value is the total number of characters sent to
**          the function "func".  Returns -1 on a error.
**
** Note that the order in which automatic variables are declared below
** seems to make a big difference in determining how fast this beast
** will run.
*/
static int vxprintf(
  void (*func)(void*,const char*,int),     /* Consumer of text */
  void *arg,                         /* First argument to the consumer */
  int useExtended,                   /* Allow extended %-conversions */
  const char *fmt,                   /* Format string */
  va_list ap                         /* arguments */
){
  int c;                     /* Next character in the format string */
  char *bufpt;               /* Pointer to the conversion buffer */
  int precision;             /* Precision of the current field */
  int length;                /* Length of the field */
  int idx;                   /* A general purpose loop counter */
  int count;                 /* Total number of characters output */
  int width;                 /* Width of the current field */
  etByte flag_leftjustify;   /* True if "-" flag is present */
  etByte flag_plussign;      /* True if "+" flag is present */
  etByte flag_blanksign;     /* True if " " flag is present */
  etByte flag_alternateform; /* True if "#" flag is present */
  etByte flag_zeropad;       /* True if field width constant starts with zero */
  etByte flag_long;          /* True if "l" flag is present */
  etByte flag_longlong;      /* True if the "ll" flag is present */
  UINT64_TYPE longvalue;     /* Value for integer types */
  LONGDOUBLE_TYPE realvalue; /* Value for real types */
  const et_info *infop;      /* Pointer to the appropriate info structure */
  char buf[etBUFSIZE];       /* Conversion buffer */
  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
  etByte errorflag = 0;      /* True if an error is encountered */
  etByte xtype;              /* Conversion paradigm */
  char *zExtra;              /* Extra memory used for etTCLESCAPE conversions */
  static const char spaces[] =
   "                                                                         ";
#define etSPACESIZE (sizeof(spaces)-1)
#ifndef etNOFLOATINGPOINT
  int  exp;                  /* exponent of real numbers */
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
  etByte flag_exp;           /* True to force display of the exponent */
  int nsd;                   /* Number of significant digits returned */
#endif

  func(arg,"",0);
  count = length = 0;
  bufpt = 0;
  for(; (c=(*fmt))!=0; ++fmt){
    if( c!='%' ){
      int amt;
      bufpt = (char *)fmt;
      amt = 1;
      while( (c=(*++fmt))!='%' && c!=0 ) amt++;
      (*func)(arg,bufpt,amt);
      count += amt;
      if( c==0 ) break;
    }
    if( (c=(*++fmt))==0 ){
      errorflag = 1;
      (*func)(arg,"%",1);
      count++;
      break;
    }
    /* Find out what flags are present */
    flag_leftjustify = flag_plussign = flag_blanksign = 
     flag_alternateform = flag_zeropad = 0;
    do{
      switch( c ){
        case '-':   flag_leftjustify = 1;     c = 0;   break;
        case '+':   flag_plussign = 1;        c = 0;   break;
        case ' ':   flag_blanksign = 1;       c = 0;   break;
        case '#':   flag_alternateform = 1;   c = 0;   break;
        case '0':   flag_zeropad = 1;         c = 0;   break;
        default:                                       break;
      }
    }while( c==0 && (c=(*++fmt))!=0 );
    /* Get the field width */
    width = 0;
    if( c=='*' ){
      width = va_arg(ap,int);
      if( width<0 ){
        flag_leftjustify = 1;
        width = -width;
      }
      c = *++fmt;
    }else{
      while( c>='0' && c<='9' ){
        width = width*10 + c - '0';
        c = *++fmt;
      }
    }
    if( width > etBUFSIZE-10 ){
      width = etBUFSIZE-10;
    }
    /* Get the precision */
    if( c=='.' ){
      precision = 0;
      c = *++fmt;
      if( c=='*' ){
        precision = va_arg(ap,int);
        if( precision<0 ) precision = -precision;
        c = *++fmt;
      }else{
        while( c>='0' && c<='9' ){
          precision = precision*10 + c - '0';
          c = *++fmt;
        }
      }
    }else{
      precision = -1;
    }
    /* Get the conversion type modifier */
    if( c=='l' ){
      flag_long = 1;
      c = *++fmt;
      if( c=='l' ){
        flag_longlong = 1;
        c = *++fmt;
      }else{
        flag_longlong = 0;
      }
    }else{
      flag_long = flag_longlong = 0;
    }
    /* Fetch the info entry for the field */
    infop = 0;
    xtype = etERROR;
    for(idx=0; idx<etNINFO; idx++){
      if( c==fmtinfo[idx].fmttype ){
        infop = &fmtinfo[idx];
        if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
          xtype = infop->type;
        }
        break;
      }
    }
    zExtra = 0;

    /* Limit the precision to prevent overflowing buf[] during conversion */
    if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
      precision = etBUFSIZE-40;
    }

    /*
    ** At this point, variables are initialized as follows:
    **
    **   flag_alternateform          TRUE if a '#' is present.
    **   flag_plussign               TRUE if a '+' is present.
    **   flag_leftjustify            TRUE if a '-' is present or if the
    **                               field width was negative.
    **   flag_zeropad                TRUE if the width began with 0.
    **   flag_long                   TRUE if the letter 'l' (ell) prefixed
    **                               the conversion character.
    **   flag_longlong               TRUE if the letter 'll' (ell ell) prefixed
    **                               the conversion character.
    **   flag_blanksign              TRUE if a ' ' is present.
    **   width                       The specified field width.  This is
    **                               always non-negative.  Zero is the default.
    **   precision                   The specified precision.  The default
    **                               is -1.
    **   xtype                       The class of the conversion.
    **   infop                       Pointer to the appropriate info struct.
    */
    switch( xtype ){
      case etPOINTER:
        flag_longlong = sizeof(char*)==sizeof(i64);
        flag_long = sizeof(char*)==sizeof(long int);
        /* Fall through into the next case */
      case etRADIX:
        if( infop->flags & FLAG_SIGNED ){
          i64 v;
          if( flag_longlong )   v = va_arg(ap,i64);
          else if( flag_long )  v = va_arg(ap,long int);
          else                  v = va_arg(ap,int);
          if( v<0 ){
            longvalue = -v;
            prefix = '-';
          }else{
            longvalue = v;
            if( flag_plussign )        prefix = '+';
            else if( flag_blanksign )  prefix = ' ';
            else                       prefix = 0;
          }
        }else{
          if( flag_longlong )   longvalue = va_arg(ap,u64);
          else if( flag_long )  longvalue = va_arg(ap,unsigned long int);
          else                  longvalue = va_arg(ap,unsigned int);
          prefix = 0;
        }
        if( longvalue==0 ) flag_alternateform = 0;
        if( flag_zeropad && precision<width-(prefix!=0) ){
          precision = width-(prefix!=0);
        }
        bufpt = &buf[etBUFSIZE-1];
        {
          register const char *cset;      /* Use registers for speed */
          register int base;
          cset = &aDigits[infop->charset];
          base = infop->base;
          do{                                           /* Convert to ascii */
            *(--bufpt) = cset[longvalue%base];
            longvalue = longvalue/base;
          }while( longvalue>0 );
        }
        length = &buf[etBUFSIZE-1]-bufpt;
        for(idx=precision-length; idx>0; idx--){
          *(--bufpt) = '0';                             /* Zero pad */
        }
        if( prefix ) *(--bufpt) = prefix;               /* Add sign */
        if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
          const char *pre;
          char x;
          pre = &aPrefix[infop->prefix];
          if( *bufpt!=pre[0] ){
            for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
          }
        }
        length = &buf[etBUFSIZE-1]-bufpt;
        break;
      case etFLOAT:
      case etEXP:
      case etGENERIC:
        realvalue = va_arg(ap,double);
#ifndef etNOFLOATINGPOINT
        if( precision<0 ) precision = 6;         /* Set default precision */
        if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
        if( realvalue<0.0 ){
          realvalue = -realvalue;
          prefix = '-';
        }else{
          if( flag_plussign )          prefix = '+';
          else if( flag_blanksign )    prefix = ' ';
          else                         prefix = 0;
        }
        if( infop->type==etGENERIC && precision>0 ) precision--;
        rounder = 0.0;
#if 0
        /* Rounding works like BSD when the constant 0.4999 is used.  Wierd! */
        for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
#else
        /* It makes more sense to use 0.5 */
        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
#endif
        if( infop->type==etFLOAT ) realvalue += rounder;
        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
        exp = 0;
        if( realvalue>0.0 ){
          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
          while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
          while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
          if( exp>350 || exp<-350 ){
            bufpt = "NaN";
            length = 3;
            break;
          }
        }
        bufpt = buf;
        /*
        ** If the field type is etGENERIC, then convert to either etEXP
        ** or etFLOAT, as appropriate.
        */
        flag_exp = xtype==etEXP;
        if( xtype!=etFLOAT ){
          realvalue += rounder;
          if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
        }
        if( xtype==etGENERIC ){
          flag_rtz = !flag_alternateform;
          if( exp<-4 || exp>precision ){
            xtype = etEXP;
          }else{
            precision = precision - exp;
            xtype = etFLOAT;
          }
        }else{
          flag_rtz = 0;
        }
        /*
        ** The "exp+precision" test causes output to be of type etEXP if
        ** the precision is too large to fit in buf[].
        */
        nsd = 0;
        if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
          flag_dp = (precision>0 || flag_alternateform);
          if( prefix ) *(bufpt++) = prefix;         /* Sign */
          if( exp<0 )  *(bufpt++) = '0';            /* Digits before "." */
          else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);
          if( flag_dp ) *(bufpt++) = '.';           /* The decimal point */
          for(exp++; exp<0 && precision>0; precision--, exp++){
            *(bufpt++) = '0';
          }
          while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
          *(bufpt--) = 0;                           /* Null terminate */
          if( flag_rtz && flag_dp ){     /* Remove trailing zeros and "." */
            while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
            if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
          }
          bufpt++;                            /* point to next free slot */
        }else{    /* etEXP or etGENERIC */
          flag_dp = (precision>0 || flag_alternateform);
          if( prefix ) *(bufpt++) = prefix;   /* Sign */
          *(bufpt++) = et_getdigit(&realvalue,&nsd);  /* First digit */
          if( flag_dp ) *(bufpt++) = '.';     /* Decimal point */
          while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
          bufpt--;                            /* point to last digit */
          if( flag_rtz && flag_dp ){          /* Remove tail zeros */
            while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
            if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
          }
          bufpt++;                            /* point to next free slot */
          if( exp || flag_exp ){
            *(bufpt++) = aDigits[infop->charset];
            if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
            else       { *(bufpt++) = '+'; }
            if( exp>=100 ){
              *(bufpt++) = (exp/100)+'0';                /* 100's digit */
              exp %= 100;
            }
            *(bufpt++) = exp/10+'0';                     /* 10's digit */
            *(bufpt++) = exp%10+'0';                     /* 1's digit */
          }
        }
        /* The converted number is in buf[] and zero terminated. Output it.
        ** Note that the number is in the usual order, not reversed as with
        ** integer conversions. */
        length = bufpt-buf;
        bufpt = buf;

        /* Special case:  Add leading zeros if the flag_zeropad flag is
        ** set and we are not left justified */
        if( flag_zeropad && !flag_leftjustify && length < width){
          int i;
          int nPad = width - length;
          for(i=width; i>=nPad; i--){
            bufpt[i] = bufpt[i-nPad];
          }
          i = prefix!=0;
          while( nPad-- ) bufpt[i++] = '0';
          length = width;
        }
#endif
        break;
      case etSIZE:
        *(va_arg(ap,int*)) = count;
        length = width = 0;
        break;
      case etPERCENT:
        buf[0] = '%';
        bufpt = buf;
        length = 1;
        break;
      case etCHARLIT:
      case etCHARX:
        c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
        if( precision>=0 ){
          for(idx=1; idx<precision; idx++) buf[idx] = c;
          length = precision;
        }else{
          length =1;
        }
        bufpt = buf;
        break;
      case etSTRING:
      case etDYNSTRING:
        bufpt = va_arg(ap,char*);
        if( bufpt==0 ){
          bufpt = "";
        }else if( xtype==etDYNSTRING ){
          zExtra = bufpt;
        }
        length = strlen(bufpt);
        if( precision>=0 && precision<length ) length = precision;
        break;
      case etSQLESCAPE:
      case etSQLESCAPE2:
        {
          int i, j, n, c, isnull;
          int needQuote;
          char *arg = va_arg(ap,char*);
          isnull = arg==0;
          if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
          for(i=n=0; (c=arg[i])!=0; i++){
            if( c=='\'' )  n++;
          }
          needQuote = !isnull && xtype==etSQLESCAPE2;
          n += i + 1 + needQuote*2;
          if( n>etBUFSIZE ){
            bufpt = zExtra = sqliteMalloc( n );
            if( bufpt==0 ) return -1;
          }else{
            bufpt = buf;
          }
          j = 0;
          if( needQuote ) bufpt[j++] = '\'';
          for(i=0; (c=arg[i])!=0; i++){
            bufpt[j++] = c;
            if( c=='\'' ) bufpt[j++] = c;
          }
          if( needQuote ) bufpt[j++] = '\'';
          bufpt[j] = 0;
          length = j;
          if( precision>=0 && precision<length ) length = precision;
        }
        break;
      case etTOKEN: {
        Token *pToken = va_arg(ap, Token*);
        if( pToken && pToken->z ){
          (*func)(arg, pToken->z, pToken->n);
        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);
        struct SrcList_item *pItem = &pSrc->a[k];
        assert( k>=0 && k<pSrc->nSrc );
        if( pItem->zDatabase && pItem->zDatabase[0] ){
          (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase));
          (*func)(arg, ".", 1);
        }
        (*func)(arg, pItem->zName, strlen(pItem->zName));
        length = width = 0;
        break;
      }
      case etERROR:
        buf[0] = '%';
        buf[1] = c;
        errorflag = 0;
        idx = 1+(c!=0);
        (*func)(arg,"%",idx);
        count += idx;
        if( c==0 ) fmt--;
        break;
    }/* End switch over the format type */
    /*
    ** The text of the conversion is pointed to by "bufpt" and is
    ** "length" characters long.  The field width is "width".  Do
    ** the output.
    */
    if( !flag_leftjustify ){
      register int nspace;
      nspace = width-length;
      if( nspace>0 ){
        count += nspace;
        while( nspace>=etSPACESIZE ){
          (*func)(arg,spaces,etSPACESIZE);
          nspace -= etSPACESIZE;
        }
        if( nspace>0 ) (*func)(arg,spaces,nspace);
      }
    }
    if( length>0 ){
      (*func)(arg,bufpt,length);
      count += length;
    }
    if( flag_leftjustify ){
      register int nspace;
      nspace = width-length;
      if( nspace>0 ){
        count += nspace;
        while( nspace>=etSPACESIZE ){
          (*func)(arg,spaces,etSPACESIZE);
          nspace -= etSPACESIZE;
        }
        if( nspace>0 ) (*func)(arg,spaces,nspace);
      }
    }
    if( zExtra ){
      sqliteFree(zExtra);
    }
  }/* End for loop over the format string */
  return errorflag ? -1 : count;
} /* End of function */


/* This structure is used to store state information about the
** write to memory that is currently in progress.
*/
struct sgMprintf {
  char *zBase;     /* A base allocation */
  char *zText;     /* The string collected so far */
  int  nChar;      /* Length of the string so far */
  int  nTotal;     /* Output size if unconstrained */
  int  nAlloc;     /* Amount of space allocated in zText */
  void *(*xRealloc)(void*,int);  /* Function used to realloc memory */
};

/* 
** This function implements the callback from vxprintf. 
**
** This routine add nNewChar characters of text in zNewText to
** the sgMprintf structure pointed to by "arg".
*/
static void mout(void *arg, const char *zNewText, int nNewChar){
  struct sgMprintf *pM = (struct sgMprintf*)arg;
  pM->nTotal += nNewChar;
  if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
    if( pM->xRealloc==0 ){
      nNewChar =  pM->nAlloc - pM->nChar - 1;
    }else{
      pM->nAlloc = pM->nChar + nNewChar*2 + 1;
      if( pM->zText==pM->zBase ){
        pM->zText = pM->xRealloc(0, pM->nAlloc);
        if( pM->zText && pM->nChar ){
          memcpy(pM->zText, pM->zBase, pM->nChar);
        }
      }else{
        pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
      }
    }
  }
  if( pM->zText ){
    if( nNewChar>0 ){
      memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
      pM->nChar += nNewChar;
    }
    pM->zText[pM->nChar] = 0;
  }
}

/*
** This routine is a wrapper around xprintf() that invokes mout() as
** the consumer.  
*/
static char *base_vprintf(
  void *(*xRealloc)(void*,int),   /* Routine to realloc memory. May be NULL */
  int useInternal,                /* Use internal %-conversions if true */
  char *zInitBuf,                 /* Initially write here, before mallocing */
  int nInitBuf,                   /* Size of zInitBuf[] */
  const char *zFormat,            /* format string */
  va_list ap                      /* arguments */
){
  struct sgMprintf sM;
  sM.zBase = sM.zText = zInitBuf;
  sM.nChar = sM.nTotal = 0;
  sM.nAlloc = nInitBuf;
  sM.xRealloc = xRealloc;
  vxprintf(mout, &sM, useInternal, zFormat, ap);
  if( xRealloc ){
    if( sM.zText==sM.zBase ){
      sM.zText = xRealloc(0, sM.nChar+1);
      if( sM.zText ){
        memcpy(sM.zText, sM.zBase, sM.nChar+1);
      }
    }else if( sM.nAlloc>sM.nChar+10 ){
      sM.zText = xRealloc(sM.zText, sM.nChar+1);
    }
  }
  return sM.zText;
}

/*
** Realloc that is a real function, not a macro.
*/
static void *printf_realloc(void *old, int size){
  return sqliteRealloc(old,size);
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
** %-conversion extensions.
*/
char *sqlite3VMPrintf(const char *zFormat, va_list ap){
  char zBase[1000];
  return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
** %-conversion extensions.
*/
char *sqlite3MPrintf(const char *zFormat, ...){
  va_list ap;
  char *z;
  char zBase[1000];
  va_start(ap, zFormat);
  z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
  va_end(ap);
  return z;
}

/*
** Print into memory obtained from malloc().  Do not use the internal
** %-conversion extensions.  This routine is for use by external users.
*/
char *sqlite3_mprintf(const char *zFormat, ...){
  va_list ap;
  char *z;
  char zBuf[200];

  va_start(ap,zFormat);
  z = base_vprintf((void*(*)(void*,int))realloc, 0, 
                   zBuf, sizeof(zBuf), zFormat, ap);
  va_end(ap);
  return z;
}

/* This is the varargs version of sqlite3_mprintf.  
*/
char *sqlite3_vmprintf(const char *zFormat, va_list ap){
  char zBuf[200];
  return base_vprintf((void*(*)(void*,int))realloc, 0,
                      zBuf, sizeof(zBuf), zFormat, ap);
}

/*
** sqlite3_snprintf() works like snprintf() except that it ignores the
** current locale settings.  This is important for SQLite because we
** are not able to use a "," as the decimal point in place of "." as
** specified by some locales.
*/
char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
  char *z;
  va_list ap;

  va_start(ap,zFormat);
  z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
  va_end(ap);
  return z;
}

#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
/*
** A version of printf() that understands %lld.  Used for debugging.
** The printf() built into some versions of windows does not understand %lld
** and segfaults if you give it a long long int.
*/
void sqlite3DebugPrintf(const char *zFormat, ...){
  extern int getpid(void);
  va_list ap;
  char zBuf[500];
  va_start(ap, zFormat);
  base_vprintf(0, 0, zBuf, sizeof(zBuf), zFormat, ap);
  va_end(ap);
  fprintf(stdout,"%d: %s", getpid(), zBuf);
  fflush(stdout);
}
#endif
Added SQLite.Interop/src/random.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
/*
** 2001 September 15
**
** 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 file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.1 2005/03/01 16:04:34 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"


/*
** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
** must be held while executing this routine.
**
** Why not just use a library random generator like lrand48() for this?
** Because the OP_NewRecno opcode in the VDBE depends on having a very
** good source of random numbers.  The lrand48() library function may
** well be good enough.  But maybe not.  Or maybe lrand48() has some
** subtle problems on some systems that could cause problems.  It is hard
** to know.  To minimize the risk of problems due to bad lrand48()
** implementations, SQLite uses this random number generator based
** on RC4, which we know works very well.
*/
static int randomByte(){
  unsigned char t;

  /* All threads share a single random number generator.
  ** This structure is the current state of the generator.
  */
  static struct {
    unsigned char isInit;          /* True if initialized */
    unsigned char i, j;            /* State variables */
    unsigned char s[256];          /* State variables */
  } prng;

  /* Initialize the state of the random number generator once,
  ** the first time this routine is called.  The seed value does
  ** not need to contain a lot of randomness since we are not
  ** trying to do secure encryption or anything like that...
  **
  ** Nothing in this file or anywhere else in SQLite does any kind of
  ** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
  ** number generator) not as an encryption device.
  */
  if( !prng.isInit ){
    int i;
    char k[256];
    prng.j = 0;
    prng.i = 0;
    sqlite3OsRandomSeed(k);
    for(i=0; i<256; i++){
      prng.s[i] = i;
    }
    for(i=0; i<256; i++){
      prng.j += prng.s[i] + k[i];
      t = prng.s[prng.j];
      prng.s[prng.j] = prng.s[i];
      prng.s[i] = t;
    }
    prng.isInit = 1;
  }

  /* Generate and return single random byte
  */
  prng.i++;
  t = prng.s[prng.i];
  prng.j += t;
  prng.s[prng.i] = prng.s[prng.j];
  prng.s[prng.j] = t;
  t += prng.s[prng.i];
  return prng.s[t];
}

/*
** Return N random bytes.
*/
void sqlite3Randomness(int N, void *pBuf){
  unsigned char *zBuf = pBuf;
  sqlite3OsEnterMutex();
  while( N-- ){
    *(zBuf++) = randomByte();
  }
  sqlite3OsLeaveMutex();
}



Added SQLite.Interop/src/select.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
/*
** 2001 September 15
**
** 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 file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.1 2005/03/01 16:04:35 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "../interop.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
Select *sqlite3SelectNew(
  ExprList *pEList,     /* which columns to include in the result */
  SrcList *pSrc,        /* the FROM clause -- which tables to scan */
  Expr *pWhere,         /* the WHERE clause */
  ExprList *pGroupBy,   /* the GROUP BY clause */
  Expr *pHaving,        /* the HAVING clause */
  ExprList *pOrderBy,   /* the ORDER BY clause */
  int isDistinct,       /* true if the DISTINCT keyword is present */
  Expr *pLimit,         /* LIMIT value.  NULL means not used */
  Expr *pOffset         /* OFFSET value.  NULL means no offset */
){
  Select *pNew;
  pNew = sqliteMalloc( sizeof(*pNew) );
  assert( !pOffset || pLimit );   /* Can't have OFFSET without LIMIT. */
  if( pNew==0 ){
    sqlite3ExprListDelete(pEList);
    sqlite3SrcListDelete(pSrc);
    sqlite3ExprDelete(pWhere);
    sqlite3ExprListDelete(pGroupBy);
    sqlite3ExprDelete(pHaving);
    sqlite3ExprListDelete(pOrderBy);
    sqlite3ExprDelete(pLimit);
    sqlite3ExprDelete(pOffset);
  }else{
    if( pEList==0 ){
      pEList = sqlite3ExprListAppend(0, sqlite3Expr(TK_ALL,0,0,0), 0);
    }
    pNew->pEList = pEList;
    pNew->pSrc = pSrc;
    pNew->pWhere = pWhere;
    pNew->pGroupBy = pGroupBy;
    pNew->pHaving = pHaving;
    pNew->pOrderBy = pOrderBy;
    pNew->isDistinct = isDistinct;
    pNew->op = TK_SELECT;
    pNew->pLimit = pLimit;
    pNew->pOffset = pOffset;
    pNew->iLimit = -1;
    pNew->iOffset = -1;
  }
  return pNew;
}

/*
** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
** type of join.  Return an integer constant that expresses that type
** in terms of the following bit values:
**
**     JT_INNER
**     JT_OUTER
**     JT_NATURAL
**     JT_LEFT
**     JT_RIGHT
**
** A full outer join is the combination of JT_LEFT and JT_RIGHT.
**
** If an illegal or unsupported join type is seen, then still return
** a join type, but put an error in the pParse structure.
*/
int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
  int jointype = 0;
  Token *apAll[3];
  Token *p;
  static const struct {
    const char *zKeyword;
    u8 nChar;
    u8 code;
  } keywords[] = {
    { "natural", 7, JT_NATURAL },
    { "left",    4, JT_LEFT|JT_OUTER },
    { "right",   5, JT_RIGHT|JT_OUTER },
    { "full",    4, JT_LEFT|JT_RIGHT|JT_OUTER },
    { "outer",   5, JT_OUTER },
    { "inner",   5, JT_INNER },
    { "cross",   5, JT_INNER },
  };
  int i, j;
  apAll[0] = pA;
  apAll[1] = pB;
  apAll[2] = pC;
  for(i=0; i<3 && apAll[i]; i++){
    p = apAll[i];
    for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
      if( p->n==keywords[j].nChar 
          && sqlite3StrNICmp(p->z, keywords[j].zKeyword, p->n)==0 ){
        jointype |= keywords[j].code;
        break;
      }
    }
    if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
      jointype |= JT_ERROR;
      break;
    }
  }
  if(
     (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
     (jointype & JT_ERROR)!=0
  ){
    const char *zSp1 = " ";
    const char *zSp2 = " ";
    if( pB==0 ){ zSp1++; }
    if( pC==0 ){ zSp2++; }
    sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
       "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC);
    jointype = JT_INNER;
  }else if( jointype & JT_RIGHT ){
    sqlite3ErrorMsg(pParse, 
      "RIGHT and FULL OUTER JOINs are not currently supported");
    jointype = JT_INNER;
  }
  return jointype;
}

/*
** Return the index of a column in a table.  Return -1 if the column
** is not contained in the table.
*/
static int columnIndex(Table *pTab, const char *zCol){
  int i;
  for(i=0; i<pTab->nCol; i++){
    if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
  }
  return -1;
}

/*
** Set the value of a token to a '\000'-terminated string.
*/
static void setToken(Token *p, const char *z){
  p->z = z;
  p->n = strlen(z);
  p->dyn = 0;
}


/*
** Add a term to the WHERE expression in *ppExpr that requires the
** zCol column to be equal in the two tables pTab1 and pTab2.
*/
static void addWhereTerm(
  const char *zCol,        /* Name of the column */
  const Table *pTab1,      /* First table */
  const char *zAlias1,     /* Alias for first table.  May be NULL */
  const Table *pTab2,      /* Second table */
  const char *zAlias2,     /* Alias for second table.  May be NULL */
  Expr **ppExpr            /* Add the equality term to this expression */
){
  Token dummy;
  Expr *pE1a, *pE1b, *pE1c;
  Expr *pE2a, *pE2b, *pE2c;
  Expr *pE;

  setToken(&dummy, zCol);
  pE1a = sqlite3Expr(TK_ID, 0, 0, &dummy);
  pE2a = sqlite3Expr(TK_ID, 0, 0, &dummy);
  if( zAlias1==0 ){
    zAlias1 = pTab1->zName;
  }
  setToken(&dummy, zAlias1);
  pE1b = sqlite3Expr(TK_ID, 0, 0, &dummy);
  if( zAlias2==0 ){
    zAlias2 = pTab2->zName;
  }
  setToken(&dummy, zAlias2);
  pE2b = sqlite3Expr(TK_ID, 0, 0, &dummy);
  pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0);
  pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0);
  pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0);
  ExprSetProperty(pE, EP_FromJoin);
  *ppExpr = sqlite3ExprAnd(*ppExpr, pE);
}

/*
** Set the EP_FromJoin property on all terms of the given expression.
**
** The EP_FromJoin property is used on terms of an expression to tell
** the LEFT OUTER JOIN processing logic that this term is part of the
** join restriction specified in the ON or USING clause and not a part
** of the more general WHERE clause.  These terms are moved over to the
** WHERE clause during join processing but we need to remember that they
** originated in the ON or USING clause.
*/
static void setJoinExpr(Expr *p){
  while( p ){
    ExprSetProperty(p, EP_FromJoin);
    setJoinExpr(p->pLeft);
    p = p->pRight;
  } 
}

/*
** This routine processes the join information for a SELECT statement.
** ON and USING clauses are converted into extra terms of the WHERE clause.
** NATURAL joins also create extra WHERE clause terms.
**
** The terms of a FROM clause are contained in the Select.pSrc structure.
** The left most table is the first entry in Select.pSrc.  The right-most
** table is the last entry.  The join operator is held in the entry to
** the left.  Thus entry 0 contains the join operator for the join between
** entries 0 and 1.  Any ON or USING clauses associated with the join are
** also attached to the left entry.
**
** This routine returns the number of errors encountered.
*/
static int sqliteProcessJoin(Parse *pParse, Select *p){
  SrcList *pSrc;                  /* All tables in the FROM clause */
  int i, j;                       /* Loop counters */
  struct SrcList_item *pLeft;     /* Left table being joined */
  struct SrcList_item *pRight;    /* Right table being joined */

  pSrc = p->pSrc;
  pLeft = &pSrc->a[0];
  pRight = &pLeft[1];
  for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
    Table *pLeftTab = pLeft->pTab;
    Table *pRightTab = pRight->pTab;

    if( pLeftTab==0 || pRightTab==0 ) continue;

    /* When the NATURAL keyword is present, add WHERE clause terms for
    ** every column that the two tables have in common.
    */
    if( pLeft->jointype & JT_NATURAL ){
      if( pLeft->pOn || pLeft->pUsing ){
        sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
           "an ON or USING clause", 0);
        return 1;
      }
      for(j=0; j<pLeftTab->nCol; j++){
        char *zName = pLeftTab->aCol[j].zName;
        if( columnIndex(pRightTab, zName)>=0 ){
          addWhereTerm(zName, pLeftTab, pLeft->zAlias, 
                              pRightTab, pRight->zAlias, &p->pWhere);
        }
      }
    }

    /* Disallow both ON and USING clauses in the same join
    */
    if( pLeft->pOn && pLeft->pUsing ){
      sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
        "clauses in the same join");
      return 1;
    }

    /* Add the ON clause to the end of the WHERE clause, connected by
    ** an AND operator.
    */
    if( pLeft->pOn ){
      setJoinExpr(pLeft->pOn);
      p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn);
      pLeft->pOn = 0;
    }

    /* Create extra terms on the WHERE clause for each column named
    ** in the USING clause.  Example: If the two tables to be joined are 
    ** A and B and the USING clause names X, Y, and Z, then add this
    ** to the WHERE clause:    A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
    ** Report an error if any column mentioned in the USING clause is
    ** not contained in both tables to be joined.
    */
    if( pLeft->pUsing ){
      IdList *pList = pLeft->pUsing;
      for(j=0; j<pList->nId; j++){
        char *zName = pList->a[j].zName;
        if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }
        addWhereTerm(zName, pLeftTab, pLeft->zAlias, 
                            pRightTab, pRight->zAlias, &p->pWhere);
      }
    }
  }
  return 0;
}

/*
** Delete the given Select structure and all of its substructures.
*/
void sqlite3SelectDelete(Select *p){
  if( p==0 ) return;
  sqlite3ExprListDelete(p->pEList);
  sqlite3SrcListDelete(p->pSrc);
  sqlite3ExprDelete(p->pWhere);
  sqlite3ExprListDelete(p->pGroupBy);
  sqlite3ExprDelete(p->pHaving);
  sqlite3ExprListDelete(p->pOrderBy);
  sqlite3SelectDelete(p->pPrior);
  sqlite3ExprDelete(p->pLimit);
  sqlite3ExprDelete(p->pOffset);
  sqliteFree(p);
}

/*
** Insert code into "v" that will push the record on the top of the
** stack into the sorter.
*/
static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
  int i;
  for(i=0; i<pOrderBy->nExpr; i++){
    sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr);
  }
  sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0);
  sqlite3VdbeAddOp(v, OP_SortPut, 0, 0);
}

/*
** Add code to implement the OFFSET and LIMIT
*/
static void codeLimiter(
  Vdbe *v,          /* Generate code into this VM */
  Select *p,        /* The SELECT statement being coded */
  int iContinue,    /* Jump here to skip the current record */
  int iBreak,       /* Jump here to end the loop */
  int nPop          /* Number of times to pop stack when jumping */
){
  if( p->iOffset>=0 ){
    int addr = sqlite3VdbeCurrentAddr(v) + 3;
    if( nPop>0 ) addr++;
    sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, 0);
    sqlite3VdbeAddOp(v, OP_IfMemPos, p->iOffset, addr);
    if( nPop>0 ){
      sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
    }
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "# skip OFFSET records"));
  }
  if( p->iLimit>=0 ){
    sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
    VdbeComment((v, "# exit when LIMIT reached"));
  }
}

/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
** If srcTab and nColumn are both zero, then the pEList expressions
** are evaluated in order to get the data for this row.  If nColumn>0
** then data is pulled from srcTab and pEList is used only to get the
** datatypes for each column.
*/
static int selectInnerLoop(
  Parse *pParse,          /* The parser context */
  Select *p,              /* The complete select statement being coded */
  ExprList *pEList,       /* List of values being extracted */
  int srcTab,             /* Pull data from this table */
  int nColumn,            /* Number of columns in the source table */
  ExprList *pOrderBy,     /* If not NULL, sort results using this key */
  int distinct,           /* If >=0, make sure results are distinct */
  int eDest,              /* How to dispose of the results */
  int iParm,              /* An argument to the disposal method */
  int iContinue,          /* Jump here to continue with next row */
  int iBreak,             /* Jump here to break out of the inner loop */
  char *aff               /* affinity string if eDest is SRT_Union */
){
  Vdbe *v = pParse->pVdbe;
  int i;
  int hasDistinct;        /* True if the DISTINCT keyword is present */

  if( v==0 ) return 0;
  assert( pEList!=0 );

  /* If there was a LIMIT clause on the SELECT statement, then do the check
  ** to see if this row should be output.
  */
  hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
  if( pOrderBy==0 && !hasDistinct ){
    codeLimiter(v, p, iContinue, iBreak, 0);
  }

  /* Pull the requested columns.
  */
  if( nColumn>0 ){
    for(i=0; i<nColumn; i++){
      sqlite3VdbeAddOp(v, OP_Column, srcTab, i);
    }
  }else{
    nColumn = pEList->nExpr;
    for(i=0; i<pEList->nExpr; i++){
      sqlite3ExprCode(pParse, pEList->a[i].pExpr);
    }
  }

  /* If the DISTINCT keyword was present on the SELECT statement
  ** and this row has been seen before, then do not make this row
  ** part of the result.
  */
  if( hasDistinct ){
#if NULL_ALWAYS_DISTINCT
    sqlite3VdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqlite3VdbeCurrentAddr(v)+7);
#endif
    /* Deliberately leave the affinity string off of the following
    ** OP_MakeRecord */
    sqlite3VdbeAddOp(v, OP_MakeRecord, pEList->nExpr * -1, 0);
    sqlite3VdbeAddOp(v, OP_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3);
    sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "# skip indistinct records"));
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0);
    if( pOrderBy==0 ){
      codeLimiter(v, p, iContinue, iBreak, nColumn);
    }
  }

  switch( eDest ){
#ifndef SQLITE_OMIT_COMPOUND_SELECT
    /* In this mode, write each query result to the key of the temporary
    ** table iParm.
    */
    case SRT_Union: {
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
      sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_PutStrKey, iParm, 0);
      break;
    }

    /* Construct a record from the query result, but instead of
    ** saving that record, use it as a key to delete elements from
    ** the temporary table iParm.
    */
    case SRT_Except: {
      int addr;
      addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
      sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
      sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
      sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
      break;
    }
#endif

    /* Store the result as data using a unique key.
    */
    case SRT_Table:
    case SRT_TempTable: {
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
      if( pOrderBy ){
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0);
        sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
        sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0);
      }
      break;
    }

#ifndef SQLITE_OMIT_SUBQUERY
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
    ** then there should be a single item on the stack.  Write this
    ** item into the set table with bogus data.
    */
    case SRT_Set: {
      int addr1 = sqlite3VdbeCurrentAddr(v);
      int addr2;

      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr1+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
      if( pOrderBy ){
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        char aff = (iParm>>16)&0xFF;
        aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
        sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
      }
      sqlite3VdbeChangeP2(v, addr2, sqlite3VdbeCurrentAddr(v));
      break;
    }

    /* If this is a scalar select that is part of an expression, then
    ** store the results in the appropriate memory cell and break out
    ** of the scan loop.
    */
    case SRT_Exists:
    case SRT_Mem: {
      assert( nColumn==1 );
      if( pOrderBy ){
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
        sqlite3VdbeAddOp(v, OP_Goto, 0, iBreak);
      }
      break;
    }
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */

    /* Send the data to the callback function.
    */
    case SRT_Callback:
    case SRT_Sorter: {
      if( pOrderBy ){
        sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        assert( eDest==SRT_Callback );
        sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
      }
      break;
    }

    /* Invoke a subroutine to handle the results.  The subroutine itself
    ** is responsible for popping the results off of the stack.
    */
    case SRT_Subroutine: {
      if( pOrderBy ){
        sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
      }
      break;
    }

#if !defined(SQLITE_OMIT_TRIGGER)
    /* Discard the results.  This is used for SELECT statements inside
    ** the body of a TRIGGER.  The purpose of such selects is to call
    ** user-defined functions that have side effects.  We do not care
    ** about the actual results of the select.
    */
    default: {
      assert( eDest==SRT_Discard );
      sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
      break;
    }
#endif
  }
  return 0;
}

/*
** If the inner loop was generated using a non-null pOrderBy argument,
** then the results were placed in a sorter.  After the loop is terminated
** we need to run the sorter and output the results.  The following
** routine generates the code needed to do that.
*/
static void generateSortTail(
  Parse *pParse,   /* The parsing context */
  Select *p,       /* The SELECT statement */
  Vdbe *v,         /* Generate code into this VDBE */
  int nColumn,     /* Number of columns of data */
  int eDest,       /* Write the sorted results here */
  int iParm        /* Optional parameter associated with eDest */
){
  int end1 = sqlite3VdbeMakeLabel(v);
  int end2 = sqlite3VdbeMakeLabel(v);
  int addr;
  KeyInfo *pInfo;
  ExprList *pOrderBy;
  int nCol, i;
  sqlite3 *db = pParse->db;

  if( eDest==SRT_Sorter ) return;
  pOrderBy = p->pOrderBy;
  nCol = pOrderBy->nExpr;
  pInfo = sqliteMalloc( sizeof(*pInfo) + nCol*(sizeof(CollSeq*)+1) );
  if( pInfo==0 ) return;
  pInfo->aSortOrder = (char*)&pInfo->aColl[nCol];
  pInfo->nField = nCol;
  for(i=0; i<nCol; i++){
    /* If a collation sequence was specified explicity, then it
    ** is stored in pOrderBy->a[i].zName. Otherwise, use the default
    ** collation type for the expression.
    */
    pInfo->aColl[i] = sqlite3ExprCollSeq(pParse, pOrderBy->a[i].pExpr);
    if( !pInfo->aColl[i] ){
      pInfo->aColl[i] = db->pDfltColl;
    }
    pInfo->aSortOrder[i] = pOrderBy->a[i].sortOrder;
  }
  sqlite3VdbeOp3(v, OP_Sort, 0, 0, (char*)pInfo, P3_KEYINFO_HANDOFF);
  addr = sqlite3VdbeAddOp(v, OP_SortNext, 0, end1);
  codeLimiter(v, p, addr, end2, 1);
  switch( eDest ){
    case SRT_Table:
    case SRT_TempTable: {
      sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case SRT_Set: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
      break;
    }
    case SRT_Exists:
    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
      sqlite3VdbeAddOp(v, OP_Goto, 0, end1);
      break;
    }
#endif
    case SRT_Callback:
    case SRT_Subroutine: {
      int i;
      sqlite3VdbeAddOp(v, OP_Integer, p->pEList->nExpr, 0);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      for(i=0; i<nColumn; i++){
        sqlite3VdbeAddOp(v, OP_Column, -1-i, i);
      }
      if( eDest==SRT_Callback ){
        sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
      }else{
        sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
      }
      sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
      break;
    }
    default: {
      /* Do nothing */
      break;
    }
  }
  sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
  sqlite3VdbeResolveLabel(v, end2);
  sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  sqlite3VdbeResolveLabel(v, end1);
  sqlite3VdbeAddOp(v, OP_SortReset, 0, 0);
}

/*
** Return a pointer to a string containing the 'declaration type' of the
** expression pExpr. The string may be treated as static by the caller.
**
** If the declaration type is the exact datatype definition extracted from
** the original CREATE TABLE statement if the expression is a column.
** 
** The declaration type for an expression is either TEXT, NUMERIC or ANY.
** The declaration type for a ROWID field is INTEGER.
*/
static const char *columnType(NameContext *pNC, Expr *pExpr){
  char const *zType;
  int j;
  if( pExpr==0 || pNC->pSrcList==0 ) return 0;

  /* The TK_AS operator can only occur in ORDER BY, GROUP BY, HAVING,
  ** and LIMIT clauses.  But pExpr originates in the result set of a
  ** SELECT.  So pExpr can never contain an AS operator.
  */
  assert( pExpr->op!=TK_AS );

  switch( pExpr->op ){
    case TK_COLUMN: {
      Table *pTab = 0;
      int iCol = pExpr->iColumn;
      while( pNC && !pTab ){
        SrcList *pTabList = pNC->pSrcList;
        for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
        if( j<pTabList->nSrc ){
          pTab = pTabList->a[j].pTab;
        }else{
          pNC = pNC->pNext;
        }
      }
      assert( pTab );
      if( iCol<0 ) iCol = pTab->iPKey;
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zType = "INTEGER";
      }else{
        zType = pTab->aCol[iCol].zType;
      }
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_SELECT: {
      NameContext sNC;
      Select *pS = pExpr->pSelect;
      sNC.pSrcList = pExpr->pSelect->pSrc;
      sNC.pNext = pNC;
      zType = columnType(&sNC, pS->pEList->a[0].pExpr); 
      break;
    }
#endif
    default:
      zType = 0;
  }
  
  return zType;
}

/*
** Generate code that will tell the VDBE the declaration types of columns
** in the result set.
*/
static void generateColumnTypes(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i;
  NameContext sNC;
  sNC.pSrcList = pTabList;
  for(i=0; i<pEList->nExpr; i++){
    Expr *p = pEList->a[i].pExpr;
    const char *zType = columnType(&sNC, p);
    if( zType==0 ) continue;
    /* The vdbe must make it's own copy of the column-type, in case the 
    ** schema is reset before this virtual machine is deleted.
    */
    sqlite3VdbeSetColName(v, i+pEList->nExpr, zType, strlen(zType));
  }
}

/*
** Generate code that will tell the VDBE the names of columns
** in the result set.  This information is used to provide the
** azCol[] values in the callback.
*/
static void _generateColumnNames(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i, j;
  sqlite3 *db = pParse->db;
  int fullNames, shortNames;

#ifndef SQLITE_OMIT_EXPLAIN
  /* If this is an EXPLAIN, skip this step */
  if( pParse->explain ){
    return;
  }
#endif

  assert( v!=0 );
  if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return;
  pParse->colNamesSet = 1;
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
    if( p==0 ) continue;
    if( pEList->a[i].zName ){
      char *zName = pEList->a[i].zName;
      sqlite3VdbeSetColName(v, i, zName, strlen(zName));
      continue;
    }
    if( p->op==TK_COLUMN && pTabList ){
      Table *pTab;
      char *zCol;
      int iCol = p->iColumn;
      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
      assert( j<pTabList->nSrc );
      pTab = pTabList->a[j].pTab;
      if( iCol<0 ) iCol = pTab->iPKey;
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zCol = "rowid";
      }else{
        zCol = pTab->aCol[iCol].zName;
      }
      if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
        sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
        char *zName = 0;
        char *zTab;
 
        zTab = pTabList->a[j].zAlias;
        if( fullNames || zTab==0 ) zTab = pTab->zName;
        sqlite3SetString(&zName, zTab, ".", zCol, 0);
        sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
      }else{
        sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
      }
    }else if( p->span.z && p->span.z[0] ){
      sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
      /* sqlite3VdbeCompressSpace(v, addr); */
    }else{
      char zName[30];
      assert( p->op!=TK_COLUMN || pTabList==0 );
      sprintf(zName, "column%d", i+1);
      sqlite3VdbeSetColName(v, i, zName, 0);
    }
  }
  generateColumnTypes(pParse, pTabList, pEList);
}

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Name of the connection operator, used for error messages.
*/
static const char *selectOpName(int id){
  char *z;
  switch( id ){
    case TK_ALL:       z = "UNION ALL";   break;
    case TK_INTERSECT: z = "INTERSECT";   break;
    case TK_EXCEPT:    z = "EXCEPT";      break;
    default:           z = "UNION";       break;
  }
  return z;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

/*
** Forward declaration
*/
static int prepSelectStmt(Parse*, Select*);

/*
** Given a SELECT statement, generate a Table structure that describes
** the result set of that SELECT.
*/
Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
  Table *pTab;
  int i, j;
  ExprList *pEList;
  Column *aCol, *pCol;

  if( prepSelectStmt(pParse, pSelect) ){
    return 0;
  }
  if( sqlite3SelectResolve(pParse, pSelect, 0) ){
    return 0;
  }
  pTab = sqliteMalloc( sizeof(Table) );
  if( pTab==0 ){
    return 0;
  }
  pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0;
  pEList = pSelect->pEList;
  pTab->nCol = pEList->nExpr;
  assert( pTab->nCol>0 );
  pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
  for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
    Expr *p, *pR;
    char *zType;
    char *zName;
    char *zBasename;
    int cnt;
    NameContext sNC;
    
    /* Get an appropriate name for the column
    */
    p = pEList->a[i].pExpr;
    assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
    if( (zName = pEList->a[i].zName)!=0 ){
      /* If the column contains an "AS <name>" phrase, use <name> as the name */
      zName = sqliteStrDup(zName);
    }else if( p->op==TK_DOT 
              && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
      /* For columns of the from A.B use B as the name */
      zName = sqlite3MPrintf("%T", &pR->token);
    }else if( p->span.z && p->span.z[0] ){
      /* Use the original text of the column expression as its name */
      zName = sqlite3MPrintf("%T", &p->span);
    }else{
      /* If all else fails, make up a name */
      zName = sqlite3MPrintf("column%d", i+1);
    }
    sqlite3Dequote(zName);

    /* Make sure the column name is unique.  If the name is not unique,
    ** append a integer to the name so that it becomes unique.
    */
    zBasename = zName;
    for(j=cnt=0; j<i; j++){
      if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
        zName = sqlite3MPrintf("%s:%d", zBasename, ++cnt);
        j = -1;
      }
    }
    if( zBasename!=zName ){
      sqliteFree(zBasename);
    }
    pCol->zName = zName;

    /* Get the typename, type affinity, and collating sequence for the
    ** column.
    */
    sNC.pSrcList = pSelect->pSrc;
    zType = sqliteStrDup(columnType(&sNC, p));
    pCol->zType = zType;
    pCol->affinity = sqlite3ExprAffinity(p);
    pCol->pColl = sqlite3ExprCollSeq(pParse, p);
    if( !pCol->pColl ){
      pCol->pColl = pParse->db->pDfltColl;
    }
  }
  pTab->iPKey = -1;
  return pTab;
}

/*
** Prepare a SELECT statement for processing by doing the following
** things:
**
**    (1)  Make sure VDBE cursor numbers have been assigned to every
**         element of the FROM clause.
**
**    (2)  Fill in the pTabList->a[].pTab fields in the SrcList that 
**         defines FROM clause.  When views appear in the FROM clause,
**         fill pTabList->a[].pSelect with a copy of the SELECT statement
**         that implements the view.  A copy is made of the view's SELECT
**         statement so that we can freely modify or delete that statement
**         without worrying about messing up the presistent representation
**         of the view.
**
**    (3)  Add terms to the WHERE clause to accomodate the NATURAL keyword
**         on joins and the ON and USING clause of joins.
**
**    (4)  Scan the list of columns in the result set (pEList) looking
**         for instances of the "*" operator or the TABLE.* operator.
**         If found, expand each "*" to be every column in every table
**         and TABLE.* to be every column in TABLE.
**
** Return 0 on success.  If there are problems, leave an error message
** in pParse and return non-zero.
*/
static int prepSelectStmt(Parse *pParse, Select *p){
  int i, j, k, rc;
  SrcList *pTabList;
  ExprList *pEList;
  Table *pTab;
  struct SrcList_item *pFrom;

  if( p==0 || p->pSrc==0 ) return 1;
  pTabList = p->pSrc;
  pEList = p->pEList;

  /* Make sure cursor numbers have been assigned to all entries in
  ** the FROM clause of the SELECT statement.
  */
  sqlite3SrcListAssignCursors(pParse, p->pSrc);

  /* Look up every table named in the FROM clause of the select.  If
  ** an entry of the FROM clause is a subquery instead of a table or view,
  ** then create a transient table structure to describe the subquery.
  */
  for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
    if( pFrom->pTab!=0 ){
      /* This statement has already been prepared.  There is no need
      ** to go further. */
      assert( i==0 );
      return 0;
    }
    if( pFrom->zName==0 ){
#ifndef SQLITE_OMIT_SUBQUERY
      /* A sub-query in the FROM clause of a SELECT */
      assert( pFrom->pSelect!=0 );
      if( pFrom->zAlias==0 ){
        pFrom->zAlias =
          sqlite3MPrintf("sqlite_subquery_%p_", (void*)pFrom->pSelect);
      }
      pFrom->pTab = pTab = 
        sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect);
      if( pTab==0 ){
        return 1;
      }
      /* The isTransient flag indicates that the Table structure has been
      ** dynamically allocated and may be freed at any time.  In other words,
      ** pTab is not pointing to a persistent table structure that defines
      ** part of the schema. */
      pTab->isTransient = 1;
#endif
    }else{
      /* An ordinary table or view name in the FROM clause */
      pFrom->pTab = pTab = 
        sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase);
      if( pTab==0 ){
        return 1;
      }
#ifndef SQLITE_OMIT_VIEW
      if( pTab->pSelect ){
        /* We reach here if the named table is a really a view */
        if( sqlite3ViewGetColumnNames(pParse, pTab) ){
          return 1;
        }
        /* If pFrom->pSelect!=0 it means we are dealing with a
        ** view within a view.  The SELECT structure has already been
        ** copied by the outer view so we can skip the copy step here
        ** in the inner view.
        */
        if( pFrom->pSelect==0 ){
          pFrom->pSelect = sqlite3SelectDup(pTab->pSelect);
        }
      }
#endif
    }
  }

  /* Process NATURAL keywords, and ON and USING clauses of joins.
  */
  if( sqliteProcessJoin(pParse, p) ) return 1;

  /* For every "*" that occurs in the column list, insert the names of
  ** all columns in all tables.  And for every TABLE.* insert the names
  ** of all columns in TABLE.  The parser inserted a special expression
  ** with the TK_ALL operator for each "*" that it found in the column list.
  ** The following code just has to locate the TK_ALL expressions and expand
  ** each one to the list of all columns in all tables.
  **
  ** The first loop just checks to see if there are any "*" operators
  ** that need expanding.
  */
  for(k=0; k<pEList->nExpr; k++){
    Expr *pE = pEList->a[k].pExpr;
    if( pE->op==TK_ALL ) break;
    if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL
         && pE->pLeft && pE->pLeft->op==TK_ID ) break;
  }
  rc = 0;
  if( k<pEList->nExpr ){
    /*
    ** If we get here it means the result set contains one or more "*"
    ** operators that need to be expanded.  Loop through each expression
    ** in the result set and expand them one by one.
    */
    struct ExprList_item *a = pEList->a;
    ExprList *pNew = 0;
    for(k=0; k<pEList->nExpr; k++){
      Expr *pE = a[k].pExpr;
      if( pE->op!=TK_ALL &&
           (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
        /* This particular expression does not need to be expanded.
        */
        pNew = sqlite3ExprListAppend(pNew, a[k].pExpr, 0);
        pNew->a[pNew->nExpr-1].zName = a[k].zName;
        a[k].pExpr = 0;
        a[k].zName = 0;
      }else{
        /* This expression is a "*" or a "TABLE.*" and needs to be
        ** expanded. */
        int tableSeen = 0;      /* Set to 1 when TABLE matches */
        char *zTName;            /* text of name of TABLE */
        if( pE->op==TK_DOT && pE->pLeft ){
          zTName = sqlite3NameFromToken(&pE->pLeft->token);
        }else{
          zTName = 0;
        }
        for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
          Table *pTab = pFrom->pTab;
          char *zTabName = pFrom->zAlias;
          if( zTabName==0 || zTabName[0]==0 ){ 
            zTabName = pTab->zName;
          }
          if( zTName && (zTabName==0 || zTabName[0]==0 || 
                 sqlite3StrICmp(zTName, zTabName)!=0) ){
            continue;
          }
          tableSeen = 1;
          for(j=0; j<pTab->nCol; j++){
            Expr *pExpr, *pLeft, *pRight;
            char *zName = pTab->aCol[j].zName;

            if( i>0 ){
              struct SrcList_item *pLeft = &pTabList->a[i-1];
              if( (pLeft->jointype & JT_NATURAL)!=0 &&
                        columnIndex(pLeft->pTab, zName)>=0 ){
                /* In a NATURAL join, omit the join columns from the 
                ** table on the right */
                continue;
              }
              if( sqlite3IdListIndex(pLeft->pUsing, zName)>=0 ){
                /* In a join with a USING clause, omit columns in the
                ** using clause from the table on the right. */
                continue;
              }
            }
            pRight = sqlite3Expr(TK_ID, 0, 0, 0);
            if( pRight==0 ) break;
            setToken(&pRight->token, zName);
            if( zTabName && pTabList->nSrc>1 ){
              pLeft = sqlite3Expr(TK_ID, 0, 0, 0);
              pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0);
              if( pExpr==0 ) break;
              setToken(&pLeft->token, zTabName);
              setToken(&pExpr->span, sqlite3MPrintf("%s.%s", zTabName, zName));
              pExpr->span.dyn = 1;
              pExpr->token.z = 0;
              pExpr->token.n = 0;
              pExpr->token.dyn = 0;
            }else{
              pExpr = pRight;
              pExpr->span = pExpr->token;
            }
            pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token);
          }
        }
        if( !tableSeen ){
          if( zTName ){
            sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
          }else{
            sqlite3ErrorMsg(pParse, "no tables specified");
          }
          rc = 1;
        }
        sqliteFree(zTName);
      }
    }
    sqlite3ExprListDelete(pEList);
    p->pEList = pNew;
  }
  return rc;
}

/*
** This routine recursively unlinks the Select.pSrc.a[].pTab pointers
** in a select structure.  It just sets the pointers to NULL.  This
** routine is recursive in the sense that if the Select.pSrc.a[].pSelect
** pointer is not NULL, this routine is called recursively on that pointer.
**
** This routine is called on the Select structure that defines a
** VIEW in order to undo any bindings to tables.  This is necessary
** because those tables might be DROPed by a subsequent SQL command.
** If the bindings are not removed, then the Select.pSrc->a[].pTab field
** will be left pointing to a deallocated Table structure after the
** DROP and a coredump will occur the next time the VIEW is used.
*/
#if 0
void sqlite3SelectUnbind(Select *p){
  int i;
  SrcList *pSrc = p->pSrc;
  struct SrcList_item *pItem;
  Table *pTab;
  if( p==0 ) return;
  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
    if( (pTab = pItem->pTab)!=0 ){
      if( pTab->isTransient ){
        sqlite3DeleteTable(0, pTab);
      }
      pItem->pTab = 0;
      if( pItem->pSelect ){
        sqlite3SelectUnbind(pItem->pSelect);
      }
    }
  }
}
#endif

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine associates entries in an ORDER BY expression list with
** columns in a result.  For each ORDER BY expression, the opcode of
** the top-level node is changed to TK_COLUMN and the iColumn value of
** the top-level node is filled in with column number and the iTable
** value of the top-level node is filled with iTable parameter.
**
** If there are prior SELECT clauses, they are processed first.  A match
** in an earlier SELECT takes precedence over a later SELECT.
**
** Any entry that does not match is flagged as an error.  The number
** of errors is returned.
*/
static int matchOrderbyToColumn(
  Parse *pParse,          /* A place to leave error messages */
  Select *pSelect,        /* Match to result columns of this SELECT */
  ExprList *pOrderBy,     /* The ORDER BY values to match against columns */
  int iTable,             /* Insert this value in iTable */
  int mustComplete        /* If TRUE all ORDER BYs must match */
){
  int nErr = 0;
  int i, j;
  ExprList *pEList;

  if( pSelect==0 || pOrderBy==0 ) return 1;
  if( mustComplete ){
    for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; }
  }
  if( prepSelectStmt(pParse, pSelect) ){
    return 1;
  }
  if( pSelect->pPrior ){
    if( matchOrderbyToColumn(pParse, pSelect->pPrior, pOrderBy, iTable, 0) ){
      return 1;
    }
  }
  pEList = pSelect->pEList;
  for(i=0; i<pOrderBy->nExpr; i++){
    Expr *pE = pOrderBy->a[i].pExpr;
    int iCol = -1;
    if( pOrderBy->a[i].done ) continue;
    if( sqlite3ExprIsInteger(pE, &iCol) ){
      if( iCol<=0 || iCol>pEList->nExpr ){
        sqlite3ErrorMsg(pParse,
          "ORDER BY position %d should be between 1 and %d",
          iCol, pEList->nExpr);
        nErr++;
        break;
      }
      if( !mustComplete ) continue;
      iCol--;
    }
    for(j=0; iCol<0 && j<pEList->nExpr; j++){
      if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
        char *zName, *zLabel;
        zName = pEList->a[j].zName;
        zLabel = sqlite3NameFromToken(&pE->token);
        assert( zLabel!=0 );
        if( sqlite3StrICmp(zName, zLabel)==0 ){ 
          iCol = j;
        }
        sqliteFree(zLabel);
      }
      if( iCol<0 && sqlite3ExprCompare(pE, pEList->a[j].pExpr) ){
        iCol = j;
      }
    }
    if( iCol>=0 ){
      pE->op = TK_COLUMN;
      pE->iColumn = iCol;
      pE->iTable = iTable;
      pE->iAgg = -1;
      pOrderBy->a[i].done = 1;
    }
    if( iCol<0 && mustComplete ){
      sqlite3ErrorMsg(pParse,
        "ORDER BY term number %d does not match any result column", i+1);
      nErr++;
      break;
    }
  }
  return nErr;  
}
#endif /* #ifndef SQLITE_OMIT_COMPOUND_SELECT */

/*
** Get a VDBE for the given parser context.  Create a new one if necessary.
** If an error occurs, return NULL and leave a message in pParse.
*/
Vdbe *sqlite3GetVdbe(Parse *pParse){
  Vdbe *v = pParse->pVdbe;
  if( v==0 ){
    v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
  }
  return v;
}

/*
** Compute the iLimit and iOffset fields of the SELECT based on the
** pLimit and pOffset expressions.  nLimit and nOffset hold the expressions
** that appear in the original SQL statement after the LIMIT and OFFSET
** keywords.  Or NULL if those keywords are omitted. iLimit and iOffset 
** are the integer memory register numbers for counters used to compute 
** the limit and offset.  If there is no limit and/or offset, then 
** iLimit and iOffset are negative.
**
** This routine changes the values if iLimit and iOffset only if
** a limit or offset is defined by nLimit and nOffset.  iLimit and
** iOffset should have been preset to appropriate default values
** (usually but not always -1) prior to calling this routine.
** Only if nLimit>=0 or nOffset>0 do the limit registers get
** redefined.  The UNION ALL operator uses this property to force
** the reuse of the same limit and offset registers across multiple
** SELECT statements.
*/
static void computeLimitRegisters(Parse *pParse, Select *p){
  /* 
  ** "LIMIT -1" always shows all rows.  There is some
  ** contraversy about what the correct behavior should be.
  ** The current implementation interprets "LIMIT 0" to mean
  ** no rows.
  */
  if( p->pLimit ){
    int iMem = pParse->nMem++;
    Vdbe *v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pLimit);
    sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
    VdbeComment((v, "# LIMIT counter"));
    p->iLimit = iMem;
  }
  if( p->pOffset ){
    int iMem = pParse->nMem++;
    Vdbe *v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pOffset);
    sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
    VdbeComment((v, "# OFFSET counter"));
    p->iOffset = iMem;
  }
}

/*
** Generate VDBE instructions that will open a transient table that
** will be used for an index or to store keyed results for a compound
** select.  In other words, open a transient table that needs a
** KeyInfo structure.  The number of columns in the KeyInfo is determined
** by the result set of the SELECT statement in the second argument.
**
** Specifically, this routine is called to open an index table for
** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not 
** UNION ALL).
**
** Make the new table a KeyAsData table if keyAsData is true.
**
** The value returned is the address of the OP_OpenTemp instruction.
*/
static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){
  KeyInfo *pKeyInfo;
  int nColumn;
  sqlite3 *db = pParse->db;
  int i;
  Vdbe *v = pParse->pVdbe;
  int addr;

  if( prepSelectStmt(pParse, p) ){
    return 0;
  }
  nColumn = p->pEList->nExpr;
  pKeyInfo = sqliteMalloc( sizeof(*pKeyInfo)+nColumn*sizeof(CollSeq*) );
  if( pKeyInfo==0 ) return 0;
  pKeyInfo->enc = db->enc;
  pKeyInfo->nField = nColumn;
  for(i=0; i<nColumn; i++){
    pKeyInfo->aColl[i] = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr);
    if( !pKeyInfo->aColl[i] ){
      pKeyInfo->aColl[i] = db->pDfltColl;
    }
  }
  addr = sqlite3VdbeOp3(v, OP_OpenTemp, iTab, 0, 
      (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
  if( keyAsData ){
    sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
  }
  return addr;
}

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Add the address "addr" to the set of all OpenTemp opcode addresses
** that are being accumulated in p->ppOpenTemp.
*/
static int multiSelectOpenTempAddr(Select *p, int addr){
  IdList *pList = *p->ppOpenTemp = sqlite3IdListAppend(*p->ppOpenTemp, 0);
  if( pList==0 ){
    return SQLITE_NOMEM;
  }
  pList->a[pList->nId-1].idx = addr;
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Return the appropriate collating sequence for the iCol-th column of
** the result set for the compound-select statement "p".  Return NULL if
** the column has no default collating sequence.
**
** The collating sequence for the compound select is taken from the
** left-most term of the select that has a collating sequence.
*/
static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
  CollSeq *pRet;
  if( p->pPrior ){
    pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
  }else{
    pRet = 0;
  }
  if( pRet==0 ){
    pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
  }
  return pRet;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine is called to process a query that is really the union
** or intersection of two or more separate queries.
**
** "p" points to the right-most of the two queries.  the query on the
** left is p->pPrior.  The left query could also be a compound query
** in which case this routine will be called recursively. 
**
** The results of the total query are to be written into a destination
** of type eDest with parameter iParm.
**
** Example 1:  Consider a three-way compound SQL statement.
**
**     SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
**
** This statement is parsed up as follows:
**
**     SELECT c FROM t3
**      |
**      `----->  SELECT b FROM t2
**                |
**                `------>  SELECT a FROM t1
**
** The arrows in the diagram above represent the Select.pPrior pointer.
** So if this routine is called with p equal to the t3 query, then
** pPrior will be the t2 query.  p->op will be TK_UNION in this case.
**
** Notice that because of the way SQLite parses compound SELECTs, the
** individual selects always group from left to right.
*/
static int multiSelect(
  Parse *pParse,        /* Parsing context */
  Select *p,            /* The right-most of SELECTs to be coded */
  int eDest,            /* \___  Store query results as specified */
  int iParm,            /* /     by these two parameters.         */
  char *aff             /* If eDest is SRT_Union, the affinity string */
){
  int rc = SQLITE_OK;   /* Success code from a subroutine */
  Select *pPrior;       /* Another SELECT immediately to our left */
  Vdbe *v;              /* Generate code to this VDBE */
  IdList *pOpenTemp = 0;/* OP_OpenTemp opcodes that need a KeyInfo */
  int aAddr[5];         /* Addresses of SetNumColumns operators */
  int nAddr = 0;        /* Number used */
  int nCol;             /* Number of columns in the result set */

  /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
  ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
  */
  if( p==0 || p->pPrior==0 ){
    rc = 1;
    goto multi_select_end;
  }
  pPrior = p->pPrior;
  if( pPrior->pOrderBy ){
    sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
      selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }
  if( pPrior->pLimit ){
    sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
      selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

  /* Make sure we have a valid query engine.  If not, create a new one.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    rc = 1;
    goto multi_select_end;
  }

  /* If *p this is the right-most select statement, then initialize
  ** p->ppOpenTemp to point to pOpenTemp.  If *p is not the right most
  ** statement then p->ppOpenTemp will have already been initialized
  ** by a prior call to this same procedure.  Pass along the pOpenTemp
  ** pointer to pPrior, the next statement to our left.
  */
  if( p->ppOpenTemp==0 ){
    p->ppOpenTemp = &pOpenTemp;
  }
  pPrior->ppOpenTemp = p->ppOpenTemp;

  /* Create the destination temporary table if necessary
  */
  if( eDest==SRT_TempTable ){
    assert( p->pEList );
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
    assert( nAddr==0 );
    aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, 0);
    eDest = SRT_Table;
  }

  /* Generate code for the left and right SELECT statements.
  */
  switch( p->op ){
    case TK_ALL: {
      if( p->pOrderBy==0 ){
        assert( !pPrior->pLimit );
        pPrior->pLimit = p->pLimit;
        pPrior->pOffset = p->pOffset;
        rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff);
        if( rc ){
          goto multi_select_end;
        }
        p->pPrior = 0;
        p->iLimit = pPrior->iLimit;
        p->iOffset = pPrior->iOffset;
        p->pLimit = 0;
        p->pOffset = 0;
        rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff);
        p->pPrior = pPrior;
        if( rc ){
          goto multi_select_end;
        }
        break;
      }
      /* For UNION ALL ... ORDER BY fall through to the next case */
    }
    case TK_EXCEPT:
    case TK_UNION: {
      int unionTab;    /* Cursor number of the temporary table holding result */
      int op = 0;      /* One of the SRT_ operations to apply to self */
      int priorOp;     /* The SRT_ operation to apply to prior selects */
      Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
      ExprList *pOrderBy;     /* The ORDER BY clause for the right SELECT */
      int addr;

      priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
      if( eDest==priorOp && p->pOrderBy==0 && !p->pLimit && !p->pOffset ){
        /* We can reuse a temporary table generated by a SELECT to our
        ** right.
        */
        unionTab = iParm;
      }else{
        /* We will need to create our own temporary table to hold the
        ** intermediate results.
        */
        unionTab = pParse->nTab++;
        if( p->pOrderBy 
        && matchOrderbyToColumn(pParse, p, p->pOrderBy, unionTab, 1) ){
          rc = 1;
          goto multi_select_end;
        }
        addr = sqlite3VdbeAddOp(v, OP_OpenTemp, unionTab, 0);
        if( p->op!=TK_ALL ){
          rc = multiSelectOpenTempAddr(p, addr);
          if( rc!=SQLITE_OK ){
            goto multi_select_end;
          }
          sqlite3VdbeAddOp(v, OP_KeyAsData, unionTab, 1);
        }
	assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
        aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, unionTab, 0);
        assert( p->pEList );
      }

      /* Code the SELECT statements to our left
      */
      assert( !pPrior->pOrderBy );
      rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff);
      if( rc ){
        goto multi_select_end;
      }

      /* Code the current SELECT statement
      */
      switch( p->op ){
         case TK_EXCEPT:  op = SRT_Except;   break;
         case TK_UNION:   op = SRT_Union;    break;
         case TK_ALL:     op = SRT_Table;    break;
      }
      p->pPrior = 0;
      pOrderBy = p->pOrderBy;
      p->pOrderBy = 0;
      pLimit = p->pLimit;
      p->pLimit = 0;
      pOffset = p->pOffset;
      p->pOffset = 0;
      rc = sqlite3Select(pParse, p, op, unionTab, 0, 0, 0, aff);
      p->pPrior = pPrior;
      p->pOrderBy = pOrderBy;
      sqlite3ExprDelete(p->pLimit);
      p->pLimit = pLimit;
      p->pOffset = pOffset;
      p->iLimit = -1;
      p->iOffset = -1;
      if( rc ){
        goto multi_select_end;
      }


      /* Convert the data in the temporary table into whatever form
      ** it is that we currently need.
      */      
      if( eDest!=priorOp || unionTab!=iParm ){
        int iCont, iBreak, iStart;
        assert( p->pEList );
        if( eDest==SRT_Callback ){
          generateColumnNames(pParse, 0, p->pEList);
        }
        iBreak = sqlite3VdbeMakeLabel(v);
        iCont = sqlite3VdbeMakeLabel(v);
        sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);
        computeLimitRegisters(pParse, p);
        iStart = sqlite3VdbeCurrentAddr(v);
        rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak, 0);
        if( rc ){
          rc = 1;
          goto multi_select_end;
        }
        sqlite3VdbeResolveLabel(v, iCont);
        sqlite3VdbeAddOp(v, OP_Next, unionTab, iStart);
        sqlite3VdbeResolveLabel(v, iBreak);
        sqlite3VdbeAddOp(v, OP_Close, unionTab, 0);
      }
      break;
    }
    case TK_INTERSECT: {
      int tab1, tab2;
      int iCont, iBreak, iStart;
      Expr *pLimit, *pOffset;
      int addr;

      /* INTERSECT is different from the others since it requires
      ** two temporary tables.  Hence it has its own case.  Begin
      ** by allocating the tables we will need.
      */
      tab1 = pParse->nTab++;
      tab2 = pParse->nTab++;
      if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){
        rc = 1;
        goto multi_select_end;
      }

      addr = sqlite3VdbeAddOp(v, OP_OpenTemp, tab1, 0);
      rc = multiSelectOpenTempAddr(p, addr);
      if( rc!=SQLITE_OK ){
        goto multi_select_end;
      }
      sqlite3VdbeAddOp(v, OP_KeyAsData, tab1, 1);
      assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
      aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab1, 0);
      assert( p->pEList );

      /* Code the SELECTs to our left into temporary table "tab1".
      */
      rc = sqlite3Select(pParse, pPrior, SRT_Union, tab1, 0, 0, 0, aff);
      if( rc ){
        goto multi_select_end;
      }

      /* Code the current SELECT into temporary table "tab2"
      */
      addr = sqlite3VdbeAddOp(v, OP_OpenTemp, tab2, 0);
      rc = multiSelectOpenTempAddr(p, addr);
      if( rc!=SQLITE_OK ){
        goto multi_select_end;
      }
      sqlite3VdbeAddOp(v, OP_KeyAsData, tab2, 1);
      assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
      aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab2, 0);
      p->pPrior = 0;
      pLimit = p->pLimit;
      p->pLimit = 0;
      pOffset = p->pOffset;
      p->pOffset = 0;
      rc = sqlite3Select(pParse, p, SRT_Union, tab2, 0, 0, 0, aff);
      p->pPrior = pPrior;
      sqlite3ExprDelete(p->pLimit);
      p->pLimit = pLimit;
      p->pOffset = pOffset;
      if( rc ){
        goto multi_select_end;
      }

      /* Generate code to take the intersection of the two temporary
      ** tables.
      */
      assert( p->pEList );
      if( eDest==SRT_Callback ){
        generateColumnNames(pParse, 0, p->pEList);
      }
      iBreak = sqlite3VdbeMakeLabel(v);
      iCont = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);
      computeLimitRegisters(pParse, p);
      iStart = sqlite3VdbeAddOp(v, OP_FullKey, tab1, 0);
      sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
      rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak, 0);
      if( rc ){
        rc = 1;
        goto multi_select_end;
      }
      sqlite3VdbeResolveLabel(v, iCont);
      sqlite3VdbeAddOp(v, OP_Next, tab1, iStart);
      sqlite3VdbeResolveLabel(v, iBreak);
      sqlite3VdbeAddOp(v, OP_Close, tab2, 0);
      sqlite3VdbeAddOp(v, OP_Close, tab1, 0);
      break;
    }
  }

  /* Make sure all SELECTs in the statement have the same number of elements
  ** in their result sets.
  */
  assert( p->pEList && pPrior->pEList );
  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

  /* Set the number of columns in temporary tables
  */
  nCol = p->pEList->nExpr;
  while( nAddr>0 ){
    nAddr--;
    sqlite3VdbeChangeP2(v, aAddr[nAddr], nCol);
  }

  /* Compute collating sequences used by either the ORDER BY clause or
  ** by any temporary tables needed to implement the compound select.
  ** Attach the KeyInfo structure to all temporary tables.  Invoke the
  ** ORDER BY processing if there is an ORDER BY clause.
  **
  ** This section is run by the right-most SELECT statement only.
  ** SELECT statements to the left always skip this part.  The right-most
  ** SELECT might also skip this part if it has no ORDER BY clause and
  ** no temp tables are required.
  */
  if( p->pOrderBy || (pOpenTemp && pOpenTemp->nId>0) ){
    int i;                        /* Loop counter */
    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */

    assert( p->ppOpenTemp == &pOpenTemp );
    pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nCol*sizeof(CollSeq*));
    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;
    }

    pKeyInfo->enc = pParse->db->enc;
    pKeyInfo->nField = nCol;

    for(i=0; i<nCol; i++){
      pKeyInfo->aColl[i] = multiSelectCollSeq(pParse, p, i);
      if( !pKeyInfo->aColl[i] ){
        pKeyInfo->aColl[i] = pParse->db->pDfltColl;
      }
    }

    for(i=0; pOpenTemp && i<pOpenTemp->nId; i++){
      int p3type = (i==0?P3_KEYINFO_HANDOFF:P3_KEYINFO);
      int addr = pOpenTemp->a[i].idx;
      sqlite3VdbeChangeP3(v, addr, (char *)pKeyInfo, p3type);
    }

    if( p->pOrderBy ){
      struct ExprList_item *pOrderByTerm = p->pOrderBy->a;
      for(i=0; i<p->pOrderBy->nExpr; i++, pOrderByTerm++){
        Expr *pExpr = pOrderByTerm->pExpr;
        char *zName = pOrderByTerm->zName;
        assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol );
        /* assert( !pExpr->pColl ); */
        if( zName ){
          pExpr->pColl = sqlite3LocateCollSeq(pParse, zName, -1);
        }else{
          pExpr->pColl = pKeyInfo->aColl[pExpr->iColumn];
        }
      }
      generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm);
    }

    if( !pOpenTemp ){
      /* This happens for UNION ALL ... ORDER BY */
      sqliteFree(pKeyInfo);
    }
  }

multi_select_end:
  if( pOpenTemp ){
    sqlite3IdListDelete(pOpenTemp);
  }
  p->ppOpenTemp = 0;
  return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

#ifndef SQLITE_OMIT_VIEW
/*
** Scan through the expression pExpr.  Replace every reference to
** a column in table number iTable with a copy of the iColumn-th
** entry in pEList.  (But leave references to the ROWID column 
** unchanged.)
**
** This routine is part of the flattening procedure.  A subquery
** whose result set is defined by pEList appears as entry in the
** FROM clause of a SELECT such that the VDBE cursor assigned to that
** FORM clause entry is iTable.  This routine make the necessary 
** changes to pExpr so that it refers directly to the source table
** of the subquery rather the result set of the subquery.
*/
static void substExprList(ExprList*,int,ExprList*);  /* Forward Decl */
static void substSelect(Select *, int, ExprList *);  /* Forward Decl */
static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){
  if( pExpr==0 ) return;
  if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
    if( pExpr->iColumn<0 ){
      pExpr->op = TK_NULL;
    }else{
      Expr *pNew;
      assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
      assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 );
      pNew = pEList->a[pExpr->iColumn].pExpr;
      assert( pNew!=0 );
      pExpr->op = pNew->op;
      assert( pExpr->pLeft==0 );
      pExpr->pLeft = sqlite3ExprDup(pNew->pLeft);
      assert( pExpr->pRight==0 );
      pExpr->pRight = sqlite3ExprDup(pNew->pRight);
      assert( pExpr->pList==0 );
      pExpr->pList = sqlite3ExprListDup(pNew->pList);
      pExpr->iTable = pNew->iTable;
      pExpr->iColumn = pNew->iColumn;
      pExpr->iAgg = pNew->iAgg;
      sqlite3TokenCopy(&pExpr->token, &pNew->token);
      sqlite3TokenCopy(&pExpr->span, &pNew->span);
      pExpr->pSelect = sqlite3SelectDup(pNew->pSelect);
      pExpr->flags = pNew->flags;
    }
  }else{
    substExpr(pExpr->pLeft, iTable, pEList);
    substExpr(pExpr->pRight, iTable, pEList);
    substSelect(pExpr->pSelect, iTable, pEList);
    substExprList(pExpr->pList, iTable, pEList);
  }
}
static void substExprList(ExprList *pList, int iTable, ExprList *pEList){
  int i;
  if( pList==0 ) return;
  for(i=0; i<pList->nExpr; i++){
    substExpr(pList->a[i].pExpr, iTable, pEList);
  }
}
static void substSelect(Select *p, int iTable, ExprList *pEList){
  if( !p ) return;
  substExprList(p->pEList, iTable, pEList);
  substExprList(p->pGroupBy, iTable, pEList);
  substExprList(p->pOrderBy, iTable, pEList);
  substExpr(p->pHaving, iTable, pEList);
  substExpr(p->pWhere, iTable, pEList);
}
#endif /* !defined(SQLITE_OMIT_VIEW) */

#ifndef SQLITE_OMIT_VIEW
/*
** This routine attempts to flatten subqueries in order to speed
** execution.  It returns 1 if it makes changes and 0 if no flattening
** occurs.
**
** To understand the concept of flattening, consider the following
** query:
**
**     SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
**
** The default way of implementing this query is to execute the
** subquery first and store the results in a temporary table, then
** run the outer query on that temporary table.  This requires two
** passes over the data.  Furthermore, because the temporary table
** has no indices, the WHERE clause on the outer query cannot be
** optimized.
**
** This routine attempts to rewrite queries such as the above into
** a single flat select, like this:
**
**     SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
**
** The code generated for this simpification gives the same result
** but only has to scan the data once.  And because indices might 
** exist on the table t1, a complete scan of the data might be
** avoided.
**
** Flattening is only attempted if all of the following are true:
**
**   (1)  The subquery and the outer query do not both use aggregates.
**
**   (2)  The subquery is not an aggregate or the outer query is not a join.
**
**   (3)  The subquery is not the right operand of a left outer join, or
**        the subquery is not itself a join.  (Ticket #306)
**
**   (4)  The subquery is not DISTINCT or the outer query is not a join.
**
**   (5)  The subquery is not DISTINCT or the outer query does not use
**        aggregates.
**
**   (6)  The subquery does not use aggregates or the outer query is not
**        DISTINCT.
**
**   (7)  The subquery has a FROM clause.
**
**   (8)  The subquery does not use LIMIT or the outer query is not a join.
**
**   (9)  The subquery does not use LIMIT or the outer query does not use
**        aggregates.
**
**  (10)  The subquery does not use aggregates or the outer query does not
**        use LIMIT.
**
**  (11)  The subquery and the outer query do not both have ORDER BY clauses.
**
**  (12)  The subquery is not the right term of a LEFT OUTER JOIN or the
**        subquery has no WHERE clause.  (added by ticket #350)
**
** In this routine, the "p" parameter is a pointer to the outer query.
** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
**
** If flattening is not attempted, this routine is a no-op and returns 0.
** If flattening is attempted this routine returns 1.
**
** All of the expression analysis must occur on both the outer query and
** the subquery before this routine runs.
*/
static int flattenSubquery(
  Parse *pParse,       /* The parsing context */
  Select *p,           /* The parent or outer SELECT statement */
  int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */
  int isAgg,           /* True if outer SELECT uses aggregate functions */
  int subqueryIsAgg    /* True if the subquery uses aggregate functions */
){
  Select *pSub;       /* The inner query or "subquery" */
  SrcList *pSrc;      /* The FROM clause of the outer query */
  SrcList *pSubSrc;   /* The FROM clause of the subquery */
  ExprList *pList;    /* The result set of the outer query */
  int iParent;        /* VDBE cursor number of the pSub result set temp table */
  int i;              /* Loop counter */
  Expr *pWhere;                    /* The WHERE clause */
  struct SrcList_item *pSubitem;   /* The subquery */

  /* Check to see if flattening is permitted.  Return 0 if not.
  */
  if( p==0 ) return 0;
  pSrc = p->pSrc;
  assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
  pSubitem = &pSrc->a[iFrom];
  pSub = pSubitem->pSelect;
  assert( pSub!=0 );
  if( isAgg && subqueryIsAgg ) return 0;
  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;
  pSubSrc = pSub->pSrc;
  assert( pSubSrc );
  if( (pSub->pLimit && p->pLimit) || pSub->pOffset || 
      (pSub->pLimit && isAgg) ) return 0;
  if( pSubSrc->nSrc==0 ) return 0;
  if( pSub->isDistinct && (pSrc->nSrc>1 || isAgg) ){
     return 0;
  }
  if( p->isDistinct && subqueryIsAgg ) return 0;
  if( p->pOrderBy && pSub->pOrderBy ) return 0;

  /* Restriction 3:  If the subquery is a join, make sure the subquery is 
  ** not used as the right operand of an outer join.  Examples of why this
  ** is not allowed:
  **
  **         t1 LEFT OUTER JOIN (t2 JOIN t3)
  **
  ** If we flatten the above, we would get
  **
  **         (t1 LEFT OUTER JOIN t2) JOIN t3
  **
  ** which is not at all the same thing.
  */
  if( pSubSrc->nSrc>1 && iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 ){
    return 0;
  }

  /* Restriction 12:  If the subquery is the right operand of a left outer
  ** join, make sure the subquery has no WHERE clause.
  ** An examples of why this is not allowed:
  **
  **         t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
  **
  ** If we flatten the above, we would get
  **
  **         (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
  **
  ** But the t2.x>0 test will always fail on a NULL row of t2, which
  ** effectively converts the OUTER JOIN into an INNER JOIN.
  */
  if( iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 
      && pSub->pWhere!=0 ){
    return 0;
  }

  /* If we reach this point, it means flattening is permitted for the
  ** iFrom-th entry of the FROM clause in the outer query.
  */

  /* Move all of the FROM elements of the subquery into the
  ** the FROM clause of the outer query.  Before doing this, remember
  ** the cursor number for the original outer query FROM element in
  ** iParent.  The iParent cursor will never be used.  Subsequent code
  ** will scan expressions looking for iParent references and replace
  ** those references with expressions that resolve to the subquery FROM
  ** elements we are now copying in.
  */
  iParent = pSubitem->iCursor;
  {
    int nSubSrc = pSubSrc->nSrc;
    int jointype = pSubitem->jointype;
    Table *pTab = pSubitem->pTab;

    if( pTab && pTab->isTransient ){
      sqlite3DeleteTable(0, pSubitem->pTab);
    }
    sqliteFree(pSubitem->zDatabase);
    sqliteFree(pSubitem->zName);
    sqliteFree(pSubitem->zAlias);
    if( nSubSrc>1 ){
      int extra = nSubSrc - 1;
      for(i=1; i<nSubSrc; i++){
        pSrc = sqlite3SrcListAppend(pSrc, 0, 0);
      }
      p->pSrc = pSrc;
      for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
        pSrc->a[i] = pSrc->a[i-extra];
      }
    }
    for(i=0; i<nSubSrc; i++){
      pSrc->a[i+iFrom] = pSubSrc->a[i];
      memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
    }
    pSrc->a[iFrom+nSubSrc-1].jointype = jointype;
  }

  /* Now begin substituting subquery result set expressions for 
  ** references to the iParent in the outer query.
  ** 
  ** Example:
  **
  **   SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
  **   \                     \_____________ subquery __________/          /
  **    \_____________________ outer query ______________________________/
  **
  ** We look at every expression in the outer query and every place we see
  ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
  */
  substExprList(p->pEList, iParent, pSub->pEList);
  pList = p->pEList;
  for(i=0; i<pList->nExpr; i++){
    Expr *pExpr;
    if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
      pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
    }
  }
  if( isAgg ){
    substExprList(p->pGroupBy, iParent, pSub->pEList);
    substExpr(p->pHaving, iParent, pSub->pEList);
  }
  if( pSub->pOrderBy ){
    assert( p->pOrderBy==0 );
    p->pOrderBy = pSub->pOrderBy;
    pSub->pOrderBy = 0;
  }else if( p->pOrderBy ){
    substExprList(p->pOrderBy, iParent, pSub->pEList);
  }
  if( pSub->pWhere ){
    pWhere = sqlite3ExprDup(pSub->pWhere);
  }else{
    pWhere = 0;
  }
  if( subqueryIsAgg ){
    assert( p->pHaving==0 );
    p->pHaving = p->pWhere;
    p->pWhere = pWhere;
    substExpr(p->pHaving, iParent, pSub->pEList);
    p->pHaving = sqlite3ExprAnd(p->pHaving, sqlite3ExprDup(pSub->pHaving));
    assert( p->pGroupBy==0 );
    p->pGroupBy = sqlite3ExprListDup(pSub->pGroupBy);
  }else{
    substExpr(p->pWhere, iParent, pSub->pEList);
    p->pWhere = sqlite3ExprAnd(p->pWhere, pWhere);
  }

  /* The flattened query is distinct if either the inner or the
  ** outer query is distinct. 
  */
  p->isDistinct = p->isDistinct || pSub->isDistinct;

  /*
  ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
  */
  if( pSub->pLimit ){
    p->pLimit = pSub->pLimit;
    pSub->pLimit = 0;
  }

  /* Finially, delete what is left of the subquery and return
  ** success.
  */
  sqlite3SelectDelete(pSub);
  return 1;
}
#endif /* SQLITE_OMIT_VIEW */

/*
** Analyze the SELECT statement passed in as an argument to see if it
** is a simple min() or max() query.  If it is and this query can be
** satisfied using a single seek to the beginning or end of an index,
** then generate the code for this SELECT and return 1.  If this is not a 
** simple min() or max() query, then return 0;
**
** A simply min() or max() query looks like this:
**
**    SELECT min(a) FROM table;
**    SELECT max(a) FROM table;
**
** The query may have only a single table in its FROM argument.  There
** can be no GROUP BY or HAVING or WHERE clauses.  The result set must
** be the min() or max() of a single column of the table.  The column
** in the min() or max() function must be indexed.
**
** The parameters to this routine are the same as for sqlite3Select().
** See the header comment on that routine for additional information.
*/
static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
  Expr *pExpr;
  int iCol;
  Table *pTab;
  Index *pIdx;
  int base;
  Vdbe *v;
  int seekOp;
  int cont;
  ExprList *pEList, *pList, eList;
  struct ExprList_item eListItem;
  SrcList *pSrc;

  /* Check to see if this query is a simple min() or max() query.  Return
  ** zero if it is  not.
  */
  if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
  pSrc = p->pSrc;
  if( pSrc->nSrc!=1 ) return 0;
  pEList = p->pEList;
  if( pEList->nExpr!=1 ) return 0;
  pExpr = pEList->a[0].pExpr;
  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
  pList = pExpr->pList;
  if( pList==0 || pList->nExpr!=1 ) return 0;
  if( pExpr->token.n!=3 ) return 0;
  if( sqlite3StrNICmp(pExpr->token.z,"min",3)==0 ){
    seekOp = OP_Rewind;
  }else if( sqlite3StrNICmp(pExpr->token.z,"max",3)==0 ){
    seekOp = OP_Last;
  }else{
    return 0;
  }
  pExpr = pList->a[0].pExpr;
  if( pExpr->op!=TK_COLUMN ) return 0;
  iCol = pExpr->iColumn;
  pTab = pSrc->a[0].pTab;

  /* If we get to here, it means the query is of the correct form.
  ** Check to make sure we have an index and make pIdx point to the
  ** appropriate index.  If the min() or max() is on an INTEGER PRIMARY
  ** key column, no index is necessary so set pIdx to NULL.  If no
  ** usable index is found, return 0.
  */
  if( iCol<0 ){
    pIdx = 0;
  }else{
    CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pIdx->nColumn>=1 );
      if( pIdx->aiColumn[0]==iCol && pIdx->keyInfo.aColl[0]==pColl ) break;
    }
    if( pIdx==0 ) return 0;
  }

  /* Identify column types if we will be using the callback.  This
  ** step is skipped if the output is going to a table or a memory cell.
  ** The column names have already been generated in the calling function.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return 0;

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_TempTable ){
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, 1);
  }

  /* Generating code to find the min or the max.  Basically all we have
  ** to do is find the first or the last entry in the chosen index.  If
  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
  ** or last entry in the main table.
  */
  sqlite3CodeVerifySchema(pParse, pTab->iDb);
  base = pSrc->a[0].iCursor;
  computeLimitRegisters(pParse, p);
  if( pSrc->a[0].pSelect==0 ){
    sqlite3OpenTableForReading(v, base, pTab);
  }
  cont = sqlite3VdbeMakeLabel(v);
  if( pIdx==0 ){
    sqlite3VdbeAddOp(v, seekOp, base, 0);
  }else{
    /* Even though the cursor used to open the index here is closed
    ** as soon as a single value has been read from it, allocate it
    ** using (pParse->nTab++) to prevent the cursor id from being 
    ** reused. This is important for statements of the form 
    ** "INSERT INTO x SELECT max() FROM x".
    */
    int iIdx;
    iIdx = pParse->nTab++;
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum,
                   (char*)&pIdx->keyInfo, P3_KEYINFO);
    if( seekOp==OP_Rewind ){
      sqlite3VdbeAddOp(v, OP_String, 0, 0);
      sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
      seekOp = OP_MoveGt;
    }
    sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
  }
  eList.nExpr = 1;
  memset(&eListItem, 0, sizeof(eListItem));
  eList.a = &eListItem;
  eList.a[0].pExpr = pExpr;
  selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont, 0);
  sqlite3VdbeResolveLabel(v, cont);
  sqlite3VdbeAddOp(v, OP_Close, base, 0);
  
  return 1;
}

/*
** Analyze and ORDER BY or GROUP BY clause in a SELECT statement.  Return
** the number of errors seen.
**
** An ORDER BY or GROUP BY is a list of expressions.  If any expression
** is an integer constant, then that expression is replaced by the
** corresponding entry in the result set.
*/
static int processOrderGroupBy(
  NameContext *pNC,     /* Name context of the SELECT statement. */
  ExprList *pOrderBy,   /* The ORDER BY or GROUP BY clause to be processed */
  const char *zType     /* Either "ORDER" or "GROUP", as appropriate */
){
  int i;
  ExprList *pEList = pNC->pEList;     /* The result set of the SELECT */
  Parse *pParse = pNC->pParse;     /* The result set of the SELECT */
  assert( pEList );

  if( pOrderBy==0 ) return 0;
  for(i=0; i<pOrderBy->nExpr; i++){
    int iCol;
    Expr *pE = pOrderBy->a[i].pExpr;
    if( sqlite3ExprIsInteger(pE, &iCol) ){
      if( iCol>0 && iCol<=pEList->nExpr ){
        sqlite3ExprDelete(pE);
        pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);
      }else{
        sqlite3ErrorMsg(pParse, 
           "%s BY column number %d out of range - should be "
           "between 1 and %d", zType, iCol, pEList->nExpr);
        return 1;
      }
    }
    if( sqlite3ExprResolveNames(pNC, pE) ){
      return 1;
    }
    if( sqlite3ExprIsConstant(pE) ){
      sqlite3ErrorMsg(pParse,
          "%s BY terms must not be non-integer constants", zType);
      return 1;
    }
  }
  return 0;
}

/*
** This routine resolves any names used in the result set of the
** supplied SELECT statement. If the SELECT statement being resolved
** is a sub-select, then pOuterNC is a pointer to the NameContext 
** of the parent SELECT.
*/
int sqlite3SelectResolve(
  Parse *pParse,         /* The parser context */
  Select *p,             /* The SELECT statement being coded. */
  NameContext *pOuterNC  /* The outer name context. May be NULL. */
){
  ExprList *pEList;          /* Result set. */
  int i;                     /* For-loop variable used in multiple places */
  NameContext sNC;           /* Local name-context */

  /* If this routine has run before, return immediately. */
  if( p->isResolved ){
    assert( !pOuterNC );
    return SQLITE_OK;
  }
  p->isResolved = 1;

  /* If there have already been errors, do nothing. */
  if( pParse->nErr>0 ){
    return SQLITE_ERROR;
  }

  /* Prepare the select statement. This call will allocate all cursors
  ** required to handle the tables and subqueries in the FROM clause.
  */
  if( prepSelectStmt(pParse, p) ){
    return SQLITE_ERROR;
  }

  /* Resolve the expressions in the LIMIT and OFFSET clauses. These
  ** are not allowed to refer to any names, so pass an empty NameContext.
  */
  sNC.pParse = pParse;
  sNC.hasAgg = 0;
  sNC.nErr = 0;
  sNC.nRef = 0;
  sNC.pEList = 0;
  sNC.allowAgg = 0;
  sNC.pSrcList = 0;
  sNC.pNext = 0;
  if( sqlite3ExprResolveNames(&sNC, p->pLimit) ||
      sqlite3ExprResolveNames(&sNC, p->pOffset) ){
    return SQLITE_ERROR;
  }

  /* Set up the local name-context to pass to ExprResolveNames() to
  ** resolve the expression-list.
  */
  sNC.allowAgg = 1;
  sNC.pSrcList = p->pSrc;
  sNC.pNext = pOuterNC;

  /* NameContext.nDepth stores the depth of recursion for this query. For
  ** an outer query (e.g. SELECT * FROM sqlite_master) this is 1. For
  ** a subquery it is 2. For a subquery of a subquery, 3. And so on. 
  ** Parse.nMaxDepth is the maximum depth for any subquery resolved so
  ** far. This is used to determine the number of aggregate contexts
  ** required at runtime.
  */
  sNC.nDepth = (pOuterNC?pOuterNC->nDepth+1:1);
  if( sNC.nDepth>pParse->nMaxDepth ){
    pParse->nMaxDepth = sNC.nDepth;
  }

  /* Resolve names in the result set. */
  pEList = p->pEList;
  if( !pEList ) return SQLITE_ERROR;
  for(i=0; i<pEList->nExpr; i++){
    Expr *pX = pEList->a[i].pExpr;
    if( sqlite3ExprResolveNames(&sNC, pX) ){
      return SQLITE_ERROR;
    }
  }

  /* If there are no aggregate functions in the result-set, and no GROUP BY 
  ** expression, do not allow aggregates in any of the other expressions.
  */
  assert( !p->isAgg );
  if( p->pGroupBy || sNC.hasAgg ){
    p->isAgg = 1;
  }else{
    sNC.allowAgg = 0;
  }

  /* If a HAVING clause is present, then there must be a GROUP BY clause.
  */
  if( p->pHaving && !p->pGroupBy ){
    sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
    return SQLITE_ERROR;
  }

  /* Add the expression list to the name-context before parsing the
  ** other expressions in the SELECT statement. This is so that
  ** expressions in the WHERE clause (etc.) can refer to expressions by
  ** aliases in the result set.
  **
  ** Minor point: If this is the case, then the expression will be
  ** re-evaluated for each reference to it.
  */
  sNC.pEList = p->pEList;
  if( sqlite3ExprResolveNames(&sNC, p->pWhere) ||
      sqlite3ExprResolveNames(&sNC, p->pHaving) ||
      processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") ||
      processOrderGroupBy(&sNC, p->pGroupBy, "GROUP")
  ){
    return SQLITE_ERROR;
  }

  return SQLITE_OK;
}

/*
** An instance of the following struct is used by sqlite3Select()
** to save aggregate related information from the Parse object
** at the start of each call and to restore it at the end. See
** saveAggregateInfo() and restoreAggregateInfo().
*/ 
struct AggregateInfo {
  int nAgg;
  AggExpr *aAgg;
};
typedef struct AggregateInfo AggregateInfo;

/* 
** Copy aggregate related information from the Parse structure
** into the AggregateInfo structure. Zero the aggregate related
** values in the Parse struct.
*/
static void saveAggregateInfo(Parse *pParse, AggregateInfo *pInfo){
  pInfo->aAgg = pParse->aAgg;
  pInfo->nAgg = pParse->nAgg;
  pParse->aAgg = 0;
  pParse->nAgg = 0;
}

/*
** Copy aggregate related information from the AggregateInfo struct
** back into the Parse structure. The aggregate related information
** currently stored in the Parse structure is deleted.
*/
static void restoreAggregateInfo(Parse *pParse, AggregateInfo *pInfo){
  sqliteFree(pParse->aAgg);
  pParse->aAgg = pInfo->aAgg;
  pParse->nAgg = pInfo->nAgg;
}
  
/*
** Generate code for the given SELECT statement.
**
** The results are distributed in various ways depending on the
** value of eDest and iParm.
**
**     eDest Value       Result
**     ------------    -------------------------------------------
**     SRT_Callback    Invoke the callback for each row of the result.
**
**     SRT_Mem         Store first result in memory cell iParm
**
**     SRT_Set         Store results as keys of table iParm.
**
**     SRT_Union       Store results as a key in a temporary table iParm
**
**     SRT_Except      Remove results from the temporary table iParm.
**
**     SRT_Table       Store results in temporary table iParm
**
** The table above is incomplete.  Additional eDist value have be added
** since this comment was written.  See the selectInnerLoop() function for
** a complete listing of the allowed values of eDest and their meanings.
**
** This routine returns the number of errors.  If any errors are
** encountered, then an appropriate error message is left in
** pParse->zErrMsg.
**
** This routine does NOT free the Select structure passed in.  The
** calling function needs to do that.
**
** The pParent, parentTab, and *pParentAgg fields are filled in if this
** SELECT is a subquery.  This routine may try to combine this SELECT
** with its parent to form a single flat query.  In so doing, it might
** change the parent query from a non-aggregate to an aggregate query.
** For that reason, the pParentAgg flag is passed as a pointer, so it
** can be changed.
**
** Example 1:   The meaning of the pParent parameter.
**
**    SELECT * FROM t1 JOIN (SELECT x, count(*) FROM t2) JOIN t3;
**    \                      \_______ subquery _______/        /
**     \                                                      /
**      \____________________ outer query ___________________/
**
** This routine is called for the outer query first.   For that call,
** pParent will be NULL.  During the processing of the outer query, this 
** routine is called recursively to handle the subquery.  For the recursive
** call, pParent will point to the outer query.  Because the subquery is
** the second element in a three-way join, the parentTab parameter will
** be 1 (the 2nd value of a 0-indexed array.)
*/
int sqlite3Select(
  Parse *pParse,         /* The parser context */
  Select *p,             /* The SELECT statement being coded. */
  int eDest,             /* How to dispose of the results */
  int iParm,             /* A parameter used by the eDest disposal method */
  Select *pParent,       /* Another SELECT for which this is a sub-query */
  int parentTab,         /* Index in pParent->pSrc of this query */
  int *pParentAgg,       /* True if pParent uses aggregate functions */
  char *aff              /* If eDest is SRT_Union, the affinity string */
){
  int i;
  WhereInfo *pWInfo;
  Vdbe *v;
  int isAgg;             /* True for select lists like "count(*)" */
  ExprList *pEList;      /* List of columns to extract. */
  SrcList *pTabList;     /* List of tables to select from */
  Expr *pWhere;          /* The WHERE clause.  May be NULL */
  ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
  ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
  Expr *pHaving;         /* The HAVING clause.  May be NULL */
  int isDistinct;        /* True if the DISTINCT keyword is present */
  int distinct;          /* Table to use for the distinct set */
  int rc = 1;            /* Value to return from this function */
  AggregateInfo sAggInfo;

  if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1;
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;

#ifndef SQLITE_OMIT_COMPOUND_SELECT
  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){
    return multiSelect(pParse, p, eDest, iParm, aff);
  }
#endif

  saveAggregateInfo(pParse, &sAggInfo);
  pOrderBy = p->pOrderBy;
  if( eDest==SRT_Union || eDest==SRT_Except || eDest==SRT_Discard ){
    p->pOrderBy = 0;
  }
  if( sqlite3SelectResolve(pParse, p, 0) ){
    goto select_end;
  }
  p->pOrderBy = pOrderBy;

  /* Make local copies of the parameters for this query.
  */
  pTabList = p->pSrc;
  pWhere = p->pWhere;
  pGroupBy = p->pGroupBy;
  pHaving = p->pHaving;
  isAgg = p->isAgg;
  isDistinct = p->isDistinct;
  pEList = p->pEList;
  if( pEList==0 ) goto select_end;

  /* 
  ** Do not even attempt to generate any code if we have already seen
  ** errors before this routine starts.
  */
  if( pParse->nErr>0 ) goto select_end;

  /* If writing to memory or generating a set
  ** only a single column may be output.
  */
  assert( eDest!=SRT_Exists || pEList->nExpr==1 );
#ifndef SQLITE_OMIT_SUBQUERY
  if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
    sqlite3ErrorMsg(pParse, "only a single result allowed for "
       "a SELECT that is part of an expression");
    goto select_end;
  }
#endif

  /* ORDER BY is ignored for some destinations.
  */
  switch( eDest ){
    case SRT_Union:
    case SRT_Except:
    case SRT_Discard:
      pOrderBy = 0;
      break;
    default:
      break;
  }

  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto select_end;

  /* Identify column names if we will be using them in a callback.  This
  ** step is skipped if the output is going to some other destination.
  */
  if( eDest==SRT_Callback ){
    generateColumnNames(pParse, pTabList, pEList);
  }

  /* Generate code for all sub-queries in the FROM clause
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; i<pTabList->nSrc; i++){
    const char *zSavedAuthContext = 0;
    int needRestoreContext;

    if( pTabList->a[i].pSelect==0 ) continue;
    if( pTabList->a[i].zName!=0 ){
      zSavedAuthContext = pParse->zAuthContext;
      pParse->zAuthContext = pTabList->a[i].zName;
      needRestoreContext = 1;
    }else{
      needRestoreContext = 0;
    }
    sqlite3Select(pParse, pTabList->a[i].pSelect, SRT_TempTable, 
                 pTabList->a[i].iCursor, p, i, &isAgg, 0);
    if( needRestoreContext ){
      pParse->zAuthContext = zSavedAuthContext;
    }
    pTabList = p->pSrc;
    pWhere = p->pWhere;
    if( eDest!=SRT_Union && eDest!=SRT_Except && eDest!=SRT_Discard ){
      pOrderBy = p->pOrderBy;
    }
    pGroupBy = p->pGroupBy;
    pHaving = p->pHaving;
    isDistinct = p->isDistinct;
  }
#endif

  /* Check for the special case of a min() or max() function by itself
  ** in the result set.
  */
  if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
    rc = 0;
    goto select_end;
  }

  /* Check to see if this is a subquery that can be "flattened" into its parent.
  ** If flattening is a possiblity, do so and return immediately.  
  */
#ifndef SQLITE_OMIT_VIEW
  if( pParent && pParentAgg &&
      flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
    if( isAgg ) *pParentAgg = 1;
    goto select_end;
  }
#endif

  /* If there is an ORDER BY clause, resolve any collation sequences
  ** names that have been explicitly specified.
  */
  if( pOrderBy ){
    for(i=0; i<pOrderBy->nExpr; i++){
      if( pOrderBy->a[i].zName ){
        pOrderBy->a[i].pExpr->pColl = 
            sqlite3LocateCollSeq(pParse, pOrderBy->a[i].zName, -1);
      }
    }
    if( pParse->nErr ){
      goto select_end;
    }
  }

  /* Set the limiter.
  */
  computeLimitRegisters(pParse, p);

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_TempTable ){
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, pEList->nExpr);
  }

  /* Do an analysis of aggregate expressions.
  */
  if( isAgg || pGroupBy ){
    NameContext sNC;
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    sNC.pSrcList = pTabList;

    assert( pParse->nAgg==0 );
    isAgg = 1;
    for(i=0; i<pEList->nExpr; i++){
      if( sqlite3ExprAnalyzeAggregates(&sNC, pEList->a[i].pExpr) ){
        goto select_end;
      }
    }
    if( pGroupBy ){
      for(i=0; i<pGroupBy->nExpr; i++){
        if( sqlite3ExprAnalyzeAggregates(&sNC, pGroupBy->a[i].pExpr) ){
          goto select_end;
        }
      }
    }
    if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){
      goto select_end;
    }
    if( pOrderBy ){
      for(i=0; i<pOrderBy->nExpr; i++){
        if( sqlite3ExprAnalyzeAggregates(&sNC, pOrderBy->a[i].pExpr) ){
          goto select_end;
        }
      }
    }
  }

  /* Reset the aggregator
  */
  if( isAgg ){
    int addr = sqlite3VdbeAddOp(v, OP_AggReset, (pGroupBy?0:1), pParse->nAgg);
    for(i=0; i<pParse->nAgg; i++){
      FuncDef *pFunc;
      if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
        sqlite3VdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_FUNCDEF);
      }
    }
    if( pGroupBy ){
      int sz = sizeof(KeyInfo) + pGroupBy->nExpr*sizeof(CollSeq*);
      KeyInfo *pKey = (KeyInfo *)sqliteMalloc(sz);
      if( 0==pKey ){
        goto select_end;
      }
      pKey->enc = pParse->db->enc;
      pKey->nField = pGroupBy->nExpr;
      for(i=0; i<pGroupBy->nExpr; i++){
        pKey->aColl[i] = sqlite3ExprCollSeq(pParse, pGroupBy->a[i].pExpr);
        if( !pKey->aColl[i] ){
          pKey->aColl[i] = pParse->db->pDfltColl;
        }
      }
      sqlite3VdbeChangeP3(v, addr, (char *)pKey, P3_KEYINFO_HANDOFF);
    }
  }

  /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
  */
  if( eDest==SRT_Mem || eDest==SRT_Exists ){
    sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
  }

  /* Open a temporary table to use for the distinct set.
  */
  if( isDistinct ){
    distinct = pParse->nTab++;
    openTempIndex(pParse, p, distinct, 0);
  }else{
    distinct = -1;
  }

  /* Begin the database scan
  */
  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,
                             pGroupBy ? 0 : &pOrderBy, p->pFetch);
  if( pWInfo==0 ) goto select_end;

  /* Use the standard inner loop if we are not dealing with
  ** aggregates
  */
  if( !isAgg ){
    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
                    iParm, pWInfo->iContinue, pWInfo->iBreak, aff) ){
       goto select_end;
    }
  }

  /* If we are dealing with aggregates, then do the special aggregate
  ** processing.  
  */
  else{
    AggExpr *pAgg;
    int lbl1 = 0;
    pParse->fillAgg = 1;
    if( pGroupBy ){
      for(i=0; i<pGroupBy->nExpr; i++){
        sqlite3ExprCode(pParse, pGroupBy->a[i].pExpr);
      }
      /* No affinity string is attached to the following OP_MakeRecord 
      ** because we do not need to do any coercion of datatypes. */
      sqlite3VdbeAddOp(v, OP_MakeRecord, pGroupBy->nExpr, 0);
      lbl1 = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_AggFocus, 0, lbl1);
    }
    for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
      if( pAgg->isAgg ) continue;
      sqlite3ExprCode(pParse, pAgg->pExpr);
      sqlite3VdbeAddOp(v, OP_AggSet, 0, i);
    }
    pParse->fillAgg = 0;
    if( lbl1<0 ){
      sqlite3VdbeResolveLabel(v, lbl1);
    }
    for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
      Expr *pE;
      int nExpr;
      FuncDef *pDef;
      if( !pAgg->isAgg ) continue;
      assert( pAgg->pFunc!=0 );
      assert( pAgg->pFunc->xStep!=0 );
      pDef = pAgg->pFunc;
      pE = pAgg->pExpr;
      assert( pE!=0 );
      assert( pE->op==TK_AGG_FUNCTION );
      nExpr = sqlite3ExprCodeExprList(pParse, pE->pList);
      sqlite3VdbeAddOp(v, OP_Integer, i, 0);
      if( pDef->needCollSeq ){
        CollSeq *pColl = 0;
        int j;
        for(j=0; !pColl && j<nExpr; j++){
          pColl = sqlite3ExprCollSeq(pParse, pE->pList->a[j].pExpr);
        }
        if( !pColl ) pColl = pParse->db->pDfltColl;
        sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
      }
      sqlite3VdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER);
    }
  }

  /* End the database scan loop.
  */
  sqlite3WhereEnd(pWInfo);

  /* If we are processing aggregates, we need to set up a second loop
  ** over all of the aggregate values and process them.
  */
  if( isAgg ){
    int endagg = sqlite3VdbeMakeLabel(v);
    int startagg;
    startagg = sqlite3VdbeAddOp(v, OP_AggNext, 0, endagg);
    if( pHaving ){
      sqlite3ExprIfFalse(pParse, pHaving, startagg, 1);
    }
    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
                    iParm, startagg, endagg, aff) ){
      goto select_end;
    }
    sqlite3VdbeAddOp(v, OP_Goto, 0, startagg);
    sqlite3VdbeResolveLabel(v, endagg);
    sqlite3VdbeAddOp(v, OP_Noop, 0, 0);
  }

  /* If there is an ORDER BY clause, then we need to sort the results
  ** and send them to the callback one by one.
  */
  if( pOrderBy ){
    generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm);
  }

#ifndef SQLITE_OMIT_SUBQUERY
  /* If this was a subquery, we have now converted the subquery into a
  ** temporary table.  So delete the subquery structure from the parent
  ** to prevent this subquery from being evaluated again and to force the
  ** the use of the temporary table.
  */
  if( pParent ){
    assert( pParent->pSrc->nSrc>parentTab );
    assert( pParent->pSrc->a[parentTab].pSelect==p );
    sqlite3SelectDelete(p);
    pParent->pSrc->a[parentTab].pSelect = 0;
  }
#endif

  /* The SELECT was successfully coded.   Set the return code to 0
  ** to indicate no errors.
  */
  rc = 0;

  /* Control jumps to here if an error is encountered above, or upon
  ** successful coding of the SELECT.
  */
select_end:
  restoreAggregateInfo(pParse, &sAggInfo);
  return rc;
}
Added SQLite.Interop/src/shell.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
/*
** 2001 September 15
**
** 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 file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.1 2005/03/01 16:04:35 rmsimpson Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
#include <ctype.h>

#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
# include <signal.h>
# include <pwd.h>
# include <unistd.h>
# include <sys/types.h>
#endif

#ifdef __MACOS__
# include <console.h>
# include <signal.h>
# include <unistd.h>
# include <extras.h>
# include <Files.h>
# include <Folders.h>
#endif

#if defined(HAVE_READLINE) && HAVE_READLINE==1
# include <readline/readline.h>
# include <readline/history.h>
#else
# define readline(p) local_getline(p,stdin)
# define add_history(X)
# define read_history(X)
# define write_history(X)
# define stifle_history(X)
#endif

/* Make sure isatty() has a prototype.
*/
extern int isatty();

/*
** The following is the open SQLite database.  We make a pointer
** to this database a static variable so that it can be accessed
** by the SIGINT handler to interrupt database processing.
*/
static sqlite3 *db = 0;

/*
** True if an interrupt (Control-C) has been received.
*/
static int seenInterrupt = 0;

/*
** This is the name of our program. It is set in main(), used
** in a number of other places, mostly for error messages.
*/
static char *Argv0;

/*
** Prompt strings. Initialized in main. Settable with
**   .prompt main continue
*/
static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */


/*
** Determines if a string is a number of not.
*/
static int isNumber(const unsigned char *z, int *realnum){
  if( *z=='-' || *z=='+' ) z++;
  if( !isdigit(*z) ){
    return 0;
  }
  z++;
  if( realnum ) *realnum = 0;
  while( isdigit(*z) ){ z++; }
  if( *z=='.' ){
    z++;
    if( !isdigit(*z) ) return 0;
    while( isdigit(*z) ){ z++; }
    if( realnum ) *realnum = 1;
  }
  if( *z=='e' || *z=='E' ){
    z++;
    if( *z=='+' || *z=='-' ) z++;
    if( !isdigit(*z) ) return 0;
    while( isdigit(*z) ){ z++; }
    if( realnum ) *realnum = 1;
  }
  return *z==0;
}

/*
** A global char* and an SQL function to access its current value 
** from within an SQL statement. This program used to use the 
** sqlite_exec_printf() API to substitue a string into an SQL statement.
** The correct way to do this with sqlite3 is to use the bind API, but
** since the shell is built around the callback paradigm it would be a lot
** of work. Instead just use this hack, which is quite harmless.
*/
static const char *zShellStatic = 0;
static void shellstaticFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  assert( 0==argc );
  assert( zShellStatic );
  sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
}


/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
** The interface is like "readline" but no command-line editing
** is done.
*/
static char *local_getline(char *zPrompt, FILE *in){
  char *zLine;
  int nLine;
  int n;
  int eol;

  if( zPrompt && *zPrompt ){
    printf("%s",zPrompt);
    fflush(stdout);
  }
  nLine = 100;
  zLine = malloc( nLine );
  if( zLine==0 ) return 0;
  n = 0;
  eol = 0;
  while( !eol ){
    if( n+100>nLine ){
      nLine = nLine*2 + 100;
      zLine = realloc(zLine, nLine);
      if( zLine==0 ) return 0;
    }
    if( fgets(&zLine[n], nLine - n, in)==0 ){
      if( n==0 ){
        free(zLine);
        return 0;
      }
      zLine[n] = 0;
      eol = 1;
      break;
    }
    while( zLine[n] ){ n++; }
    if( n>0 && zLine[n-1]=='\n' ){
      n--;
      zLine[n] = 0;
      eol = 1;
    }
  }
  zLine = realloc( zLine, n+1 );
  return zLine;
}

/*
** Retrieve a single line of input text.  "isatty" is true if text
** is coming from a terminal.  In that case, we issue a prompt and
** attempt to use "readline" for command-line editing.  If "isatty"
** is false, use "local_getline" instead of "readline" and issue no prompt.
**
** zPrior is a string of prior text retrieved.  If not the empty
** string, then issue a continuation prompt.
*/
static char *one_input_line(const char *zPrior, FILE *in){
  char *zPrompt;
  char *zResult;
  if( in!=0 ){
    return local_getline(0, in);
  }
  if( zPrior && zPrior[0] ){
    zPrompt = continuePrompt;
  }else{
    zPrompt = mainPrompt;
  }
  zResult = readline(zPrompt);
#if defined(HAVE_READLINE) && HAVE_READLINE==1
  if( zResult ) add_history(zResult);
#endif
  return zResult;
}

struct previous_mode_data {
  int valid;        /* Is there legit data in here? */
  int mode;
  int showHeader;
  int colWidth[100];
};
/*
** An pointer to an instance of this structure is passed from
** the main program to the callback.  This is used to communicate
** state and mode information.
*/
struct callback_data {
  sqlite3 *db;            /* The database */
  int echoOn;            /* True to echo input commands */
  int cnt;               /* Number of records displayed so far */
  FILE *out;             /* Write results here */
  int mode;              /* An output mode setting */
  int showHeader;        /* True to show column names in List or Column mode */
  char *zDestTable;      /* Name of destination table when MODE_Insert */
  char separator[20];    /* Separator character for MODE_List */
  int colWidth[100];     /* Requested width of each column when in column mode*/
  int actualWidth[100];  /* Actual width of each column */
  char nullvalue[20];    /* The text to print when a NULL comes back from
                         ** the database */
  struct previous_mode_data explainPrev;
                         /* Holds the mode information just before
                         ** .explain ON */
  char outfile[FILENAME_MAX]; /* Filename for *out */
  const char *zDbFilename;    /* name of the database file */
  char *zKey;                 /* Encryption key */
};

/*
** These are the allowed modes.
*/
#define MODE_Line     0  /* One column per line.  Blank line between records */
#define MODE_Column   1  /* One record per line in neat columns */
#define MODE_List     2  /* One record per line with a separator */
#define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */
#define MODE_Html     4  /* Generate an XHTML table */
#define MODE_Insert   5  /* Generate SQL "insert" statements */
#define MODE_Tcl      6  /* Generate ANSI-C or TCL quoted elements */
#define MODE_Csv      7  /* Quote strings, numbers are plain */
#define MODE_NUM_OF   8  /* The number of modes (not a mode itself) */

char *modeDescr[MODE_NUM_OF] = {
  "line",
  "column",
  "list",
  "semi",
  "html",
  "insert",
  "tcl",
  "csv",
};

/*
** Number of elements in an array
*/
#define ArraySize(X)  (sizeof(X)/sizeof(X[0]))

/*
** Output the given string as a quoted string using SQL quoting conventions.
*/
static void output_quoted_string(FILE *out, const char *z){
  int i;
  int nSingle = 0;
  for(i=0; z[i]; i++){
    if( z[i]=='\'' ) nSingle++;
  }
  if( nSingle==0 ){
    fprintf(out,"'%s'",z);
  }else{
    fprintf(out,"'");
    while( *z ){
      for(i=0; z[i] && z[i]!='\''; i++){}
      if( i==0 ){
        fprintf(out,"''");
        z++;
      }else if( z[i]=='\'' ){
        fprintf(out,"%.*s''",i,z);
        z += i+1;
      }else{
        fprintf(out,"%s",z);
        break;
      }
    }
    fprintf(out,"'");
  }
}

/*
** Output the given string as a quoted according to C or TCL quoting rules.
*/
static void output_c_string(FILE *out, const char *z){
  unsigned int c;
  fputc('"', out);
  while( (c = *(z++))!=0 ){
    if( c=='\\' ){
      fputc(c, out);
      fputc(c, out);
    }else if( c=='\t' ){
      fputc('\\', out);
      fputc('t', out);
    }else if( c=='\n' ){
      fputc('\\', out);
      fputc('n', out);
    }else if( c=='\r' ){
      fputc('\\', out);
      fputc('r', out);
    }else if( !isprint(c) ){
      fprintf(out, "\\%03o", c);
    }else{
      fputc(c, out);
    }
  }
  fputc('"', out);
}

/*
** Output the given string with characters that are special to
** HTML escaped.
*/
static void output_html_string(FILE *out, const char *z){
  int i;
  while( *z ){
    for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
    if( i>0 ){
      fprintf(out,"%.*s",i,z);
    }
    if( z[i]=='<' ){
      fprintf(out,"&lt;");
    }else if( z[i]=='&' ){
      fprintf(out,"&amp;");
    }else{
      break;
    }
    z += i + 1;
  }
}

/*
** Output a single term of CSV.  Actually, p->separator is used for
** the separator, which may or may not be a comma.  p->nullvalue is
** the null value.  Strings are quoted using ANSI-C rules.  Numbers
** appear outside of quotes.
*/
static void output_csv(struct callback_data *p, const char *z, int bSep){
  if( z==0 ){
    fprintf(p->out,"%s",p->nullvalue);
  }else if( isNumber(z, 0) ){
    fprintf(p->out,"%s",z);
  }else{
    output_c_string(p->out, z);
  }
  if( bSep ){
    fprintf(p->out, p->separator);
  }
}

#ifdef SIGINT
/*
** This routine runs when the user presses Ctrl-C
*/
static void interrupt_handler(int NotUsed){
  seenInterrupt = 1;
  if( db ) sqlite3_interrupt(db);
}
#endif

/*
** This is the callback routine that the SQLite library
** invokes for each row of a query result.
*/
static int callback(void *pArg, int nArg, char **azArg, char **azCol){
  int i;
  struct callback_data *p = (struct callback_data*)pArg;
  switch( p->mode ){
    case MODE_Line: {
      int w = 5;
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        int len = strlen(azCol[i]);
        if( len>w ) w = len;
      }
      if( p->cnt++>0 ) fprintf(p->out,"\n");
      for(i=0; i<nArg; i++){
        fprintf(p->out,"%*s = %s\n", w, azCol[i], 
                azArg[i] ? azArg[i] : p->nullvalue);
      }
      break;
    }
    case MODE_Column: {
      if( p->cnt++==0 ){
        for(i=0; i<nArg; i++){
          int w, n;
          if( i<ArraySize(p->colWidth) ){
             w = p->colWidth[i];
          }else{
             w = 0;
          }
          if( w<=0 ){
            w = strlen(azCol[i] ? azCol[i] : "");
            if( w<10 ) w = 10;
            n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
            if( w<n ) w = n;
          }
          if( i<ArraySize(p->actualWidth) ){
            p->actualWidth[i] = w;
          }
          if( p->showHeader ){
            fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");
          }
        }
        if( p->showHeader ){
          for(i=0; i<nArg; i++){
            int w;
            if( i<ArraySize(p->actualWidth) ){
               w = p->actualWidth[i];
            }else{
               w = 10;
            }
            fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
                   "----------------------------------------------------------",
                    i==nArg-1 ? "\n": "  ");
          }
        }
      }
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        int w;
        if( i<ArraySize(p->actualWidth) ){
           w = p->actualWidth[i];
        }else{
           w = 10;
        }
        fprintf(p->out,"%-*.*s%s",w,w,
            azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
      }
      break;
    }
    case MODE_Semi:
    case MODE_List: {
      if( p->cnt++==0 && p->showHeader ){
        for(i=0; i<nArg; i++){
          fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
        }
      }
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        char *z = azArg[i];
        if( z==0 ) z = p->nullvalue;
        fprintf(p->out, "%s", z);
        if( i<nArg-1 ){
          fprintf(p->out, "%s", p->separator);
        }else if( p->mode==MODE_Semi ){
          fprintf(p->out, ";\n");
        }else{
          fprintf(p->out, "\n");
        }
      }
      break;
    }
    case MODE_Html: {
      if( p->cnt++==0 && p->showHeader ){
        fprintf(p->out,"<TR>");
        for(i=0; i<nArg; i++){
          fprintf(p->out,"<TH>%s</TH>",azCol[i]);
        }
        fprintf(p->out,"</TR>\n");
      }
      if( azArg==0 ) break;
      fprintf(p->out,"<TR>");
      for(i=0; i<nArg; i++){
        fprintf(p->out,"<TD>");
        output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
        fprintf(p->out,"</TD>\n");
      }
      fprintf(p->out,"</TR>\n");
      break;
    }
    case MODE_Tcl: {
      if( p->cnt++==0 && p->showHeader ){
        for(i=0; i<nArg; i++){
          output_c_string(p->out,azCol[i]);
          fprintf(p->out, "%s", p->separator);
        }
        fprintf(p->out,"\n");
      }
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
        fprintf(p->out, "%s", p->separator);
      }
      fprintf(p->out,"\n");
      break;
    }
    case MODE_Csv: {
      if( p->cnt++==0 && p->showHeader ){
        for(i=0; i<nArg; i++){
          output_csv(p, azCol[i], i<nArg-1);
        }
        fprintf(p->out,"\n");
      }
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        output_csv(p, azArg[i], i<nArg-1);
      }
      fprintf(p->out,"\n");
      break;
    }
    case MODE_Insert: {
      if( azArg==0 ) break;
      fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
      for(i=0; i<nArg; i++){
        char *zSep = i>0 ? ",": "";
        if( azArg[i]==0 ){
          fprintf(p->out,"%sNULL",zSep);
        }else if( isNumber(azArg[i], 0) ){
          fprintf(p->out,"%s%s",zSep, azArg[i]);
        }else{
          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          output_quoted_string(p->out, azArg[i]);
        }
      }
      fprintf(p->out,");\n");
      break;
    }
  }
  return 0;
}

/*
** Set the destination table field of the callback_data structure to
** the name of the table given.  Escape any quote characters in the
** table name.
*/
static void set_table_name(struct callback_data *p, const char *zName){
  int i, n;
  int needQuote;
  char *z;

  if( p->zDestTable ){
    free(p->zDestTable);
    p->zDestTable = 0;
  }
  if( zName==0 ) return;
  needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
  for(i=n=0; zName[i]; i++, n++){
    if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
      needQuote = 1;
      if( zName[i]=='\'' ) n++;
    }
  }
  if( needQuote ) n += 2;
  z = p->zDestTable = malloc( n+1 );
  if( z==0 ){
    fprintf(stderr,"Out of memory!\n");
    exit(1);
  }
  n = 0;
  if( needQuote ) z[n++] = '\'';
  for(i=0; zName[i]; i++){
    z[n++] = zName[i];
    if( zName[i]=='\'' ) z[n++] = '\'';
  }
  if( needQuote ) z[n++] = '\'';
  z[n] = 0;
}

/* zIn is either a pointer to a NULL-terminated string in memory obtained
** from malloc(), or a NULL pointer. The string pointed to by zAppend is
** added to zIn, and the result returned in memory obtained from malloc().
** zIn, if it was not NULL, is freed.
**
** If the third argument, quote, is not '\0', then it is used as a 
** quote character for zAppend.
*/
static char * appendText(char *zIn, char const *zAppend, char quote){
  int len;
  int i;
  int nAppend = strlen(zAppend);
  int nIn = (zIn?strlen(zIn):0);

  len = nAppend+nIn+1;
  if( quote ){
    len += 2;
    for(i=0; i<nAppend; i++){
      if( zAppend[i]==quote ) len++;
    }
  }

  zIn = (char *)realloc(zIn, len);
  if( !zIn ){
    return 0;
  }

  if( quote ){
    char *zCsr = &zIn[nIn];
    *zCsr++ = quote;
    for(i=0; i<nAppend; i++){
      *zCsr++ = zAppend[i];
      if( zAppend[i]==quote ) *zCsr++ = quote;
    }
    *zCsr++ = quote;
    *zCsr++ = '\0';
    assert( (zCsr-zIn)==len );
  }else{
    memcpy(&zIn[nIn], zAppend, nAppend);
    zIn[len-1] = '\0';
  }

  return zIn;
}


/*
** Execute a query statement that has a single result column.  Print
** that result column on a line by itself with a semicolon terminator.
*/
static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
  sqlite3_stmt *pSelect;
  int rc;
  rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
  if( rc!=SQLITE_OK || !pSelect ){
    return rc;
  }
  rc = sqlite3_step(pSelect);
  while( rc==SQLITE_ROW ){
    fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
    rc = sqlite3_step(pSelect);
  }
  return sqlite3_finalize(pSelect);
}


/*
** This is a different callback routine used for dumping the database.
** Each row received by this callback consists of a table name,
** the table type ("index" or "table") and SQL to create the table.
** This routine should print text sufficient to recreate the table.
*/
static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
  int rc;
  const char *zTable;
  const char *zType;
  const char *zSql;
  struct callback_data *p = (struct callback_data *)pArg;

  if( nArg!=3 ) return 1;
  zTable = azArg[0];
  zType = azArg[1];
  zSql = azArg[2];
  
  if( strcasecmp(zTable,"sqlite_sequence")!=0 ){
    fprintf(p->out, "%s;\n", zSql);
  }else{
    fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
  }

  if( strcmp(zType, "table")==0 ){
    sqlite3_stmt *pTableInfo = 0;
    char *zSelect = 0;
    char *zTableInfo = 0;
    char *zTmp = 0;
   
    zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
    zTableInfo = appendText(zTableInfo, zTable, '"');
    zTableInfo = appendText(zTableInfo, ");", 0);

    rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
    if( zTableInfo ) free(zTableInfo);
    if( rc!=SQLITE_OK || !pTableInfo ){
      return 1;
    }

    zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
    zTmp = appendText(zTmp, zTable, '"');
    if( zTmp ){
      zSelect = appendText(zSelect, zTmp, '\'');
    }
    zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
    rc = sqlite3_step(pTableInfo);
    while( rc==SQLITE_ROW ){
      zSelect = appendText(zSelect, "quote(", 0);
      zSelect = appendText(zSelect, sqlite3_column_text(pTableInfo, 1), '"');
      rc = sqlite3_step(pTableInfo);
      if( rc==SQLITE_ROW ){
        zSelect = appendText(zSelect, ") || ', ' || ", 0);
      }else{
        zSelect = appendText(zSelect, ") ", 0);
      }
    }
    rc = sqlite3_finalize(pTableInfo);
    if( rc!=SQLITE_OK ){
      if( zSelect ) free(zSelect);
      return 1;
    }
    zSelect = appendText(zSelect, "|| ')' FROM  ", 0);
    zSelect = appendText(zSelect, zTable, '"');

    rc = run_table_dump_query(p->out, p->db, zSelect);
    if( rc==SQLITE_CORRUPT ){
      zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
      rc = run_table_dump_query(p->out, p->db, zSelect);
    }
    if( zSelect ) free(zSelect);
    if( rc!=SQLITE_OK ){
      return 1;
    }
  }
  return 0;
}

/*
** Run zQuery.  Update dump_callback() as the callback routine.
** If we get a SQLITE_CORRUPT error, rerun the query after appending
** "ORDER BY rowid DESC" to the end.
*/
static int run_schema_dump_query(
  struct callback_data *p, 
  const char *zQuery,
  char **pzErrMsg
){
  int rc;
  rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
  if( rc==SQLITE_CORRUPT ){
    char *zQ2;
    int len = strlen(zQuery);
    if( pzErrMsg ) sqlite3_free(*pzErrMsg);
    zQ2 = malloc( len+100 );
    if( zQ2==0 ) return rc;
    sprintf(zQ2, "%s ORDER BY rowid DESC", zQuery);
    rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
    free(zQ2);
  }
  return rc;
}

/*
** Text of a help message
*/
static char zHelp[] =
  ".databases             List names and files of attached databases\n"
  ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
  ".echo ON|OFF           Turn command echo on or off\n"
  ".exit                  Exit this program\n"
  ".explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.\n"
  ".header(s) ON|OFF      Turn display of headers on or off\n"
  ".help                  Show this message\n"
  ".import FILE TABLE     Import data from FILE into TABLE\n"
  ".indices TABLE         Show names of all indices on TABLE\n"
  ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
  "                         csv      Comma-separated values\n"
  "                         column   Left-aligned columns.  (See .width)\n"
  "                         html     HTML <table> code\n"
  "                         insert   SQL insert statements for TABLE\n"
  "                         line     One value per line\n"
  "                         list     Values delimited by .separator string\n"
  "                         tabs     Tab-separated values\n"
  "                         tcl      TCL list elements\n"
  ".nullvalue STRING      Print STRING in place of NULL values\n"
  ".output FILENAME       Send output to FILENAME\n"
  ".output stdout         Send output to the screen\n"
  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
  ".quit                  Exit this program\n"
  ".read FILENAME         Execute SQL in FILENAME\n"
#ifdef SQLITE_HAS_CODEC
  ".rekey OLD NEW NEW     Change the encryption key\n"
#endif
  ".schema ?TABLE?        Show the CREATE statements\n"
  ".separator STRING      Change separator used by output mode and .import\n"
  ".show                  Show the current values for various settings\n"
  ".tables ?PATTERN?      List names of tables matching a LIKE pattern\n"
  ".timeout MS            Try opening locked tables for MS milliseconds\n"
  ".width NUM NUM ...     Set column widths for \"column\" mode\n"
;

/* Forward reference */
static void process_input(struct callback_data *p, FILE *in);

/*
** Make sure the database is open.  If it is not, then open it.  If
** the database fails to open, print an error message and exit.
*/
static void open_db(struct callback_data *p){
  if( p->db==0 ){
    sqlite3_open(p->zDbFilename, &p->db);
    db = p->db;
#ifdef SQLITE_HAS_CODEC
    sqlite3_key(p->db, p->zKey, p->zKey ? strlen(p->zKey) : 0);
#endif
    sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
        shellstaticFunc, 0, 0);
    if( SQLITE_OK!=sqlite3_errcode(db) ){
      fprintf(stderr,"Unable to open database \"%s\": %s\n", 
          p->zDbFilename, sqlite3_errmsg(db));
      exit(1);
    }
  }
}

/*
** Do C-language style dequoting.
**
**    \t    -> tab
**    \n    -> newline
**    \r    -> carriage return
**    \NNN  -> ascii character NNN in octal
**    \\    -> backslash
*/
static void resolve_backslashes(char *z){
  int i, j, c;
  for(i=j=0; (c = z[i])!=0; i++, j++){
    if( c=='\\' ){
      c = z[++i];
      if( c=='n' ){
        c = '\n';
      }else if( c=='t' ){
        c = '\t';
      }else if( c=='r' ){
        c = '\r';
      }else if( c>='0' && c<='7' ){
        c =- '0';
        if( z[i+1]>='0' && z[i+1]<='7' ){
          i++;
          c = (c<<3) + z[i] - '0';
          if( z[i+1]>='0' && z[i+1]<='7' ){
            i++;
            c = (c<<3) + z[i] - '0';
          }
        }
      }
    }
    z[j] = c;
  }
  z[j] = 0;
}

/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
** Return 1 to exit and 0 to continue.
*/
static int do_meta_command(char *zLine, struct callback_data *p){
  int i = 1;
  int nArg = 0;
  int n, c;
  int rc = 0;
  char *azArg[50];

  /* Parse the input line into tokens.
  */
  while( zLine[i] && nArg<ArraySize(azArg) ){
    while( isspace((unsigned char)zLine[i]) ){ i++; }
    if( zLine[i]==0 ) break;
    if( zLine[i]=='\'' || zLine[i]=='"' ){
      int delim = zLine[i++];
      azArg[nArg++] = &zLine[i];
      while( zLine[i] && zLine[i]!=delim ){ i++; }
      if( zLine[i]==delim ){
        zLine[i++] = 0;
      }
      if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
    }else{
      azArg[nArg++] = &zLine[i];
      while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
      if( zLine[i] ) zLine[i++] = 0;
      resolve_backslashes(azArg[nArg-1]);
    }
  }

  /* Process the input line.
  */
  if( nArg==0 ) return rc;
  n = strlen(azArg[0]);
  c = azArg[0][0];
  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 1;
    data.mode = MODE_Column;
    data.colWidth[0] = 3;
    data.colWidth[1] = 15;
    data.colWidth[2] = 58;
    data.cnt = 0;
    sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
  }else

  if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
    char *zErrMsg = 0;
    open_db(p);
    fprintf(p->out, "BEGIN TRANSACTION;\n");
    if( nArg==1 ){
      run_schema_dump_query(p, 
        "SELECT name, type, sql FROM sqlite_master "
        "WHERE sql NOT NULL AND type=='table'", 0
      );
      run_schema_dump_query(p, 
        "SELECT name, type, sql FROM sqlite_master "
        "WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0
      );
    }else{
      int i;
      for(i=1; i<nArg; i++){
        zShellStatic = azArg[i];
        run_schema_dump_query(p,
          "SELECT name, type, sql FROM sqlite_master "
          "WHERE tbl_name LIKE shellstatic() AND type=='table'"
          "  AND sql NOT NULL", 0);
        run_schema_dump_query(p,
          "SELECT name, type, sql FROM sqlite_master "
          "WHERE tbl_name LIKE shellstatic() AND type!='table'"
          "  AND type!='meta' AND sql NOT NULL", 0);
        zShellStatic = 0;
      }
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }else{
      fprintf(p->out, "COMMIT;\n");
    }
  }else

  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
    int j;
    char *z = azArg[1];
    int val = atoi(azArg[1]);
    for(j=0; z[j]; j++){
      z[j] = tolower((unsigned char)z[j]);
    }
    if( strcmp(z,"on")==0 ){
      val = 1;
    }else if( strcmp(z,"yes")==0 ){
      val = 1;
    }
    p->echoOn = val;
  }else

  if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
    rc = 1;
  }else

  if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
    int j;
    static char zOne[] = "1";
    char *z = nArg>=2 ? azArg[1] : zOne;
    int val = atoi(z);
    for(j=0; z[j]; j++){
      z[j] = tolower((unsigned char)z[j]);
    }
    if( strcmp(z,"on")==0 ){
      val = 1;
    }else if( strcmp(z,"yes")==0 ){
      val = 1;
    }
    if(val == 1) {
      if(!p->explainPrev.valid) {
        p->explainPrev.valid = 1;
        p->explainPrev.mode = p->mode;
        p->explainPrev.showHeader = p->showHeader;
        memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
      }
      /* We could put this code under the !p->explainValid
      ** condition so that it does not execute if we are already in
      ** explain mode. However, always executing it allows us an easy
      ** was to reset to explain mode in case the user previously
      ** did an .explain followed by a .width, .mode or .header
      ** command.
      */
      p->mode = MODE_Column;
      p->showHeader = 1;
      memset(p->colWidth,0,ArraySize(p->colWidth));
      p->colWidth[0] = 4;
      p->colWidth[1] = 12;
      p->colWidth[2] = 10;
      p->colWidth[3] = 10;
      p->colWidth[4] = 35;
    }else if (p->explainPrev.valid) {
      p->explainPrev.valid = 0;
      p->mode = p->explainPrev.mode;
      p->showHeader = p->explainPrev.showHeader;
      memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
    }
  }else

  if( c=='h' && (strncmp(azArg[0], "header", n)==0
                 ||
                 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
    int j;
    char *z = azArg[1];
    int val = atoi(azArg[1]);
    for(j=0; z[j]; j++){
      z[j] = tolower((unsigned char)z[j]);
    }
    if( strcmp(z,"on")==0 ){
      val = 1;
    }else if( strcmp(z,"yes")==0 ){
      val = 1;
    }
    p->showHeader = val;
  }else

  if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
    fprintf(stderr,zHelp);
  }else

  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
    char *zTable = azArg[2];    /* Insert data into this table */
    char *zFile = azArg[1];     /* The file from which to extract data */
    sqlite3_stmt *pStmt;        /* A statement */
    int rc;                     /* Result code */
    int nCol;                   /* Number of columns in the table */
    int nByte;                  /* Number of bytes in an SQL string */
    int i, j;                   /* Loop counters */
    int nSep;                   /* Number of bytes in p->separator[] */
    char *zSql;                 /* An SQL statement */
    char *zLine;                /* A single line of input from the file */
    char **azCol;               /* zLine[] broken up into columns */
    char *zCommit;              /* How to commit changes */   
    FILE *in;                   /* The input file */
    int lineno = 0;             /* Line number of input file */

    nSep = strlen(p->separator);
    if( nSep==0 ){
      fprintf(stderr, "non-null separator required for import\n");
      return 0;
    }
    zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
    if( zSql==0 ) return 0;
    nByte = strlen(zSql);
    rc = sqlite3_prepare(p->db, zSql, 0, &pStmt, 0);
    sqlite3_free(zSql);
    if( rc ){
      fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
      nCol = 0;
    }else{
      nCol = sqlite3_column_count(pStmt);
    }
    sqlite3_finalize(pStmt);
    if( nCol==0 ) return 0;
    zSql = malloc( nByte + 20 + nCol*2 );
    if( zSql==0 ) return 0;
    sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
    j = strlen(zSql);
    for(i=1; i<nCol; i++){
      zSql[j++] = ',';
      zSql[j++] = '?';
    }
    zSql[j++] = ')';
    zSql[j] = 0;
    rc = sqlite3_prepare(p->db, zSql, 0, &pStmt, 0);
    free(zSql);
    if( rc ){
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
      sqlite3_finalize(pStmt);
      return 0;
    }
    in = fopen(zFile, "rb");
    if( in==0 ){
      fprintf(stderr, "cannot open file: %s\n", zFile);
      sqlite3_finalize(pStmt);
      return 0;
    }
    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
    if( azCol==0 ) return 0;
    sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
    zCommit = "COMMIT";
    while( (zLine = local_getline(0, in))!=0 ){
      char *z;
      i = 0;
      lineno++;
      azCol[0] = zLine;
      for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
        if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
          *z = 0;
          i++;
          if( i<nCol ){
            azCol[i] = &z[nSep];
            z += nSep-1;
          }
        }
      }
      if( i+1!=nCol ){
        fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
           zFile, lineno, nCol, i+1);
        zCommit = "ROLLBACK";
        break;
      }
      for(i=0; i<nCol; i++){
        sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
      }
      sqlite3_step(pStmt);
      rc = sqlite3_reset(pStmt);
      free(zLine);
      if( rc!=SQLITE_OK ){
        fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
        zCommit = "ROLLBACK";
        break;
      }
    }
    free(azCol);
    fclose(in);
    sqlite3_finalize(pStmt);
    sqlite3_exec(p->db, zCommit, 0, 0, 0);
  }else

  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_List;
    zShellStatic = azArg[1];
    sqlite3_exec(p->db,
      "SELECT name FROM sqlite_master "
      "WHERE type='index' AND tbl_name LIKE shellstatic() "
      "UNION ALL "
      "SELECT name FROM sqlite_temp_master "
      "WHERE type='index' AND tbl_name LIKE shellstatic() "
      "ORDER BY 1",
      callback, &data, &zErrMsg
    );
    zShellStatic = 0;
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
  }else

  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
    int n2 = strlen(azArg[1]);
    if( strncmp(azArg[1],"line",n2)==0
        ||
        strncmp(azArg[1],"lines",n2)==0 ){
      p->mode = MODE_Line;
    }else if( strncmp(azArg[1],"column",n2)==0
              ||
              strncmp(azArg[1],"columns",n2)==0 ){
      p->mode = MODE_Column;
    }else if( strncmp(azArg[1],"list",n2)==0 ){
      p->mode = MODE_List;
    }else if( strncmp(azArg[1],"html",n2)==0 ){
      p->mode = MODE_Html;
    }else if( strncmp(azArg[1],"tcl",n2)==0 ){
      p->mode = MODE_Tcl;
    }else if( strncmp(azArg[1],"csv",n2)==0 ){
      p->mode = MODE_Csv;
      strcpy(p->separator, ",");
    }else if( strncmp(azArg[1],"tabs",n2)==0 ){
      p->mode = MODE_List;
      strcpy(p->separator, "\t");
    }else if( strncmp(azArg[1],"insert",n2)==0 ){
      p->mode = MODE_Insert;
      if( nArg>=3 ){
        set_table_name(p, azArg[2]);
      }else{
        set_table_name(p, "table");
      }
    }else {
      fprintf(stderr,"mode should be on of: "
         "column csv html insert line list tabs tcl\n");
    }
  }else

  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
    sprintf(p->nullvalue, "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
  }else

  if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
    if( p->out!=stdout ){
      fclose(p->out);
    }
    if( strcmp(azArg[1],"stdout")==0 ){
      p->out = stdout;
      strcpy(p->outfile,"stdout");
    }else{
      p->out = fopen(azArg[1], "wb");
      if( p->out==0 ){
        fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
        p->out = stdout;
      } else {
         strcpy(p->outfile,azArg[1]);
      }
    }
  }else

  if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
    if( nArg >= 2) {
      strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
    }
    if( nArg >= 3) {
      strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
    }
  }else

  if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
    rc = 1;
  }else

  if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
    FILE *alt = fopen(azArg[1], "rb");
    if( alt==0 ){
      fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
    }else{
      process_input(p, alt);
      fclose(alt);
    }
  }else

#ifdef SQLITE_HAS_CODEC
  if( c=='r' && strncmp(azArg[0],"rekey", n)==0 && nArg==4 ){
    char *zOld = p->zKey;
    if( zOld==0 ) zOld = "";
    if( strcmp(azArg[1],zOld) ){
      fprintf(stderr,"old key is incorrect\n");
    }else if( strcmp(azArg[2], azArg[3]) ){
      fprintf(stderr,"2nd copy of new key does not match the 1st\n");
    }else{
      sqlite3_free(p->zKey);
      p->zKey = sqlite3_mprintf("%s", azArg[2]);
      sqlite3_rekey(p->db, p->zKey, strlen(p->zKey));
    }
  }else
#endif

  if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_Semi;
    if( nArg>1 ){
      int i;
      for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
      if( strcmp(azArg[1],"sqlite_master")==0 ){
        char *new_argv[2], *new_colv[2];
        new_argv[0] = "CREATE TABLE sqlite_master (\n"
                      "  type text,\n"
                      "  name text,\n"
                      "  tbl_name text,\n"
                      "  rootpage integer,\n"
                      "  sql text\n"
                      ")";
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
      }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
        char *new_argv[2], *new_colv[2];
        new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
                      "  type text,\n"
                      "  name text,\n"
                      "  tbl_name text,\n"
                      "  rootpage integer,\n"
                      "  sql text\n"
                      ")";
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
      }else{
        zShellStatic = azArg[1];
        sqlite3_exec(p->db,
          "SELECT sql FROM "
          "  (SELECT * FROM sqlite_master UNION ALL"
          "   SELECT * FROM sqlite_temp_master) "
          "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
          "ORDER BY substr(type,2,1), name",
          callback, &data, &zErrMsg);
        zShellStatic = 0;
      }
    }else{
      sqlite3_exec(p->db,
         "SELECT sql FROM "
         "  (SELECT * FROM sqlite_master UNION ALL"
         "   SELECT * FROM sqlite_temp_master) "
         "WHERE type!='meta' AND sql NOTNULL "
         "ORDER BY substr(type,2,1), name",
         callback, &data, &zErrMsg
      );
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
  }else

  if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
    sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]);
  }else

  if( c=='s' && strncmp(azArg[0], "show", n)==0){
    int i;
    fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
    fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
    fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
    fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
    fprintf(p->out,"%9.9s: ", "nullvalue");
      output_c_string(p->out, p->nullvalue);
      fprintf(p->out, "\n");
    fprintf(p->out,"%9.9s: %s\n","output",
                                 strlen(p->outfile) ? p->outfile : "stdout");
    fprintf(p->out,"%9.9s: ", "separator");
      output_c_string(p->out, p->separator);
      fprintf(p->out, "\n");
    fprintf(p->out,"%9.9s: ","width");
    for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
      fprintf(p->out,"%d ",p->colWidth[i]);
    }
    fprintf(p->out,"\n");
  }else

  if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
    char **azResult;
    int nRow, rc;
    char *zErrMsg;
    open_db(p);
    if( nArg==1 ){
      rc = sqlite3_get_table(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type IN ('table','view') "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
    }else{
      zShellStatic = azArg[1];
      rc = sqlite3_get_table(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
      zShellStatic = 0;
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
    if( rc==SQLITE_OK ){
      int len, maxlen = 0;
      int i, j;
      int nPrintCol, nPrintRow;
      for(i=1; i<=nRow; i++){
        if( azResult[i]==0 ) continue;
        len = strlen(azResult[i]);
        if( len>maxlen ) maxlen = len;
      }
      nPrintCol = 80/(maxlen+2);
      if( nPrintCol<1 ) nPrintCol = 1;
      nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
      for(i=0; i<nPrintRow; i++){
        for(j=i+1; j<=nRow; j+=nPrintRow){
          char *zSp = j<=nPrintRow ? "" : "  ";
          printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
        }
        printf("\n");
      }
    }
    sqlite3_free_table(azResult);
  }else

  if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
    open_db(p);
    sqlite3_busy_timeout(p->db, atoi(azArg[1]));
  }else

  if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
    int j;
    for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
      p->colWidth[j-1] = atoi(azArg[j]);
    }
  }else

  {
    fprintf(stderr, "unknown command or invalid arguments: "
      " \"%s\". Enter \".help\" for help\n", azArg[0]);
  }

  return rc;
}

/*
** Return TRUE if the last non-whitespace character in z[] is a semicolon.
** z[] is N characters long.
*/
static int _ends_with_semicolon(const char *z, int N){
  while( N>0 && isspace((unsigned char)z[N-1]) ){ N--; }
  return N>0 && z[N-1]==';';
}

/*
** Test to see if a line consists entirely of whitespace.
*/
static int _all_whitespace(const char *z){
  for(; *z; z++){
    if( isspace(*(unsigned char*)z) ) continue;
    if( *z=='/' && z[1]=='*' ){
      z += 2;
      while( *z && (*z!='*' || z[1]!='/') ){ z++; }
      if( *z==0 ) return 0;
      z++;
      continue;
    }
    if( *z=='-' && z[1]=='-' ){
      z += 2;
      while( *z && *z!='\n' ){ z++; }
      if( *z==0 ) return 1;
      continue;
    }
    return 0;
  }
  return 1;
}

/*
** Return TRUE if the line typed in is an SQL command terminator other
** than a semi-colon.  The SQL Server style "go" command is understood
** as is the Oracle "/".
*/
static int _is_command_terminator(const char *zLine){
  while( isspace(*(unsigned char*)zLine) ){ zLine++; };
  if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1;  /* Oracle */
  if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
         && _all_whitespace(&zLine[2]) ){
    return 1;  /* SQL Server */
  }
  return 0;
}

/*
** Read input from *in and process it.  If *in==0 then input
** is interactive - the user is typing it it.  Otherwise, input
** is coming from a file or device.  A prompt is issued and history
** is saved only if input is interactive.  An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
*/
static void process_input(struct callback_data *p, FILE *in){
  char *zLine;
  char *zSql = 0;
  int nSql = 0;
  char *zErrMsg;
  int rc;
  while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){
    if( seenInterrupt ){
      if( in!=0 ) break;
      seenInterrupt = 0;
    }
    if( p->echoOn ) printf("%s\n", zLine);
    if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
    if( zLine && zLine[0]=='.' && nSql==0 ){
      int rc = do_meta_command(zLine, p);
      free(zLine);
      if( rc ) break;
      continue;
    }
    if( _is_command_terminator(zLine) ){
      strcpy(zLine,";");
    }
    if( zSql==0 ){
      int i;
      for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
      if( zLine[i]!=0 ){
        nSql = strlen(zLine);
        zSql = malloc( nSql+1 );
        strcpy(zSql, zLine);
      }
    }else{
      int len = strlen(zLine);
      zSql = realloc( zSql, nSql + len + 2 );
      if( zSql==0 ){
        fprintf(stderr,"%s: out of memory!\n", Argv0);
        exit(1);
      }
      strcpy(&zSql[nSql++], "\n");
      strcpy(&zSql[nSql], zLine);
      nSql += len;
    }
    free(zLine);
    if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite3_complete(zSql) ){
      p->cnt = 0;
      open_db(p);
      rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
      if( rc || zErrMsg ){
        if( in!=0 && !p->echoOn ) printf("%s\n",zSql);
        if( zErrMsg!=0 ){
          printf("SQL error: %s\n", zErrMsg);
          sqlite3_free(zErrMsg);
          zErrMsg = 0;
        }else{
          printf("SQL error: %s\n", sqlite3_errmsg(p->db));
        }
      }
      free(zSql);
      zSql = 0;
      nSql = 0;
    }
  }
  if( zSql ){
    if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
    free(zSql);
  }
}

/*
** Return a pathname which is the user's home directory.  A
** 0 return indicates an error of some kind.  Space to hold the
** resulting string is obtained from malloc().  The calling
** function should free the result.
*/
static char *find_home_dir(void){
  char *home_dir = NULL;

#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
  struct passwd *pwent;
  uid_t uid = getuid();
  if( (pwent=getpwuid(uid)) != NULL) {
    home_dir = pwent->pw_dir;
  }
#endif

#ifdef __MACOS__
  char home_path[_MAX_PATH+1];
  home_dir = getcwd(home_path, _MAX_PATH);
#endif

  if (!home_dir) {
    home_dir = getenv("HOME");
    if (!home_dir) {
      home_dir = getenv("HOMEPATH"); /* Windows? */
    }
  }

#if defined(_WIN32) || defined(WIN32)
  if (!home_dir) {
    home_dir = "c:";
  }
#endif

  if( home_dir ){
    char *z = malloc( strlen(home_dir)+1 );
    if( z ) strcpy(z, home_dir);
    home_dir = z;
  }

  return home_dir;
}

/*
** Read input from the file given by sqliterc_override.  Or if that
** parameter is NULL, take input from ~/.sqliterc
*/
static void process_sqliterc(
  struct callback_data *p,        /* Configuration data */
  const char *sqliterc_override   /* Name of config file. NULL to use default */
){
  char *home_dir = NULL;
  const char *sqliterc = sqliterc_override;
  char *zBuf;
  FILE *in = NULL;

  if (sqliterc == NULL) {
    home_dir = find_home_dir();
    if( home_dir==0 ){
      fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
      return;
    }
    zBuf = malloc(strlen(home_dir) + 15);
    if( zBuf==0 ){
      fprintf(stderr,"%s: out of memory!\n", Argv0);
      exit(1);
    }
    sprintf(zBuf,"%s/.sqliterc",home_dir);
    free(home_dir);
    sqliterc = (const char*)zBuf;
  }
  in = fopen(sqliterc,"rb");
  if( in ){
    if( isatty(fileno(stdout)) ){
      printf("Loading resources from %s\n",sqliterc);
    }
    process_input(p,in);
    fclose(in);
  }
  return;
}

/*
** Show available command line options
*/
static const char zOptions[] = 
  "   -init filename       read/process named file\n"
  "   -echo                print commands before execution\n"
  "   -[no]header          turn headers on or off\n"
  "   -column              set output mode to 'column'\n"
  "   -html                set output mode to HTML\n"
#ifdef SQLITE_HAS_CODEC
  "   -key KEY             encryption key\n"
#endif                 
  "   -line                set output mode to 'line'\n"
  "   -list                set output mode to 'list'\n"
  "   -separator 'x'       set output field separator (|)\n"
  "   -nullvalue 'text'    set text string for NULL values\n"
  "   -version             show SQLite version\n"
  "   -help                show this text, also show dot-commands\n"
;
static void usage(int showDetail){
  fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0);
  if( showDetail ){
    fprintf(stderr, "Options are:\n%s", zOptions);
  }else{
    fprintf(stderr, "Use the -help option for additional information\n");
  }
  exit(1);
}

/*
** Initialize the state information in data
*/
void main_init(struct callback_data *data) {
  memset(data, 0, sizeof(*data));
  data->mode = MODE_List;
  strcpy(data->separator,"|");
  data->showHeader = 0;
  strcpy(mainPrompt,"sqlite> ");
  strcpy(continuePrompt,"   ...> ");
}

int main(int argc, char **argv){
  char *zErrMsg = 0;
  struct callback_data data;
  const char *zInitFile = 0;
  char *zFirstCmd = 0;
  int i;

#ifdef __MACOS__
  argc = ccommand(&argv);
#endif

  Argv0 = argv[0];
  main_init(&data);

  /* Make sure we have a valid signal handler early, before anything
  ** else is done.
  */
#ifdef SIGINT
  signal(SIGINT, interrupt_handler);
#endif

  /* Do an initial pass through the command-line argument to locate
  ** the name of the database file, the name of the initialization file,
  ** and the first command to execute.
  */
  for(i=1; i<argc-1; i++){
    if( argv[i][0]!='-' ) break;
    if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
      i++;
    }else if( strcmp(argv[i],"-init")==0 ){
      i++;
      zInitFile = argv[i];
    }else if( strcmp(argv[i],"-key")==0 ){
      i++;
      data.zKey = sqlite3_mprintf("%s",argv[i]);
    }
  }
  if( i<argc ){
    data.zDbFilename = argv[i++];
  }else{
#ifndef SQLITE_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
#else
    data.zDbFilename = 0;
#endif
  }
  if( i<argc ){
    zFirstCmd = argv[i++];
  }
  data.out = stdout;

  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
  ** files from being created if a user mistypes the database name argument
  ** to the sqlite command-line tool.
  */
  if( access(data.zDbFilename, 0)==0 ){
    open_db(&data);
  }

  /* Process the initialization file if there is one.  If no -init option
  ** is given on the command line, look for a file named ~/.sqliterc and
  ** try to process it.
  */
  process_sqliterc(&data,zInitFile);

  /* Make a second pass through the command-line argument and set
  ** options.  This second pass is delayed until after the initialization
  ** file is processed so that the command-line arguments will override
  ** settings in the initialization file.
  */
  for(i=1; i<argc && argv[i][0]=='-'; i++){
    char *z = argv[i];
    if( strcmp(z,"-init")==0 || strcmp(z,"-key")==0 ){
      i++;
    }else if( strcmp(z,"-html")==0 ){
      data.mode = MODE_Html;
    }else if( strcmp(z,"-list")==0 ){
      data.mode = MODE_List;
    }else if( strcmp(z,"-line")==0 ){
      data.mode = MODE_Line;
    }else if( strcmp(z,"-column")==0 ){
      data.mode = MODE_Column;
    }else if( strcmp(z,"-separator")==0 ){
      i++;
      sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]);
    }else if( strcmp(z,"-nullvalue")==0 ){
      i++;
      sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
    }else if( strcmp(z,"-header")==0 ){
      data.showHeader = 1;
    }else if( strcmp(z,"-noheader")==0 ){
      data.showHeader = 0;
    }else if( strcmp(z,"-echo")==0 ){
      data.echoOn = 1;
    }else if( strcmp(z,"-version")==0 ){
      printf("%s\n", sqlite3_libversion());
      return 1;
    }else if( strcmp(z,"-help")==0 ){
      usage(1);
    }else{
      fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
      fprintf(stderr,"Use -help for a list of options.\n");
      return 1;
    }
  }

  if( zFirstCmd ){
    /* Run just the command that follows the database name
    */
    if( zFirstCmd[0]=='.' ){
      do_meta_command(zFirstCmd, &data);
      exit(0);
    }else{
      int rc;
      open_db(&data);
      rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
      if( rc!=0 && zErrMsg!=0 ){
        fprintf(stderr,"SQL error: %s\n", zErrMsg);
        exit(1);
      }
    }
  }else{
    /* Run commands received from standard input
    */
    if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){
      char *zHome;
      char *zHistory = 0;
      printf(
        "SQLite version %s\n"
        "Enter \".help\" for instructions\n",
        sqlite3_libversion()
      );
      zHome = find_home_dir();
      if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){
        sprintf(zHistory,"%s/.sqlite_history", zHome);
      }
#if defined(HAVE_READLINE) && HAVE_READLINE==1
      if( zHistory ) read_history(zHistory);
#endif
      process_input(&data, 0);
      if( zHistory ){
        stifle_history(100);
        write_history(zHistory);
      }
    }else{
      process_input(&data, stdin);
    }
  }
  set_table_name(&data, 0);
  if( db ) sqlite3_close(db);
  return 0;
}
Added SQLite.Interop/src/sqlite3.def.






















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
EXPORTS
sqlite3_aggregate_context
sqlite3_aggregate_count
sqlite3_bind_blob
sqlite3_bind_double
sqlite3_bind_int
sqlite3_bind_int64
sqlite3_bind_null
sqlite3_bind_parameter_count
sqlite3_bind_parameter_index
sqlite3_bind_parameter_name
sqlite3_bind_text
sqlite3_bind_text16
sqlite3_busy_handler
sqlite3_busy_timeout
sqlite3_changes
sqlite3_close
sqlite3_collation_needed
sqlite3_collation_needed16
sqlite3_column_blob
sqlite3_column_bytes
sqlite3_column_bytes16
sqlite3_column_count
sqlite3_column_decltype
sqlite3_column_decltype16
sqlite3_column_double
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_name
sqlite3_column_name16
sqlite3_column_text
sqlite3_column_text16
sqlite3_column_type
sqlite3_commit_hook
sqlite3_complete
sqlite3_complete16
sqlite3_create_collation
sqlite3_create_collation16
sqlite3_create_function
sqlite3_create_function16
sqlite3_data_count
sqlite3_errcode
sqlite3_errmsg
sqlite3_errmsg16
sqlite3_exec
sqlite3_finalize
sqlite3_free
sqlite3_free_table
sqlite3_get_auxdata
sqlite3_get_table
sqlite3_interrupt
sqlite3_last_insert_rowid
sqlite3_libversion
sqlite3_mprintf
sqlite3_open
sqlite3_open16
sqlite3_prepare
sqlite3_prepare16
sqlite3_progress_handler
sqlite3_reset
sqlite3_result_blob
sqlite3_result_double
sqlite3_result_error
sqlite3_result_error16
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_null
sqlite3_result_text
sqlite3_result_text16
sqlite3_result_text16be
sqlite3_result_text16le
sqlite3_result_value
sqlite3_set_authorizer
sqlite3_set_auxdata
sqlite3_snprintf
sqlite3_step
sqlite3_total_changes
sqlite3_trace
sqlite3_user_data
sqlite3_value_blob
sqlite3_value_bytes
sqlite3_value_bytes16
sqlite3_value_double
sqlite3_value_int
sqlite3_value_int64
sqlite3_value_text
sqlite3_value_text16
sqlite3_value_text16be
sqlite3_value_text16le
sqlite3_value_type
sqlite3_vmprintf
Added SQLite.Interop/src/sqlite3.h.




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2001 September 15
**
** 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 header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite3.h,v 1.1 2005/03/01 16:04:36 rmsimpson Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif

/*
** The version of the SQLite library.
*/
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#endif
#define SQLITE_VERSION         "3.1.3"

/*
** The format of the version string is "X.Y.Z<trailing string>", where
** X is the major version number, Y is the minor version number and Z
** is the release number. The trailing string is often "alpha" or "beta".
** For example "3.1.1beta".
**
** The SQLITE_VERSION_NUMBER is an integer with the value 
** (X*100000 + Y*1000 + Z). For example, for version "3.1.1beta", 
** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using 
** version 3.1.1 or greater at compile time, programs may use the test 
** (SQLITE_VERSION_NUMBER>=3001001).
*/
#ifdef SQLITE_VERSION_NUMBER
# undef SQLITE_VERSION_NUMBER
#endif
#define SQLITE_VERSION_NUMBER 3001003

/*
** The version string is also compiled into the library so that a program
** can check to make sure that the lib*.a file and the *.h file are from
** the same version.  The sqlite3_libversion() function returns a pointer
** to the sqlite3_version variable - useful in DLLs which cannot access
** global variables.
*/
extern const char sqlite3_version[];
const char *sqlite3_libversion(void);

/*
** Return the value of the SQLITE_VERSION_NUMBER macro when the
** library was compiled.
*/
int sqlite3_libversion_number(void);

/*
** Each open sqlite database is represented by an instance of the
** following opaque structure.
*/
typedef struct sqlite3 sqlite3;


/*
** Some compilers do not support the "long long" datatype.  So we have
** to do a typedef that for 64-bit integers that depends on what compiler
** is being used.
*/
#if defined(_MSC_VER) || defined(__BORLANDC__)
  typedef __int64 sqlite_int64;
  typedef unsigned __int64 sqlite_uint64;
#else
  typedef long long int sqlite_int64;
  typedef unsigned long long int sqlite_uint64;
#endif


/*
** A function to close the database.
**
** Call this function with a pointer to a structure that was previously
** returned from sqlite3_open() and the corresponding database will by closed.
**
** All SQL statements prepared using sqlite3_prepare() or
** sqlite3_prepare16() must be deallocated using sqlite3_finalize() before
** this routine is called. Otherwise, SQLITE_BUSY is returned and the
** database connection remains open.
*/
int sqlite3_close(sqlite3 *);

/*
** The type for a callback function.
*/
typedef int (*sqlite3_callback)(void*,int,char**, char**);

/*
** A function to executes one or more statements of SQL.
**
** If one or more of the SQL statements are queries, then
** the callback function specified by the 3rd parameter is
** invoked once for each row of the query result.  This callback
** should normally return 0.  If the callback returns a non-zero
** value then the query is aborted, all subsequent SQL statements
** are skipped and the sqlite3_exec() function returns the SQLITE_ABORT.
**
** The 4th parameter is an arbitrary pointer that is passed
** to the callback function as its first parameter.
**
** The 2nd parameter to the callback function is the number of
** columns in the query result.  The 3rd parameter to the callback
** is an array of strings holding the values for each column.
** The 4th parameter to the callback is an array of strings holding
** the names of each column.
**
** The callback function may be NULL, even for queries.  A NULL
** callback is not an error.  It just means that no callback
** will be invoked.
**
** If an error occurs while parsing or evaluating the SQL (but
** not while executing the callback) then an appropriate error
** message is written into memory obtained from malloc() and
** *errmsg is made to point to that message.  The calling function
** is responsible for freeing the memory that holds the error
** message.   Use sqlite3_free() for this.  If errmsg==NULL,
** then no error message is ever written.
**
** The return value is is SQLITE_OK if there are no errors and
** some other return code if there is an error.  The particular
** return value depends on the type of error. 
**
** If the query could not be executed because a database file is
** locked or busy, then this function returns SQLITE_BUSY.  (This
** behavior can be modified somewhat using the sqlite3_busy_handler()
** and sqlite3_busy_timeout() functions below.)
*/
int sqlite3_exec(
  sqlite3*,                     /* An open database */
  const char *sql,              /* SQL to be executed */
  sqlite3_callback,             /* Callback function */
  void *,                       /* 1st argument to callback function */
  char **errmsg                 /* Error msg written here */
);

/*
** Return values for sqlite3_exec() and sqlite3_step()
*/
#define SQLITE_OK           0   /* Successful result */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* An internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* (Internal Only) Table or record not found */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* Database is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_FORMAT      24   /* Auxiliary database format error */
#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB      26   /* File opened that is not a database file */
#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */

/*
** Each entry in an SQLite table has a unique integer key.  (The key is
** the value of the INTEGER PRIMARY KEY column if there is such a column,
** otherwise the key is generated at random.  The unique key is always
** available as the ROWID, OID, or _ROWID_ column.)  The following routine
** returns the integer key of the most recent insert in the database.
**
** This function is similar to the mysql_insert_id() function from MySQL.
*/
sqlite_int64 sqlite3_last_insert_rowid(sqlite3*);

/*
** This function returns the number of database rows that were changed
** (or inserted or deleted) by the most recent called sqlite3_exec().
**
** All changes are counted, even if they were later undone by a
** ROLLBACK or ABORT.  Except, changes associated with creating and
** dropping tables are not counted.
**
** If a callback invokes sqlite3_exec() recursively, then the changes
** in the inner, recursive call are counted together with the changes
** in the outer call.
**
** SQLite implements the command "DELETE FROM table" without a WHERE clause
** by dropping and recreating the table.  (This is much faster than going
** through and deleting individual elements form the table.)  Because of
** this optimization, the change count for "DELETE FROM table" will be
** zero regardless of the number of elements that were originally in the
** table. To get an accurate count of the number of rows deleted, use
** "DELETE FROM table WHERE 1" instead.
*/
int sqlite3_changes(sqlite3*);

/*
** This function returns the number of database rows that have been
** modified by INSERT, UPDATE or DELETE statements since the database handle
** was opened. This includes UPDATE, INSERT and DELETE statements executed
** as part of trigger programs. All changes are counted as soon as the
** statement that makes them is completed (when the statement handle is
** passed to sqlite3_reset() or sqlite_finalise()).
**
** SQLite implements the command "DELETE FROM table" without a WHERE clause
** by dropping and recreating the table.  (This is much faster than going
** through and deleting individual elements form the table.)  Because of
** this optimization, the change count for "DELETE FROM table" will be
** zero regardless of the number of elements that were originally in the
** table. To get an accurate count of the number of rows deleted, use
** "DELETE FROM table WHERE 1" instead.
*/
int sqlite3_total_changes(sqlite3*);

/* This function causes any pending database operation to abort and
** return at its earliest opportunity.  This routine is typically
** called in response to a user action such as pressing "Cancel"
** or Ctrl-C where the user wants a long query operation to halt
** immediately.
*/
void sqlite3_interrupt(sqlite3*);


/* These functions return true if the given input string comprises
** one or more complete SQL statements. For the sqlite3_complete() call,
** the parameter must be a nul-terminated UTF-8 string. For
** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string
** is required.
**
** The algorithm is simple.  If the last token other than spaces
** and comments is a semicolon, then return true.  otherwise return
** false.
*/
int sqlite3_complete(const char *sql);
int sqlite3_complete16(const void *sql);

/*
** This routine identifies a callback function that is invoked
** whenever an attempt is made to open a database table that is
** currently locked by another process or thread.  If the busy callback
** is NULL, then sqlite3_exec() returns SQLITE_BUSY immediately if
** it finds a locked table.  If the busy callback is not NULL, then
** sqlite3_exec() invokes the callback with three arguments.  The
** second argument is the name of the locked table and the third
** argument is the number of times the table has been busy.  If the
** busy callback returns 0, then sqlite3_exec() immediately returns
** SQLITE_BUSY.  If the callback returns non-zero, then sqlite3_exec()
** tries to open the table again and the cycle repeats.
**
** The default busy callback is NULL.
**
** Sqlite is re-entrant, so the busy handler may start a new query. 
** (It is not clear why anyone would every want to do this, but it
** is allowed, in theory.)  But the busy handler may not close the
** database.  Closing the database from a busy handler will delete 
** data structures out from under the executing query and will 
** probably result in a coredump.
*/
int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);

/*
** This routine sets a busy handler that sleeps for a while when a
** table is locked.  The handler will sleep multiple times until 
** at least "ms" milleseconds of sleeping have been done.  After
** "ms" milleseconds of sleeping, the handler returns 0 which
** causes sqlite3_exec() to return SQLITE_BUSY.
**
** Calling this routine with an argument less than or equal to zero
** turns off all busy handlers.
*/
int sqlite3_busy_timeout(sqlite3*, int ms);

/*
** This next routine is really just a wrapper around sqlite3_exec().
** Instead of invoking a user-supplied callback for each row of the
** result, this routine remembers each row of the result in memory
** obtained from malloc(), then returns all of the result after the
** query has finished. 
**
** As an example, suppose the query result where this table:
**
**        Name        | Age
**        -----------------------
**        Alice       | 43
**        Bob         | 28
**        Cindy       | 21
**
** If the 3rd argument were &azResult then after the function returns
** azResult will contain the following data:
**
**        azResult[0] = "Name";
**        azResult[1] = "Age";
**        azResult[2] = "Alice";
**        azResult[3] = "43";
**        azResult[4] = "Bob";
**        azResult[5] = "28";
**        azResult[6] = "Cindy";
**        azResult[7] = "21";
**
** Notice that there is an extra row of data containing the column
** headers.  But the *nrow return value is still 3.  *ncolumn is
** set to 2.  In general, the number of values inserted into azResult
** will be ((*nrow) + 1)*(*ncolumn).
**
** After the calling function has finished using the result, it should 
** pass the result data pointer to sqlite3_free_table() in order to 
** release the memory that was malloc-ed.  Because of the way the 
** malloc() happens, the calling function must not try to call 
** free() directly.  Only sqlite3_free_table() is able to release 
** the memory properly and safely.
**
** The return value of this routine is the same as from sqlite3_exec().
*/
int sqlite3_get_table(
  sqlite3*,               /* An open database */
  const char *sql,       /* SQL to be executed */
  char ***resultp,       /* Result written to a char *[]  that this points to */
  int *nrow,             /* Number of result rows written here */
  int *ncolumn,          /* Number of result columns written here */
  char **errmsg          /* Error msg written here */
);

/*
** Call this routine to free the memory that sqlite3_get_table() allocated.
*/
void sqlite3_free_table(char **result);

/*
** The following routines are variants of the "sprintf()" from the
** standard C library.  The resulting string is written into memory
** obtained from malloc() so that there is never a possiblity of buffer
** overflow.  These routines also implement some additional formatting
** options that are useful for constructing SQL statements.
**
** The strings returned by these routines should be freed by calling
** sqlite3_free().
**
** All of the usual printf formatting options apply.  In addition, there
** is a "%q" option.  %q works like %s in that it substitutes a null-terminated
** string from the argument list.  But %q also doubles every '\'' character.
** %q is designed for use inside a string literal.  By doubling each '\''
** character it escapes that character and allows it to be inserted into
** the string.
**
** For example, so some string variable contains text as follows:
**
**      char *zText = "It's a happy day!";
**
** We can use this text in an SQL statement as follows:
**
**      sqlite3_exec_printf(db, "INSERT INTO table VALUES('%q')",
**          callback1, 0, 0, zText);
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
**      INSERT INTO table1 VALUES('It''s a happy day!')
**
** This is correct.  Had we used %s instead of %q, the generated SQL
** would have looked like this:
**
**      INSERT INTO table1 VALUES('It's a happy day!');
**
** This second example is an SQL syntax error.  As a general rule you
** should always use %q instead of %s when inserting text into a string 
** literal.
*/
char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
void sqlite3_free(char *z);
char *sqlite3_snprintf(int,char*,const char*, ...);

#ifndef SQLITE_OMIT_AUTHORIZATION
/*
** This routine registers a callback with the SQLite library.  The
** callback is invoked (at compile-time, not at run-time) for each
** attempt to access a column of a table in the database.  The callback
** returns SQLITE_OK if access is allowed, SQLITE_DENY if the entire
** SQL statement should be aborted with an error and SQLITE_IGNORE
** if the column should be treated as a NULL value.
*/
int sqlite3_set_authorizer(
  sqlite3*,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pUserData
);
#endif

/*
** The second parameter to the access authorization function above will
** be one of the values below.  These values signify what kind of operation
** is to be authorized.  The 3rd and 4th parameters to the authorization
** function will be parameters or NULL depending on which of the following
** codes is used as the second parameter.  The 5th parameter is the name
** of the database ("main", "temp", etc.) if applicable.  The 6th parameter
** is the name of the inner-most trigger or view that is responsible for
** the access attempt or NULL if this access attempt is directly from 
** input SQL code.
**
**                                          Arg-3           Arg-4
*/
#define SQLITE_COPY                  0   /* Table Name      File Name       */
#define SQLITE_CREATE_INDEX          1   /* Index Name      Table Name      */
#define SQLITE_CREATE_TABLE          2   /* Table Name      NULL            */
#define SQLITE_CREATE_TEMP_INDEX     3   /* Index Name      Table Name      */
#define SQLITE_CREATE_TEMP_TABLE     4   /* Table Name      NULL            */
#define SQLITE_CREATE_TEMP_TRIGGER   5   /* Trigger Name    Table Name      */
#define SQLITE_CREATE_TEMP_VIEW      6   /* View Name       NULL            */
#define SQLITE_CREATE_TRIGGER        7   /* Trigger Name    Table Name      */
#define SQLITE_CREATE_VIEW           8   /* View Name       NULL            */
#define SQLITE_DELETE                9   /* Table Name      NULL            */
#define SQLITE_DROP_INDEX           10   /* Index Name      Table Name      */
#define SQLITE_DROP_TABLE           11   /* Table Name      NULL            */
#define SQLITE_DROP_TEMP_INDEX      12   /* Index Name      Table Name      */
#define SQLITE_DROP_TEMP_TABLE      13   /* Table Name      NULL            */
#define SQLITE_DROP_TEMP_TRIGGER    14   /* Trigger Name    Table Name      */
#define SQLITE_DROP_TEMP_VIEW       15   /* View Name       NULL            */
#define SQLITE_DROP_TRIGGER         16   /* Trigger Name    Table Name      */
#define SQLITE_DROP_VIEW            17   /* View Name       NULL            */
#define SQLITE_INSERT               18   /* Table Name      NULL            */
#define SQLITE_PRAGMA               19   /* Pragma Name     1st arg or NULL */
#define SQLITE_READ                 20   /* Table Name      Column Name     */
#define SQLITE_SELECT               21   /* NULL            NULL            */
#define SQLITE_TRANSACTION          22   /* NULL            NULL            */
#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
#define SQLITE_ATTACH               24   /* Filename        NULL            */
#define SQLITE_DETACH               25   /* Database Name   NULL            */
#define SQLITE_ALTER_TABLE          26   /* Database Name   Table Name      */
#define SQLITE_REINDEX              27   /* Index Name      NULL            */


/*
** The return value of the authorization function should be one of the
** following constants:
*/
/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */

/*
** Register a function that is called at every invocation of sqlite3_exec()
** or sqlite3_prepare().  This function can be used (for example) to generate
** a log file of all SQL executed against a database.
*/
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);

/*
** This routine configures a callback function - the progress callback - that
** is invoked periodically during long running calls to sqlite3_exec(),
** sqlite3_step() and sqlite3_get_table(). An example use for this API is to 
** keep a GUI updated during a large query.
**
** The progress callback is invoked once for every N virtual machine opcodes,
** where N is the second argument to this function. The progress callback
** itself is identified by the third argument to this function. The fourth
** argument to this function is a void pointer passed to the progress callback
** function each time it is invoked.
**
** If a call to sqlite3_exec(), sqlite3_step() or sqlite3_get_table() results 
** in less than N opcodes being executed, then the progress callback is not
** invoked.
** 
** To remove the progress callback altogether, pass NULL as the third
** argument to this function.
**
** If the progress callback returns a result other than 0, then the current 
** query is immediately terminated and any database changes rolled back. If the
** query was part of a larger transaction, then the transaction is not rolled
** back and remains active. The sqlite3_exec() call returns SQLITE_ABORT. 
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);

/*
** Register a callback function to be invoked whenever a new transaction
** is committed.  The pArg argument is passed through to the callback.
** callback.  If the callback function returns non-zero, then the commit
** is converted into a rollback.
**
** If another function was previously registered, its pArg value is returned.
** Otherwise NULL is returned.
**
** Registering a NULL function disables the callback.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);

/*
** Open the sqlite database file "filename".  The "filename" is UTF-8
** encoded for sqlite3_open() and UTF-16 encoded in the native byte order
** for sqlite3_open16().  An sqlite3* handle is returned in *ppDb, even
** if an error occurs. If the database is opened (or created) successfully,
** then SQLITE_OK is returned. Otherwise an error code is returned. The
** sqlite3_errmsg() or sqlite3_errmsg16()  routines can be used to obtain
** an English language description of the error.
**
** If the database file does not exist, then a new database is created.
** The encoding for the database is UTF-8 if sqlite3_open() is called and
** UTF-16 if sqlite3_open16 is used.
**
** Whether or not an error occurs when it is opened, resources associated
** with the sqlite3* handle should be released by passing it to
** sqlite3_close() when it is no longer required.
*/
int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
int sqlite3_open16(
  const void *filename,   /* Database filename (UTF-16) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);

/*
** Return the error code for the most recent sqlite3_* API call associated
** with sqlite3 handle 'db'. SQLITE_OK is returned if the most recent 
** API call was successful.
**
** Calls to many sqlite3_* functions set the error code and string returned
** by sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16()
** (overwriting the previous values). Note that calls to sqlite3_errcode(),
** sqlite3_errmsg() and sqlite3_errmsg16() themselves do not affect the
** results of future invocations.
**
** Assuming no other intervening sqlite3_* API calls are made, the error
** code returned by this function is associated with the same error as
** the strings  returned by sqlite3_errmsg() and sqlite3_errmsg16().
*/
int sqlite3_errcode(sqlite3 *db);

/*
** Return a pointer to a UTF-8 encoded string describing in english the
** error condition for the most recent sqlite3_* API call. The returned
** string is always terminated by an 0x00 byte.
**
** The string "not an error" is returned when the most recent API call was
** successful.
*/
const char *sqlite3_errmsg(sqlite3*);

/*
** Return a pointer to a UTF-16 native byte order encoded string describing
** in english the error condition for the most recent sqlite3_* API call.
** The returned string is always terminated by a pair of 0x00 bytes.
**
** The string "not an error" is returned when the most recent API call was
** successful.
*/
const void *sqlite3_errmsg16(sqlite3*);

/*
** An instance of the following opaque structure is used to represent
** a compiled SQL statment.
*/
typedef struct sqlite3_stmt sqlite3_stmt;

/*
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of the following routines. The only difference between
** them is that the second argument, specifying the SQL statement to
** compile, is assumed to be encoded in UTF-8 for the sqlite3_prepare()
** function and UTF-16 for sqlite3_prepare16().
**
** The first parameter "db" is an SQLite database handle. The second
** parameter "zSql" is the statement to be compiled, encoded as either
** UTF-8 or UTF-16 (see above). If the next parameter, "nBytes", is less
** than zero, then zSql is read up to the first nul terminator.  If
** "nBytes" is not less than zero, then it is the length of the string zSql
** in bytes (not characters).
**
** *pzTail is made to point to the first byte past the end of the first
** SQL statement in zSql.  This routine only compiles the first statement
** in zSql, so *pzTail is left pointing to what remains uncompiled.
**
** *ppStmt is left pointing to a compiled SQL statement that can be
** executed using sqlite3_step().  Or if there is an error, *ppStmt may be
** set to NULL.  If the input text contained no SQL (if the input is and
** empty string or a comment) then *ppStmt is set to NULL.
**
** On success, SQLITE_OK is returned.  Otherwise an error code is returned.
*/
int sqlite3_prepare(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nBytes,             /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
int sqlite3_prepare16(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nBytes,             /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);

/*
** Pointers to the following two opaque structures are used to communicate
** with the implementations of user-defined functions.
*/
typedef struct sqlite3_context sqlite3_context;
typedef struct Mem sqlite3_value;

/*
** In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(),
** one or more literals can be replace by parameters "?" or ":AAA" or
** "$VVV" where AAA is an identifer and VVV is a variable name according
** to the syntax rules of the TCL programming language.
** The value of these parameters (also called "host parameter names") can
** be set using the routines listed below.
**
** In every case, the first parameter is a pointer to the sqlite3_stmt
** structure returned from sqlite3_prepare().  The second parameter is the
** index of the parameter.  The first parameter as an index of 1.  For
** named parameters (":AAA" or "$VVV") you can use 
** sqlite3_bind_parameter_index() to get the correct index value given
** the parameters name.  If the same named parameter occurs more than
** once, it is assigned the same index each time.
**
** The fifth parameter to sqlite3_bind_blob(), sqlite3_bind_text(), and
** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
** text after SQLite has finished with it.  If the fifth argument is the
** special value SQLITE_STATIC, then the library assumes that the information
** is in static, unmanaged space and does not need to be freed.  If the
** fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its
** own private copy of the data.
**
** The sqlite3_bind_* routine must be called before sqlite3_step() after
** an sqlite3_prepare() or sqlite3_reset().  Unbound parameterss are
** interpreted as NULL.
*/
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);

/*
** Return the number of parameters in a compiled SQL statement.  This
** routine was added to support DBD::SQLite.
*/
int sqlite3_bind_parameter_count(sqlite3_stmt*);

/*
** Return the name of the i-th parameter.  Ordinary parameters "?" are
** nameless and a NULL is returned.  For parameters of the form :AAA or
** $VVV the complete text of the parameter name is returned, including
** the initial ":" or "$".  NULL is returned if the index is out of range.
*/
const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);

/*
** Return the index of a parameter with the given name.  The name
** must match exactly.  If no parameter with the given name is found,
** return 0.
*/
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);

/*
** Set all the parameters in the compiled SQL statement to NULL.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_clear_bindings(sqlite3_stmt*);

/*
** Return the number of columns in the result set returned by the compiled
** SQL statement. This routine returns 0 if pStmt is an SQL statement
** that does not return data (for example an UPDATE).
*/
int sqlite3_column_count(sqlite3_stmt *pStmt);

/*
** The first parameter is a compiled SQL statement. This function returns
** the column heading for the Nth column of that statement, where N is the
** second function parameter.  The string returned is UTF-8 for
** sqlite3_column_name() and UTF-16 for sqlite3_column_name16().
*/
const char *sqlite3_column_name(sqlite3_stmt*,int);
const void *sqlite3_column_name16(sqlite3_stmt*,int);

/*
** The first parameter is a compiled SQL statement. If this statement
** is a SELECT statement, the Nth column of the returned result set 
** of the SELECT is a table column then the declared type of the table
** column is returned. If the Nth column of the result set is not at table
** column, then a NULL pointer is returned. The returned string is always
** UTF-8 encoded. For example, in the database schema:
**
** CREATE TABLE t1(c1 VARIANT);
**
** And the following statement compiled:
**
** SELECT c1 + 1, 0 FROM t1;
**
** Then this routine would return the string "VARIANT" for the second
** result column (i==1), and a NULL pointer for the first result column
** (i==0).
*/
const char *sqlite3_column_decltype(sqlite3_stmt *, int i);

/*
** The first parameter is a compiled SQL statement. If this statement
** is a SELECT statement, the Nth column of the returned result set 
** of the SELECT is a table column then the declared type of the table
** column is returned. If the Nth column of the result set is not at table
** column, then a NULL pointer is returned. The returned string is always
** UTF-16 encoded. For example, in the database schema:
**
** CREATE TABLE t1(c1 INTEGER);
**
** And the following statement compiled:
**
** SELECT c1 + 1, 0 FROM t1;
**
** Then this routine would return the string "INTEGER" for the second
** result column (i==1), and a NULL pointer for the first result column
** (i==0).
*/
const void *sqlite3_column_decltype16(sqlite3_stmt*,int);

/* 
** After an SQL query has been compiled with a call to either
** sqlite3_prepare() or sqlite3_prepare16(), then this function must be
** called one or more times to execute the statement.
**
** The return value will be either SQLITE_BUSY, SQLITE_DONE, 
** SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE.
**
** SQLITE_BUSY means that the database engine attempted to open
** a locked database and there is no busy callback registered.
** Call sqlite3_step() again to retry the open.
**
** SQLITE_DONE means that the statement has finished executing
** successfully.  sqlite3_step() should not be called again on this virtual
** machine.
**
** If the SQL statement being executed returns any data, then 
** SQLITE_ROW is returned each time a new row of data is ready
** for processing by the caller. The values may be accessed using
** the sqlite3_column_*() functions described below. sqlite3_step()
** is called again to retrieve the next row of data.
** 
** SQLITE_ERROR means that a run-time error (such as a constraint
** violation) has occurred.  sqlite3_step() should not be called again on
** the VM. More information may be found by calling sqlite3_errmsg().
**
** SQLITE_MISUSE means that the this routine was called inappropriately.
** Perhaps it was called on a virtual machine that had already been
** finalized or on one that had previously returned SQLITE_ERROR or
** SQLITE_DONE.  Or it could be the case the the same database connection
** is being used simulataneously by two or more threads.
*/
int sqlite3_step(sqlite3_stmt*);

/*
** Return the number of values in the current row of the result set.
**
** After a call to sqlite3_step() that returns SQLITE_ROW, this routine
** will return the same value as the sqlite3_column_count() function.
** After sqlite3_step() has returned an SQLITE_DONE, SQLITE_BUSY or
** error code, or before sqlite3_step() has been called on a 
** compiled SQL statement, this routine returns zero.
*/
int sqlite3_data_count(sqlite3_stmt *pStmt);

/*
** Values are stored in the database in one of the following fundamental
** types.
*/
#define SQLITE_INTEGER  1
#define SQLITE_FLOAT    2
/* #define SQLITE_TEXT  3  // See below */
#define SQLITE_BLOB     4
#define SQLITE_NULL     5

/*
** SQLite version 2 defines SQLITE_TEXT differently.  To allow both
** version 2 and version 3 to be included, undefine them both if a
** conflict is seen.  Define SQLITE3_TEXT to be the version 3 value.
*/
#ifdef SQLITE_TEXT
# undef SQLITE_TEXT
#else
# define SQLITE_TEXT     3
#endif
#define SQLITE3_TEXT     3

/*
** The next group of routines returns information about the information
** in a single column of the current result row of a query.  In every
** case the first parameter is a pointer to the SQL statement that is being
** executed (the sqlite_stmt* that was returned from sqlite3_prepare()) and
** the second argument is the index of the column for which information 
** should be returned.  iCol is zero-indexed.  The left-most column as an
** index of 0.
**
** If the SQL statement is not currently point to a valid row, or if the
** the colulmn index is out of range, the result is undefined.
**
** These routines attempt to convert the value where appropriate.  For
** example, if the internal representation is FLOAT and a text result
** is requested, sprintf() is used internally to do the conversion
** automatically.  The following table details the conversions that
** are applied:
**
**    Internal Type    Requested Type     Conversion
**    -------------    --------------    --------------------------
**       NULL             INTEGER         Result is 0
**       NULL             FLOAT           Result is 0.0
**       NULL             TEXT            Result is an empty string
**       NULL             BLOB            Result is a zero-length BLOB
**       INTEGER          FLOAT           Convert from integer to float
**       INTEGER          TEXT            ASCII rendering of the integer
**       INTEGER          BLOB            Same as for INTEGER->TEXT
**       FLOAT            INTEGER         Convert from float to integer
**       FLOAT            TEXT            ASCII rendering of the float
**       FLOAT            BLOB            Same as FLOAT->TEXT
**       TEXT             INTEGER         Use atoi()
**       TEXT             FLOAT           Use atof()
**       TEXT             BLOB            No change
**       BLOB             INTEGER         Convert to TEXT then use atoi()
**       BLOB             FLOAT           Convert to TEXT then use atof()
**       BLOB             TEXT            Add a \000 terminator if needed
**
** The following access routines are provided:
**
** _type()     Return the datatype of the result.  This is one of
**             SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB,
**             or SQLITE_NULL.
** _blob()     Return the value of a BLOB.
** _bytes()    Return the number of bytes in a BLOB value or the number
**             of bytes in a TEXT value represented as UTF-8.  The \000
**             terminator is included in the byte count for TEXT values.
** _bytes16()  Return the number of bytes in a BLOB value or the number
**             of bytes in a TEXT value represented as UTF-16.  The \u0000
**             terminator is included in the byte count for TEXT values.
** _double()   Return a FLOAT value.
** _int()      Return an INTEGER value in the host computer's native
**             integer representation.  This might be either a 32- or 64-bit
**             integer depending on the host.
** _int64()    Return an INTEGER value as a 64-bit signed integer.
** _text()     Return the value as UTF-8 text.
** _text16()   Return the value as UTF-16 text.
*/
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);

/*
** The sqlite3_finalize() function is called to delete a compiled
** SQL statement obtained by a previous call to sqlite3_prepare()
** or sqlite3_prepare16(). If the statement was executed successfully, or
** not executed at all, then SQLITE_OK is returned. If execution of the
** statement failed then an error code is returned. 
**
** This routine can be called at any point during the execution of the
** virtual machine.  If the virtual machine has not completed execution
** when this routine is called, that is like encountering an error or
** an interrupt.  (See sqlite3_interrupt().)  Incomplete updates may be
** rolled back and transactions cancelled,  depending on the circumstances,
** and the result code returned will be SQLITE_ABORT.
*/
int sqlite3_finalize(sqlite3_stmt *pStmt);

/*
** The sqlite3_reset() function is called to reset a compiled SQL
** statement obtained by a previous call to sqlite3_prepare() or
** sqlite3_prepare16() back to it's initial state, ready to be re-executed.
** Any SQL statement variables that had values bound to them using
** the sqlite3_bind_*() API retain their values.
*/
int sqlite3_reset(sqlite3_stmt *pStmt);

/*
** The following two functions are used to add user functions or aggregates
** implemented in C to the SQL langauge interpreted by SQLite. The
** difference only between the two is that the second parameter, the
** name of the (scalar) function or aggregate, is encoded in UTF-8 for
** sqlite3_create_function() and UTF-16 for sqlite3_create_function16().
**
** The first argument is the database handle that the new function or
** aggregate is to be added to. If a single program uses more than one
** database handle internally, then user functions or aggregates must 
** be added individually to each database handle with which they will be
** used.
**
** The third parameter is the number of arguments that the function or
** aggregate takes. If this parameter is negative, then the function or
** aggregate may take any number of arguments.
**
** The fourth parameter is one of SQLITE_UTF* values defined below,
** indicating the encoding that the function is most likely to handle
** values in.  This does not change the behaviour of the programming
** interface. However, if two versions of the same function are registered
** with different encoding values, SQLite invokes the version likely to
** minimize conversions between text encodings.
**
** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
** pointers to user implemented C functions that implement the user
** function or aggregate. A scalar function requires an implementation of
** the xFunc callback only, NULL pointers should be passed as the xStep
** and xFinal parameters. An aggregate function requires an implementation
** of xStep and xFinal, but NULL should be passed for xFunc. To delete an
** existing user function or aggregate, pass NULL for all three function
** callback. Specifying an inconstent set of callback values, such as an
** xFunc and an xFinal, or an xStep but no xFinal, SQLITE_ERROR is
** returned.
*/
int sqlite3_create_function(
  sqlite3 *,
  const char *zFunctionName,
  int nArg,
  int eTextRep,
  void*,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
);
int sqlite3_create_function16(
  sqlite3*,
  const void *zFunctionName,
  int nArg,
  int eTextRep,
  void*,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
);

/*
** The next routine returns the number of calls to xStep for a particular
** aggregate function instance.  The current call to xStep counts so this
** routine always returns at least 1.
*/
int sqlite3_aggregate_count(sqlite3_context*);

/*
** The next group of routines returns information about parameters to
** a user-defined function.  Function implementations use these routines
** to access their parameters.  These routines are the same as the
** sqlite3_column_* routines except that these routines take a single
** sqlite3_value* pointer instead of an sqlite3_stmt* and an integer
** column number.
*/
const void *sqlite3_value_blob(sqlite3_value*);
int sqlite3_value_bytes(sqlite3_value*);
int sqlite3_value_bytes16(sqlite3_value*);
double sqlite3_value_double(sqlite3_value*);
int sqlite3_value_int(sqlite3_value*);
sqlite_int64 sqlite3_value_int64(sqlite3_value*);
const unsigned char *sqlite3_value_text(sqlite3_value*);
const void *sqlite3_value_text16(sqlite3_value*);
const void *sqlite3_value_text16le(sqlite3_value*);
const void *sqlite3_value_text16be(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);

/*
** Aggregate functions use the following routine to allocate
** a structure for storing their state.  The first time this routine
** is called for a particular aggregate, a new structure of size nBytes
** is allocated, zeroed, and returned.  On subsequent calls (for the
** same aggregate instance) the same buffer is returned.  The implementation
** of the aggregate can use the returned buffer to accumulate data.
**
** The buffer allocated is freed automatically by SQLite.
*/
void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);

/*
** The pUserData parameter to the sqlite3_create_function() and
** sqlite3_create_aggregate() routines used to register user functions
** is available to the implementation of the function using this
** call.
*/
void *sqlite3_user_data(sqlite3_context*);

/*
** The following two functions may be used by scalar user functions to
** associate meta-data with argument values. If the same value is passed to
** multiple invocations of the user-function during query execution, under
** some circumstances the associated meta-data may be preserved. This may
** be used, for example, to add a regular-expression matching scalar
** function. The compiled version of the regular expression is stored as
** meta-data associated with the SQL value passed as the regular expression
** pattern.
**
** Calling sqlite3_get_auxdata() returns a pointer to the meta data
** associated with the Nth argument value to the current user function
** call, where N is the second parameter. If no meta-data has been set for
** that value, then a NULL pointer is returned.
**
** The sqlite3_set_auxdata() is used to associate meta data with a user
** function argument. The third parameter is a pointer to the meta data
** to be associated with the Nth user function argument value. The fourth
** parameter specifies a 'delete function' that will be called on the meta
** data pointer to release it when it is no longer required. If the delete
** function pointer is NULL, it is not invoked.
**
** In practice, meta-data is preserved between function calls for
** expressions that are constant at compile time. This includes literal
** values and SQL variables.
*/
void *sqlite3_get_auxdata(sqlite3_context*, int);
void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));


/*
** These are special value for the destructor that is passed in as the
** final argument to routines like sqlite3_result_blob().  If the destructor
** argument is SQLITE_STATIC, it means that the content pointer is constant
** and will never change.  It does not need to be destroyed.  The 
** SQLITE_TRANSIENT value means that the content will likely change in
** the near future and that SQLite should make its own private copy of
** the content before returning.
*/
#define SQLITE_STATIC      ((void(*)(void *))0)
#define SQLITE_TRANSIENT   ((void(*)(void *))-1)

/*
** User-defined functions invoke the following routines in order to
** set their return value.
*/
void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
void sqlite3_result_double(sqlite3_context*, double);
void sqlite3_result_error(sqlite3_context*, const char*, int);
void sqlite3_result_error16(sqlite3_context*, const void*, int);
void sqlite3_result_int(sqlite3_context*, int);
void sqlite3_result_int64(sqlite3_context*, sqlite_int64);
void sqlite3_result_null(sqlite3_context*);
void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
void sqlite3_result_value(sqlite3_context*, sqlite3_value*);

/*
** These are the allowed values for the eTextRep argument to
** sqlite3_create_collation and sqlite3_create_function.
*/
#define SQLITE_UTF8    1
#define SQLITE_UTF16LE 2
#define SQLITE_UTF16BE 3
#define SQLITE_UTF16   4    /* Use native byte order */
#define SQLITE_ANY     5    /* sqlite3_create_function only */

/*
** These two functions are used to add new collation sequences to the
** sqlite3 handle specified as the first argument. 
**
** The name of the new collation sequence is specified as a UTF-8 string
** for sqlite3_create_collation() and a UTF-16 string for
** sqlite3_create_collation16(). In both cases the name is passed as the
** second function argument.
**
** The third argument must be one of the constants SQLITE_UTF8,
** SQLITE_UTF16LE or SQLITE_UTF16BE, indicating that the user-supplied
** routine expects to be passed pointers to strings encoded using UTF-8,
** UTF-16 little-endian or UTF-16 big-endian respectively.
**
** A pointer to the user supplied routine must be passed as the fifth
** argument. If it is NULL, this is the same as deleting the collation
** sequence (so that SQLite cannot call it anymore). Each time the user
** supplied function is invoked, it is passed a copy of the void* passed as
** the fourth argument to sqlite3_create_collation() or
** sqlite3_create_collation16() as its first parameter.
**
** The remaining arguments to the user-supplied routine are two strings,
** each represented by a [length, data] pair and encoded in the encoding
** that was passed as the third argument when the collation sequence was
** registered. The user routine should return negative, zero or positive if
** the first string is less than, equal to, or greater than the second
** string. i.e. (STRING1 - STRING2).
*/
int sqlite3_create_collation(
  sqlite3*, 
  const char *zName, 
  int eTextRep, 
  void*,
  int(*xCompare)(void*,int,const void*,int,const void*)
);
int sqlite3_create_collation16(
  sqlite3*, 
  const char *zName, 
  int eTextRep, 
  void*,
  int(*xCompare)(void*,int,const void*,int,const void*)
);

/*
** To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
** database handle to be called whenever an undefined collation sequence is
** required.
**
** If the function is registered using the sqlite3_collation_needed() API,
** then it is passed the names of undefined collation sequences as strings
** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names
** are passed as UTF-16 in machine native byte order. A call to either
** function replaces any existing callback.
**
** When the user-function is invoked, the first argument passed is a copy
** of the second argument to sqlite3_collation_needed() or
** sqlite3_collation_needed16(). The second argument is the database
** handle. The third argument is one of SQLITE_UTF8, SQLITE_UTF16BE or
** SQLITE_UTF16LE, indicating the most desirable form of the collation
** sequence function required. The fourth parameter is the name of the
** required collation sequence.
**
** The collation sequence is returned to SQLite by a collation-needed
** callback using the sqlite3_create_collation() or
** sqlite3_create_collation16() APIs, described above.
*/
int sqlite3_collation_needed(
  sqlite3*, 
  void*, 
  void(*)(void*,sqlite3*,int eTextRep,const char*)
);
int sqlite3_collation_needed16(
  sqlite3*, 
  void*,
  void(*)(void*,sqlite3*,int eTextRep,const void*)
);

/*
** Specify the key for an encrypted database.  This routine should be
** called right after sqlite3_open().
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
int sqlite3_key(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The key */
);

/*
** Change the key on an open database.  If the current database is not
** encrypted, this routine will encrypt it.  If pNew==0 or nNew==0, the
** database is decrypted.
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
int sqlite3_rekey(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The new key */
);

/*
** Sleep for a little while. The second parameter is the number of
** miliseconds to sleep for. 
**
** If the operating system does not support sleep requests with 
** milisecond time resolution, then the time will be rounded up to 
** the nearest second. The number of miliseconds of sleep actually 
** requested from the operating system is returned.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_sleep(int);

/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled.  A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_expired(sqlite3_stmt*);

/*
** If the following global variable is made to point to a
** string which is the name of a directory, then all temporary files
** created by SQLite will be placed in that directory.  If this variable
** is NULL pointer, then SQLite does a search for an appropriate temporary
** file directory.
**
** Once sqlite3_open() has been called, changing this variable will invalidate the
** current temporary database, if any.
*/
extern char *sqlite3_temp_directory;

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif
Added SQLite.Interop/src/sqliteInt.h.




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
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
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.1 2005/03/01 16:04:36 rmsimpson Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line.  This is necessary if you are compiling
** on a recent machine (ex: RedHat 7.2) but you want your code to work
** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
** without this option, LFS is enable.  But LFS does not exist in the kernel
** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
** portability you should omit LFS.
**
** Similar is true for MacOS.  LFS is only supported on MacOS 9 and later.
*/
#ifndef SQLITE_DISABLE_LFS
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>

/*
** The maximum number of in-memory pages to use for the main database
** table and for temporary tables. Internally, the MAX_PAGES and 
** TEMP_PAGES macros are used. To override the default values at
** compilation time, the SQLITE_DEFAULT_CACHE_SIZE and 
** SQLITE_DEFAULT_TEMP_CACHE_SIZE macros should be set.
*/
#ifdef SQLITE_DEFAULT_CACHE_SIZE
# define MAX_PAGES SQLITE_DEFAULT_CACHE_SIZE
#else
# define MAX_PAGES   2000
#endif
#ifdef SQLITE_DEFAULT_TEMP_CACHE_SIZE
# define TEMP_PAGES SQLITE_DEFAULT_TEMP_CACHE_SIZE
#else
# define TEMP_PAGES   500
#endif

/*
** If the following macro is set to 1, then NULL values are considered
** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
** compound queries.  No other SQL database engine (among those tested) 
** works this way except for OCELOT.  But the SQL92 spec implies that
** this is how things should work.
**
** If the following macro is set to 0, then NULLs are indistinct for
** SELECT DISTINCT and for UNION.
*/
#define NULL_ALWAYS_DISTINCT 0

/*
** If the following macro is set to 1, then NULL values are considered
** distinct when determining whether or not two entries are the same
** in a UNIQUE index.  This is the way PostgreSQL, Oracle, DB2, MySQL,
** OCELOT, and Firebird all work.  The SQL92 spec explicitly says this
** is the way things are suppose to work.
**
** If the following macro is set to 0, the NULLs are indistinct for
** a UNIQUE index.  In this mode, you can only have a single NULL entry
** for a column declared UNIQUE.  This is the way Informix and SQL Server
** work.
*/
#define NULL_DISTINCT_FOR_UNIQUE 1

/*
** The maximum number of attached databases.  This must be at least 2
** in order to support the main database file (0) and the file used to
** hold temporary tables (1).  And it must be less than 32 because
** we use a bitmask of databases with a u32 in places (for example
** the Parse.cookieMask field).
*/
#define MAX_ATTACHED 10

/*
** The maximum value of a ?nnn wildcard that the parser will accept.
*/
#define SQLITE_MAX_VARIABLE_NUMBER 999

/*
** When building SQLite for embedded systems where memory is scarce,
** you can define one or more of the following macros to omit extra
** features of the library and thus keep the size of the library to
** a minimum.
*/
/* #define SQLITE_OMIT_AUTHORIZATION  1 */
/* #define SQLITE_OMIT_MEMORYDB     1 */
/* #define SQLITE_OMIT_VACUUM         1 */
/* #define SQLITE_OMIT_DATETIME_FUNCS 1 */
/* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */
/* #define SQLITE_OMIT_AUTOVACUUM */
/* #define SQLITE_OMIT_ALTERTABLE */

/*
** Provide a default value for TEMP_STORE in case it is not specified
** on the command-line
*/
#ifndef TEMP_STORE
# define TEMP_STORE 1
#endif

/*
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
*/
#ifndef offsetof
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif

/*
** Integers of known sizes.  These typedefs might change for architectures
** where the sizes very.  Preprocessor macros are available so that the
** types can be conveniently redefined at compile-type.  Like this:
**
**         cc '-DUINTPTR_TYPE=long long int' ...
*/
#ifndef UINT64_TYPE
# if defined(_MSC_VER) || defined(__BORLANDC__)
#   define UINT64_TYPE unsigned __int64
# else
#   define UINT64_TYPE unsigned long long int
# endif
#endif
#ifndef UINT32_TYPE
# define UINT32_TYPE unsigned int
#endif
#ifndef UINT16_TYPE
# define UINT16_TYPE unsigned short int
#endif
#ifndef INT16_TYPE
# define INT16_TYPE short int
#endif
#ifndef UINT8_TYPE
# define UINT8_TYPE unsigned char
#endif
#ifndef INT8_TYPE
# define INT8_TYPE signed char
#endif
#ifndef LONGDOUBLE_TYPE
# define LONGDOUBLE_TYPE long double
#endif
#ifndef INTPTR_TYPE
# if SQLITE_PTR_SZ==4
#   define INTPTR_TYPE int
# else
#   define INTPTR_TYPE sqlite_int64
# endif
#endif
#ifndef UINTPTR_TYPE
# if SQLITE_PTR_SZ==4
#   define UINTPTR_TYPE unsigned int
# else
#   define UINTPTR_TYPE sqlite_uint64
# endif
#endif
typedef sqlite_int64 i64;          /* 8-byte signed integer */
typedef UINT64_TYPE u64;           /* 8-byte unsigned integer */
typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
typedef INT16_TYPE i16;            /* 2-byte signed integer */
typedef UINT8_TYPE u8;             /* 1-byte unsigned integer */
typedef UINT8_TYPE i8;             /* 1-byte signed integer */
typedef INTPTR_TYPE ptr;           /* Big enough to hold a pointer */
typedef UINTPTR_TYPE uptr;         /* Big enough to hold a pointer */

/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
extern const int sqlite3one;
#define SQLITE_BIGENDIAN    (*(char *)(&sqlite3one)==0)
#define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)

/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle. 
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
** callback is currently invoked only from within pager.c.
*/
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
  int (*xFunc)(void *,int);  /* The busy callback */
  void *pArg;                /* First arg to busy callback */
};

/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and 
** "BusyHandler typedefs.
*/
#include "vdbe.h"
#include "btree.h"

/*
** This macro casts a pointer to an integer.  Useful for doing
** pointer arithmetic.
*/
#define Addr(X)  ((uptr)X)

/*
** If memory allocation problems are found, recompile with
**
**      -DSQLITE_DEBUG=1
**
** to enable some sanity checking on malloc() and free().  To
** check for memory leaks, recompile with
**
**      -DSQLITE_DEBUG=2
**
** and a line of text will be written to standard error for
** each malloc() and free().  This output can be analyzed
** by an AWK script to determine if there are any leaks.
*/
#ifdef SQLITE_MEMDEBUG
# define sqliteMalloc(X)    sqlite3Malloc_(X,1,__FILE__,__LINE__)
# define sqliteMallocRaw(X) sqlite3Malloc_(X,0,__FILE__,__LINE__)
# define sqliteFree(X)      sqlite3Free_(X,__FILE__,__LINE__)
# define sqliteRealloc(X,Y) sqlite3Realloc_(X,Y,__FILE__,__LINE__)
# define sqliteStrDup(X)    sqlite3StrDup_(X,__FILE__,__LINE__)
# define sqliteStrNDup(X,Y) sqlite3StrNDup_(X,Y,__FILE__,__LINE__)
#else
# define sqliteFree          sqlite3FreeX
# define sqliteMalloc        sqlite3Malloc
# define sqliteMallocRaw     sqlite3MallocRaw
# define sqliteRealloc       sqlite3Realloc
# define sqliteStrDup        sqlite3StrDup
# define sqliteStrNDup       sqlite3StrNDup
#endif

/*
** This variable gets set if malloc() ever fails.  After it gets set,
** the SQLite library shuts down permanently.
*/
extern int sqlite3_malloc_failed;

/*
** The following global variables are used for testing and debugging
** only.  They only work if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_MEMDEBUG
extern int sqlite3_nMalloc;      /* Number of sqliteMalloc() calls */
extern int sqlite3_nFree;        /* Number of sqliteFree() calls */
extern int sqlite3_iMallocFail;  /* Fail sqliteMalloc() after this many calls */
extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
#endif

/*
** Name of the master database table.  The master database table
** is a special table that holds the names and attributes of all
** user tables and indices.
*/
#define MASTER_NAME       "sqlite_master"
#define TEMP_MASTER_NAME  "sqlite_temp_master"

/*
** The root-page of the master database table.
*/
#define MASTER_ROOT       1

/*
** The name of the schema table.
*/
#define SCHEMA_TABLE(x)  (x==1?TEMP_MASTER_NAME:MASTER_NAME)

/*
** A convenience macro that returns the number of elements in
** an array.
*/
#define ArraySize(X)    (sizeof(X)/sizeof(X[0]))

/*
** Forward references to structures
*/
typedef struct Column Column;
typedef struct Table Table;
typedef struct Index Index;
typedef struct Instruction Instruction;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct Parse Parse;
typedef struct Token Token;
typedef struct IdList IdList;
typedef struct SrcList SrcList;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;
typedef struct Select Select;
typedef struct AggExpr AggExpr;
typedef struct FuncDef FuncDef;
typedef struct Trigger Trigger;
typedef struct TriggerStep TriggerStep;
typedef struct TriggerStack TriggerStack;
typedef struct FKey FKey;
typedef struct Db Db;
typedef struct AuthContext AuthContext;
typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo;
typedef struct NameContext NameContext;
typedef struct Fetch Fetch;

/*
** Each database file to be accessed by the system is an instance
** of the following structure.  There are normally two of these structures
** in the sqlite.aDb[] array.  aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables.  Additional
** databases may be attached.
*/
struct Db {
  char *zName;         /* Name of this database */
  Btree *pBt;          /* The B*Tree structure for this database file */
  int schema_cookie;   /* Database schema version number for this file */
  Hash tblHash;        /* All tables indexed by name */
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */
  u16 flags;           /* Flags associated with this database */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u8 safety_level;     /* How aggressive at synching data to disk */
  int cache_size;      /* Number of pages to use in the cache */
  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
  void *pAux;               /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */
};

/*
** These macros can be used to test, set, or clear bits in the 
** Db.flags field.
*/
#define DbHasProperty(D,I,P)     (((D)->aDb[I].flags&(P))==(P))
#define DbHasAnyProperty(D,I,P)  (((D)->aDb[I].flags&(P))!=0)
#define DbSetProperty(D,I,P)     (D)->aDb[I].flags|=(P)
#define DbClearProperty(D,I,P)   (D)->aDb[I].flags&=~(P)

/*
** Allowed values for the DB.flags field.
**
** The DB_SchemaLoaded flag is set after the database schema has been
** read into internal hash tables.
**
** DB_UnresetViews means that one or more views have column names that
** have been filled out.  If the schema changes, these column names might
** changes and so the view will need to be reset.
*/
#define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
#define DB_UnresetViews    0x0002  /* Some views have defined column names */

#define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)

/*
** Each database is an instance of the following structure.
**
** The sqlite.lastRowid records the last insert rowid generated by an
** insert statement.  Inserts on views do not affect its value.  Each
** trigger has its own context, so that lastRowid can be updated inside
** triggers as usual.  The previous value will be restored once the trigger
** exits.  Upon entering a before or instead of trigger, lastRowid is no
** longer (since after version 2.8.12) reset to -1.
**
** The sqlite.nChange does not count changes within triggers and keeps no
** context.  It is reset at start of sqlite3_exec.
** The sqlite.lsChange represents the number of changes made by the last
** insert, update, or delete statement.  It remains constant throughout the
** length of a statement and is then updated by OP_SetCounts.  It keeps a
** context stack just like lastRowid so that the count of changes
** within a trigger is not seen outside the trigger.  Changes to views do not
** affect the value of lsChange.
** The sqlite.csChange keeps track of the number of current changes (since
** the last statement) and is used to update sqlite_lsChange.
**
** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16
** store the most recent error code and, if applicable, string. The
** internal function sqlite3Error() is used to set these variables
** consistently.
*/
struct sqlite3 {
  int nDb;                      /* Number of backends currently in use */
  Db *aDb;                      /* All backends */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
  int flags;                    /* Miscellanous flags. See below */
  u8 file_format;               /* What file format version is this database? */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  int nTable;                   /* Number of tables in the database */
  BusyHandler busyHandler;      /* Busy callback */
  void *pCommitArg;             /* Argument to xCommitCallback() */   
  int (*xCommitCallback)(void*);/* Invoked at every commit. */
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  Hash aCollSeq;                /* All collating sequences */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 priorNewRowid;            /* Last randomly generated ROWID */
  int magic;                    /* Magic number for detect library misuse */
  int nChange;                  /* Value returned by sqlite3_changes() */
  int nTotalChange;             /* Value returned by sqlite3_total_changes() */
  struct sqlite3InitInfo {      /* Information used during initialization */
    int iDb;                    /* When back is being initialized */
    int newTnum;                /* Rootpage of table being initialized */
    u8 busy;                    /* TRUE if currently initializing */
  } init;
  struct Vdbe *pVdbe;           /* List of active virtual machines */
  int activeVdbeCnt;            /* Number of vdbes currently executing */
  void (*xTrace)(void*,const char*);     /* Trace function */
  void *pTraceArg;                       /* Argument to the trace function */
#ifndef SQLITE_OMIT_AUTHORIZATION
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
                                /* Access authorization function */
  void *pAuthArg;               /* 1st argument to the access auth function */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int (*xProgress)(void *);     /* The progress callback */
  void *pProgressArg;           /* Argument to the progress callback */
  int nProgressOps;             /* Number of opcodes for progress callback */
#endif
  int errCode;                  /* Most recent error code (SQLITE_*) */
  u8 enc;                       /* Text encoding for this database. */
  u8 autoCommit;                /* The auto-commit flag. */
  void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
  void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
  void *pCollNeededArg;
  sqlite3_value *pValue;        /* Value used for transient conversions */
  sqlite3_value *pErr;          /* Most recent error message */
  char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
  char *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
};

/*
** Possible values for the sqlite.flags and or Db.flags fields.
**
** On sqlite.flags, the SQLITE_InTrans value means that we have
** executed a BEGIN.  On Db.flags, SQLITE_InTrans means a statement
** transaction is active on that particular database file.
*/
#define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
#define SQLITE_Initialized    0x00000002  /* True after initialization */
#define SQLITE_Interrupt      0x00000004  /* Cancel current operation */
#define SQLITE_InTrans        0x00000008  /* True if in a transaction */
#define SQLITE_InternChanges  0x00000010  /* Uncommitted Hash table changes */
#define SQLITE_FullColNames   0x00000020  /* Show full column names on SELECT */
#define SQLITE_ShortColNames  0x00000040  /* Show short columns names */
#define SQLITE_CountRows      0x00000080  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_SqlTrace       0x00000200  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x00000400  /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema    0x00000800  /* OK to update SQLITE_MASTER */
#define SQLITE_NoReadlock     0x00001000  /* Readlocks are omitted when 
                                          ** accessing read-only databases */

/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */
#define SQLITE_MAGIC_CLOSED   0x9f3c2d33  /* Database is closed */
#define SQLITE_MAGIC_BUSY     0xf03b7906  /* Database currently in use */
#define SQLITE_MAGIC_ERROR    0xb5357930  /* An SQLITE_MISUSE error occurred */

/*
** Each SQL function is defined by an instance of the following
** structure.  A pointer to this structure is stored in the sqlite.aFunc
** hash table.  When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct FuncDef {
  char *zName;         /* SQL name of the function */
  int nArg;            /* Number of arguments.  -1 means unlimited */
  u8 iPrefEnc;         /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
  void *pUserData;     /* User data parameter */
  FuncDef *pNext;      /* Next function with same name */
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
  void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
  void (*xFinalize)(sqlite3_context*);                /* Aggregate finializer */
  u8 needCollSeq;      /* True if sqlite3GetFuncCollSeq() might be called */
};

/*
** information about each column of an SQL table is held in an instance
** of this structure.
*/
struct Column {
  char *zName;     /* Name of this column */
  Expr *pDflt;     /* Default value of this column */
  char *zType;     /* Data type for this column */
  CollSeq *pColl;  /* Collating sequence.  If NULL, use the default */
  u8 notNull;      /* True if there is a NOT NULL constraint */
  u8 isPrimKey;    /* True if this column is part of the PRIMARY KEY */
  char affinity;   /* One of the SQLITE_AFF_... values */
};

/*
** A "Collating Sequence" is defined by an instance of the following
** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence.
**
** There may two seperate implementations of the collation function, one
** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
** native byte order. When a collation sequence is invoked, SQLite selects
** the version that will require the least expensive encoding
** transalations, if any.
**
** The CollSeq.pUser member variable is an extra parameter that passed in
** as the first argument to the UTF-8 comparison function, xCmp.
** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
** xCmp16.
**
** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
** collating sequence is undefined.  Indices built on an undefined
** collating sequence may not be read or written.
*/
struct CollSeq {
  char *zName;         /* Name of the collating sequence, UTF-8 encoded */
  u8 enc;              /* Text encoding handled by xCmp() */
  void *pUser;         /* First argument to xCmp() */
  int (*xCmp)(void*,int, const void*, int, const void*);
};

/*
** A sort order can be either ASC or DESC.
*/
#define SQLITE_SO_ASC       0  /* Sort in ascending order */
#define SQLITE_SO_DESC      1  /* Sort in ascending order */

/*
** Column affinity types.
*/
#define SQLITE_AFF_INTEGER  'i'
#define SQLITE_AFF_NUMERIC  'n'
#define SQLITE_AFF_TEXT     't'
#define SQLITE_AFF_NONE     'o'


/*
** Each SQL table is represented in memory by an instance of the
** following structure.
**
** Table.zName is the name of the table.  The case of the original
** CREATE TABLE statement is stored, but case is not significant for
** comparisons.
**
** Table.nCol is the number of columns in this table.  Table.aCol is a
** pointer to an array of Column structures, one for each column.
**
** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
** the column that is that key.   Otherwise Table.iPKey is negative.  Note
** that the datatype of the PRIMARY KEY must be INTEGER for this field to
** be set.  An INTEGER PRIMARY KEY is used as the rowid for each row of
** the table.  If a table has no INTEGER PRIMARY KEY, then a random rowid
** is generated for each row of the table.  Table.hasPrimKey is true if
** the table has any PRIMARY KEY, INTEGER or otherwise.
**
** Table.tnum is the page number for the root BTree page of the table in the
** database file.  If Table.iDb is the index of the database table backend
** in sqlite.aDb[].  0 is for the main database and 1 is for the file that
** holds temporary tables and indices.  If Table.isTransient
** is true, then the table is stored in a file that is automatically deleted
** when the VDBE cursor to the table is closed.  In this case Table.tnum 
** refers VDBE cursor number that holds the table open, not to the root
** page number.  Transient tables are used to hold the results of a
** sub-query that appears instead of a real table name in the FROM clause 
** of a SELECT statement.
*/
struct Table {
  char *zName;     /* Name of the table */
  int nCol;        /* Number of columns in this table */
  Column *aCol;    /* Information about each column */
  int iPKey;       /* If not less then 0, use aCol[iPKey] as the primary key */
  Index *pIndex;   /* List of SQL indexes on this table. */
  int tnum;        /* Root BTree node for this table (see note above) */
  Select *pSelect; /* NULL for tables.  Points to definition if a view. */
  u8 readOnly;     /* True if this table should not be written by the user */
  u8 iDb;          /* Index into sqlite.aDb[] of the backend for this table */
  u8 isTransient;  /* True if automatically deleted when VDBE finishes */
  u8 hasPrimKey;   /* True if there exists a primary key */
  u8 keyConf;      /* What to do in case of uniqueness conflict on iPKey */
  u8 autoInc;      /* True if the integer primary key is autoincrement */
  Trigger *pTrigger; /* List of SQL triggers on this table */
  FKey *pFKey;       /* Linked list of all foreign keys in this table */
  char *zColAff;     /* String defining the affinity of each column */
};

/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
** key.  The "to" table is the table that is named in the REFERENCES clause.
** Consider this example:
**
**     CREATE TABLE ex1(
**       a INTEGER PRIMARY KEY,
**       b INTEGER CONSTRAINT fk1 REFERENCES ex2(x)
**     );
**
** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
**
** Each REFERENCES clause generates an instance of the following structure
** which is attached to the from-table.  The to-table need not exist when
** the from-table is created.  The existance of the to-table is not checked
** until an attempt is made to insert data into the from-table.
**
** The sqlite.aFKey hash table stores pointers to this structure
** given the name of a to-table.  For each to-table, all foreign keys
** associated with that table are on a linked list using the FKey.pNextTo
** field.
*/
struct FKey {
  Table *pFrom;     /* The table that constains the REFERENCES clause */
  FKey *pNextFrom;  /* Next foreign key in pFrom */
  char *zTo;        /* Name of table that the key points to */
  FKey *pNextTo;    /* Next foreign key that points to zTo */
  int nCol;         /* Number of columns in this key */
  struct sColMap {  /* Mapping of columns in pFrom to columns in zTo */
    int iFrom;         /* Index of column in pFrom */
    char *zCol;        /* Name of column in zTo.  If 0 use PRIMARY KEY */
  } *aCol;          /* One entry for each of nCol column s */
  u8 isDeferred;    /* True if constraint checking is deferred till COMMIT */
  u8 updateConf;    /* How to resolve conflicts that occur on UPDATE */
  u8 deleteConf;    /* How to resolve conflicts that occur on DELETE */
  u8 insertConf;    /* How to resolve conflicts that occur on INSERT */
};

/*
** SQLite supports many different ways to resolve a contraint
** error.  ROLLBACK processing means that a constraint violation
** causes the operation in process to fail and for the current transaction
** to be rolled back.  ABORT processing means the operation in process
** fails and any prior changes from that one operation are backed out,
** but the transaction is not rolled back.  FAIL processing means that
** the operation in progress stops and returns an error code.  But prior
** changes due to the same operation are not backed out and no rollback
** occurs.  IGNORE means that the particular row that caused the constraint
** error is not inserted or updated.  Processing continues and no error
** is returned.  REPLACE means that preexisting database rows that caused
** a UNIQUE constraint violation are removed so that the new insert or
** update can proceed.  Processing continues and no error is reported.
**
** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys.
** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the
** same as ROLLBACK for DEFERRED keys.  SETNULL means that the foreign
** key is set to NULL.  CASCADE means that a DELETE or UPDATE of the
** referenced table row is propagated into the row that holds the
** foreign key.
** 
** The following symbolic values are used to record which type
** of action to take.
*/
#define OE_None     0   /* There is no constraint to check */
#define OE_Rollback 1   /* Fail the operation and rollback the transaction */
#define OE_Abort    2   /* Back out changes but do no rollback transaction */
#define OE_Fail     3   /* Stop the operation but leave all prior changes */
#define OE_Ignore   4   /* Ignore the error. Do not do the INSERT or UPDATE */
#define OE_Replace  5   /* Delete existing record, then do INSERT or UPDATE */

#define OE_Restrict 6   /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
#define OE_SetNull  7   /* Set the foreign key value to NULL */
#define OE_SetDflt  8   /* Set the foreign key value to its default */
#define OE_Cascade  9   /* Cascade the changes */

#define OE_Default  99  /* Do whatever the default action is */


/*
** An instance of the following structure is passed as the first
** argument to sqlite3VdbeKeyCompare and is used to control the 
** comparison of the two index keys.
**
** If the KeyInfo.incrKey value is true and the comparison would
** otherwise be equal, then return a result as if the second key larger.
*/
struct KeyInfo {
  u8 enc;             /* Text encoding - one of the TEXT_Utf* values */
  u8 incrKey;         /* Increase 2nd key by epsilon before comparison */
  int nField;         /* Number of entries in aColl[] */
  u8 *aSortOrder;     /* If defined an aSortOrder[i] is true, sort DESC */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
};

/*
** Each SQL index is represented in memory by an
** instance of the following structure.
**
** The columns of the table that are to be indexed are described
** by the aiColumn[] field of this structure.  For example, suppose
** we have the following table and index:
**
**     CREATE TABLE Ex1(c1 int, c2 int, c3 text);
**     CREATE INDEX Ex2 ON Ex1(c3,c1);
**
** In the Table structure describing Ex1, nCol==3 because there are
** three columns in the table.  In the Index structure describing
** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
** The value of aiColumn is {2, 0}.  aiColumn[0]==2 because the 
** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
** The second column to be indexed (c1) has an index of 0 in
** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
**
** The Index.onError field determines whether or not the indexed columns
** must be unique and what to do if they are not.  When Index.onError=OE_None,
** it means this is not a unique index.  Otherwise it is a unique index
** and the value of Index.onError indicate the which conflict resolution 
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
*/
struct Index {
  char *zName;     /* Name of this index */
  int nColumn;     /* Number of columns in the table used by this index */
  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
  u8 iDb;          /* Index in sqlite.aDb[] of where this index is stored */
  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  KeyInfo keyInfo; /* Info on how to order keys.  MUST BE LAST */
};

/*
** Each token coming out of the lexer is an instance of
** this structure.  Tokens are also used as part of an expression.
**
** Note if Token.z==0 then Token.dyn and Token.n are undefined and
** may contain random values.  Do not make any assuptions about Token.dyn
** and Token.n when Token.z==0.
*/
struct Token {
  const unsigned char *z; /* Text of the token.  Not NULL-terminated! */
  unsigned dyn  : 1;      /* True for malloced memory, false for static */
  unsigned n    : 31;     /* Number of characters in this token */
};

/*
** Each node of an expression in the parse tree is an instance
** of this structure.
**
** Expr.op is the opcode.  The integer parser token codes are reused
** as opcodes here.  For example, the parser defines TK_GE to be an integer
** code representing the ">=" operator.  This same integer code is reused
** to represent the greater-than-or-equal-to operator in the expression
** tree.
**
** Expr.pRight and Expr.pLeft are subexpressions.  Expr.pList is a list
** of argument if the expression is a function.
**
** Expr.token is the operator token for this node.  For some expressions
** that have subexpressions, Expr.token can be the complete text that gave
** rise to the Expr.  In the latter case, the token is marked as being
** a compound token.
**
** An expression of the form ID or ID.ID refers to a column in a table.
** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is
** the integer cursor number of a VDBE cursor pointing to that table and
** Expr.iColumn is the column number for the specific column.  If the
** expression is used as a result in an aggregate SELECT, then the
** value is also stored in the Expr.iAgg column in the aggregate so that
** it can be accessed after all aggregates are computed.
**
** If the expression is a function, the Expr.iTable is an integer code
** representing which function.  If the expression is an unbound variable
** marker (a question mark character '?' in the original SQL) then the
** Expr.iTable holds the index number for that variable.
**
** If the expression is a subquery then Expr.iColumn holds an integer
** register number containing the result of the subquery.  If the
** subquery gives a constant result, then iTable is -1.  If the subquery
** gives a different answer at different times during statement processing
** then iTable is the address of a subroutine that computes the subquery.
**
** The Expr.pSelect field points to a SELECT statement.  The SELECT might
** be the right operand of an IN operator.  Or, if a scalar SELECT appears
** in an expression the opcode is TK_SELECT and Expr.pSelect is the only
** operand.
*/
struct Expr {
  u8 op;                 /* Operation performed by this node */
  char affinity;         /* The affinity of the column or 0 if not a column */
  u8 iDb;                /* Database referenced by this expression */
  u8 flags;              /* Various flags.  See below */
  CollSeq *pColl;        /* The collation type of the column or 0 */
  Expr *pLeft, *pRight;  /* Left and right subnodes */
  ExprList *pList;       /* A list of expressions used as function arguments
                         ** or in "<expr> IN (<expr-list)" */
  Token token;           /* An operand token */
  Token span;            /* Complete text of the expression */
  int iTable, iColumn;   /* When op==TK_COLUMN, then this expr node means the
                         ** iColumn-th field of the iTable-th table. */
  int iAgg;              /* When op==TK_COLUMN and pParse->fillAgg==FALSE, pull
                         ** result from the iAgg-th element of the aggregator */
  int iAggCtx;           /* The value to pass as P1 of OP_AggGet. */
  Select *pSelect;       /* When the expression is a sub-select.  Also the
                         ** right side of "<expr> IN (<select>)" */
};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin     0x0001  /* Originated in ON or USING clause of a join */
#define EP_Agg          0x0002  /* Contains one or more aggregate functions */
#define EP_Resolved     0x0004  /* IDs have been resolved to COLUMNs */
#define EP_Error        0x0008  /* Expression contains one or more errors */
#define EP_Not          0x0010  /* Operator preceeded by NOT */
#define EP_VarSelect    0x0020  /* pSelect is correlated, not constant */

/*
** These macros can be used to test, set, or clear bits in the 
** Expr.flags field.
*/
#define ExprHasProperty(E,P)     (((E)->flags&(P))==(P))
#define ExprHasAnyProperty(E,P)  (((E)->flags&(P))!=0)
#define ExprSetProperty(E,P)     (E)->flags|=(P)
#define ExprClearProperty(E,P)   (E)->flags&=~(P)

/*
** A list of expressions.  Each expression may optionally have a
** name.  An expr/name combination can be used in several ways, such
** as the list of "expr AS ID" fields following a "SELECT" or in the
** list of "ID = expr" items in an UPDATE.  A list of expressions can
** also be used as the argument to a function, in which case the a.zName
** field is not used.
*/
struct ExprList {
  int nExpr;             /* Number of expressions on the list */
  int nAlloc;            /* Number of entries allocated below */
  struct ExprList_item {
    Expr *pExpr;           /* The list of expressions */
    char *zName;           /* Token associated with this expression */
    u8 sortOrder;          /* 1 for DESC or 0 for ASC */
    u8 isAgg;              /* True if this is an aggregate like count(*) */
    u8 done;               /* A flag to indicate when processing is finished */
  } *a;                  /* One entry for each expression */
};

/*
** An instance of this structure can hold a simple list of identifiers,
** such as the list "a,b,c" in the following statements:
**
**      INSERT INTO t(a,b,c) VALUES ...;
**      CREATE INDEX idx ON t(a,b,c);
**      CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...;
**
** The IdList.a.idx field is used when the IdList represents the list of
** column names after a table name in an INSERT statement.  In the statement
**
**     INSERT INTO t(a,b,c) ...
**
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {
  int nId;         /* Number of identifiers on the list */
  int nAlloc;      /* Number of entries allocated for a[] below */
  struct IdList_item {
    char *zName;      /* Name of the identifier */
    int idx;          /* Index in some Table.aCol[] of a column named zName */
  } *a;
};

/*
** The bitmask datatype defined below is used for various optimizations.
*/
typedef unsigned int Bitmask;

/*
** The following structure describes the FROM clause of a SELECT statement.
** Each table or subquery in the FROM clause is a separate element of
** the SrcList.a[] array.
**
** With the addition of multiple database support, the following structure
** can also be used to describe a particular table such as the table that
** is modified by an INSERT, DELETE, or UPDATE statement.  In standard SQL,
** such a table must be a simple name: ID.  But in SQLite, the table can
** now be identified by a database name, a dot, then the table name: ID.ID.
*/
struct SrcList {
  i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
  i16 nAlloc;      /* Number of entries allocated in a[] below */
  struct SrcList_item {
    char *zDatabase;  /* Name of database holding this table */
    char *zName;      /* Name of the table */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */
    int jointype;     /* Type of join between this table and the next */
    int iCursor;      /* The VDBE cursor number used to access this table */
    Expr *pOn;        /* The ON clause of a join */
    IdList *pUsing;   /* The USING clause of a join */
    Bitmask colUsed;  /* Bit N (1<<N) set if column N or pTab is used */
  } a[1];             /* One entry for each identifier on the list */
};

/*
** Permitted values of the SrcList.a.jointype field
*/
#define JT_INNER     0x0001    /* Any kind of inner or cross join */
#define JT_NATURAL   0x0002    /* True for a "natural" join */
#define JT_LEFT      0x0004    /* Left outer join */
#define JT_RIGHT     0x0008    /* Right outer join */
#define JT_OUTER     0x0010    /* The "OUTER" keyword is present */
#define JT_ERROR     0x0020    /* unknown or unsupported join type */

/*
** For each nested loop in a WHERE clause implementation, the WhereInfo
** structure contains a single instance of this structure.  This structure
** is intended to be private the the where.c module and should not be
** access or modified by other modules.
*/
struct WhereLevel {
  int iMem;            /* Memory cell used by this level */
  Index *pIdx;         /* Index used.  NULL if no index */
  int iTabCur;         /* The VDBE cursor used to access the table */
  int iIdxCur;         /* The VDBE cursor used to acesss pIdx */
  int score;           /* How well this index scored */
  int brk;             /* Jump here to break out of the loop */
  int cont;            /* Jump here to continue with the next loop cycle */
  int op, p1, p2;      /* Opcode used to terminate the loop */
  int iLeftJoin;       /* Memory cell used to implement LEFT OUTER JOIN */
  int top;             /* First instruction of interior of the loop */
  int inOp, inP1, inP2;/* Opcode used to implement an IN operator */
  int bRev;            /* Do the scan in the reverse direction */
};

/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed
** into the second half to give some continuity.
*/
struct WhereInfo {
  Parse *pParse;
  SrcList *pTabList;   /* List of tables in the join */
  int iTop;            /* The very beginning of the WHERE loop */
  int iContinue;       /* Jump here to continue with next record */
  int iBreak;          /* Jump here to break out of the loop */
  int nLevel;          /* Number of nested loop */
  WhereLevel a[1];     /* Information about each nest loop in the WHERE */
};

/*
** A NameContext defines a context in which to resolve table and column
** names.  The context consists of a list of tables (the pSrcList) field and
** a list of named expression (pEList).  The named expression list may
** be NULL.  The pSrc corresponds to the FROM clause of a SELECT or
** to the table being operated on by INSERT, UPDATE, or DELETE.  The
** pEList corresponds to the result set of a SELECT and is NULL for
** other statements.
**
** NameContexts can be nested.  When resolving names, the inner-most 
** context is searched first.  If no match is found, the next outer
** context is checked.  If there is still no match, the next context
** is checked.  This process continues until either a match is found
** or all contexts are check.  When a match is found, the nRef member of
** the context containing the match is incremented. 
**
** Each subquery gets a new NameContext.  The pNext field points to the
** NameContext in the parent query.  Thus the process of scanning the
** NameContext list corresponds to searching through successively outer
** subqueries looking for a match.
*/
struct NameContext {
  Parse *pParse;       /* The parser */
  SrcList *pSrcList;   /* One or more tables used to resolve names */
  ExprList *pEList;    /* Optional list of named expressions */
  int nRef;            /* Number of names resolved by this context */
  int nErr;            /* Number of errors encountered while resolving names */
  u8 allowAgg;         /* Aggregate functions allowed here */
  u8 hasAgg;
  int nDepth;          /* Depth of subquery recursion. 1 for no recursion */
  NameContext *pNext;  /* Next outer name context.  NULL for outermost */
};

/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
** limit and nOffset to the value of the offset (or 0 if there is not
** offset).  But later on, nLimit and nOffset become the memory locations
** in the VDBE that record the limit and offset counters.
*/
struct Select {
  ExprList *pEList;      /* The fields of the result */
  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  u8 isDistinct;         /* True if the DISTINCT keyword is present */
  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
  Select *pPrior;        /* Prior select in a compound select statement */
  Expr *pLimit;          /* LIMIT expression. NULL means not used. */
  Expr *pOffset;         /* OFFSET expression. NULL means not used. */
  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
  IdList **ppOpenTemp;   /* OP_OpenTemp addresses used by multi-selects */
  Fetch *pFetch;         /* If this stmt is part of a FETCH command */
  u8 isResolved;         /* True once sqlite3SelectResolve() has run. */
  u8 isAgg;              /* True if this is an aggregate query */
};

/*
** The results of a select can be distributed in several ways.
*/
#define SRT_Callback     1  /* Invoke a callback with each row of result */
#define SRT_Mem          2  /* Store result in a memory cell */
#define SRT_Set          3  /* Store result as unique keys in a table */
#define SRT_Union        5  /* Store result as keys in a table */
#define SRT_Except       6  /* Remove result from a UNION table */
#define SRT_Table        7  /* Store result as data with a unique key */
#define SRT_TempTable    8  /* Store result in a trasient table */
#define SRT_Discard      9  /* Do not save the results anywhere */
#define SRT_Sorter      10  /* Store results in the sorter */
#define SRT_Subroutine  11  /* Call a subroutine to handle results */
#define SRT_Exists      12  /* Put 0 or 1 in a memory cell */

/*
** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
** we have to do some additional analysis of expressions.  An instance
** of the following structure holds information about a single subexpression
** somewhere in the SELECT statement.  An array of these structures holds
** all the information we need to generate code for aggregate
** expressions.
**
** Note that when analyzing a SELECT containing aggregates, both
** non-aggregate field variables and aggregate functions are stored
** in the AggExpr array of the Parser structure.
**
** The pExpr field points to an expression that is part of either the
** field list, the GROUP BY clause, the HAVING clause or the ORDER BY
** clause.  The expression will be freed when those clauses are cleaned
** up.  Do not try to delete the expression attached to AggExpr.pExpr.
**
** If AggExpr.pExpr==0, that means the expression is "count(*)".
*/
struct AggExpr {
  int isAgg;        /* if TRUE contains an aggregate function */
  Expr *pExpr;      /* The expression */
  FuncDef *pFunc;   /* Information about the aggregate function */
};

/*
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
**
** The structure is divided into two parts.  When the parser and code
** generate call themselves recursively, the first part of the structure
** is constant but the second part is reset at the beginning and end of
** each recursion.
*/
struct Parse {
  sqlite3 *db;         /* The main database structure */
  int rc;              /* Return code from execution */
  char *zErrMsg;       /* An error message */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 nameClash;        /* A permanent table name clashes with temp table name */
  u8 checkSchema;      /* Causes schema cookie check after an error */
  u8 nested;           /* Number of nested calls to the parser/code generator */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  u32 cookieMask;      /* Bitmask of schema verified databases */
  int cookieValue[MAX_ATTACHED+2];  /* Values of cookies to verify */
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  u32 writeMask;       /* Start a write transaction on these databases */
  u8 fillAgg;          /* If true, ignore the Expr.iAgg field. Normally false */

  /* Above is constant between recursions.  Below is reset before and after
  ** each recursion */

  int nVar;            /* Number of '?' variables seen in the SQL so far */
  int nVarExpr;        /* Number of used slots in apVarExpr[] */
  int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
  Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
  u8 explain;          /* True if the EXPLAIN flag is found on the query */
  Token sErrToken;     /* The token at which the error occurred */
  Token sNameToken;    /* Token with unqualified schema object name */
  Token sLastToken;    /* The last token parsed */
  const char *zSql;    /* All SQL text */
  const char *zTail;   /* All SQL text past the last semicolon parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  TriggerStack *trigStack;  /* Trigger actions being coded */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
  int nAgg;            /* Number of aggregate expressions */
  AggExpr *aAgg;       /* An array of aggregate expressions */
  int nMaxDepth;       /* Maximum depth of subquery recursion */
};

/*
** An instance of the following structure can be declared on a stack and used
** to save the Parse.zAuthContext value so that it can be restored later.
*/
struct AuthContext {
  const char *zAuthContext;   /* Put saved Parse.zAuthContext here */
  Parse *pParse;              /* The Parse structure */
};

/*
** Bitfield flags for P2 value in OP_PutIntKey and OP_Delete
*/
#define OPFLAG_NCHANGE   1    /* Set to update db->nChange */
#define OPFLAG_LASTROWID 2    /* Set to update db->lastRowid */

/*
 * Each trigger present in the database schema is stored as an instance of
 * struct Trigger. 
 *
 * Pointers to instances of struct Trigger are stored in two ways.
 * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
 *    database). This allows Trigger structures to be retrieved by name.
 * 2. All triggers associated with a single table form a linked list, using the
 *    pNext member of struct Trigger. A pointer to the first element of the
 *    linked list is stored as the "pTrigger" member of the associated
 *    struct Table.
 *
 * The "step_list" member points to the first element of a linked list
 * containing the SQL statements specified as the trigger program.
 */
struct Trigger {
  char *name;             /* The name of the trigger                        */
  char *table;            /* The table or view to which the trigger applies */
  u8 iDb;                 /* Database containing this trigger               */
  u8 iTabDb;              /* Database containing Trigger.table              */
  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
  u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
  IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
                             the <column-list> is stored here */
  int foreach;            /* One of TK_ROW or TK_STATEMENT */
  Token nameToken;        /* Token containing zName. Use during parsing only */

  TriggerStep *step_list; /* Link list of trigger program steps             */
  Trigger *pNext;         /* Next trigger associated with the table */
};

/*
** A trigger is either a BEFORE or an AFTER trigger.  The following constants
** determine which. 
**
** If there are multiple triggers, you might of some BEFORE and some AFTER.
** In that cases, the constants below can be ORed together.
*/
#define TRIGGER_BEFORE  1
#define TRIGGER_AFTER   2

/*
 * An instance of struct TriggerStep is used to store a single SQL statement
 * that is a part of a trigger-program. 
 *
 * Instances of struct TriggerStep are stored in a singly linked list (linked
 * using the "pNext" member) referenced by the "step_list" member of the 
 * associated struct Trigger instance. The first element of the linked list is
 * the first step of the trigger-program.
 * 
 * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
 * "SELECT" statement. The meanings of the other members is determined by the 
 * value of "op" as follows:
 *
 * (op == TK_INSERT)
 * orconf    -> stores the ON CONFLICT algorithm
 * pSelect   -> If this is an INSERT INTO ... SELECT ... statement, then
 *              this stores a pointer to the SELECT statement. Otherwise NULL.
 * target    -> A token holding the name of the table to insert into.
 * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
 *              this stores values to be inserted. Otherwise NULL.
 * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ... 
 *              statement, then this stores the column-names to be
 *              inserted into.
 *
 * (op == TK_DELETE)
 * target    -> A token holding the name of the table to delete from.
 * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
 *              Otherwise NULL.
 * 
 * (op == TK_UPDATE)
 * target    -> A token holding the name of the table to update rows of.
 * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
 *              Otherwise NULL.
 * pExprList -> A list of the columns to update and the expressions to update
 *              them to. See sqlite3Update() documentation of "pChanges"
 *              argument.
 * 
 */
struct TriggerStep {
  int op;              /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
  int orconf;          /* OE_Rollback etc. */
  Trigger *pTrig;      /* The trigger that this step is a part of */

  Select *pSelect;     /* Valid for SELECT and sometimes 
			  INSERT steps (when pExprList == 0) */
  Token target;        /* Valid for DELETE, UPDATE, INSERT steps */
  Expr *pWhere;        /* Valid for DELETE, UPDATE steps */
  ExprList *pExprList; /* Valid for UPDATE statements and sometimes 
			   INSERT steps (when pSelect == 0)         */
  IdList *pIdList;     /* Valid for INSERT statements only */

  TriggerStep * pNext; /* Next in the link-list */
};

/*
 * An instance of struct TriggerStack stores information required during code
 * generation of a single trigger program. While the trigger program is being
 * coded, its associated TriggerStack instance is pointed to by the
 * "pTriggerStack" member of the Parse structure.
 *
 * The pTab member points to the table that triggers are being coded on. The 
 * newIdx member contains the index of the vdbe cursor that points at the temp
 * table that stores the new.* references. If new.* references are not valid
 * for the trigger being coded (for example an ON DELETE trigger), then newIdx
 * is set to -1. The oldIdx member is analogous to newIdx, for old.* references.
 *
 * The ON CONFLICT policy to be used for the trigger program steps is stored 
 * as the orconf member. If this is OE_Default, then the ON CONFLICT clause 
 * specified for individual triggers steps is used.
 *
 * struct TriggerStack has a "pNext" member, to allow linked lists to be
 * constructed. When coding nested triggers (triggers fired by other triggers)
 * each nested trigger stores its parent trigger's TriggerStack as the "pNext" 
 * pointer. Once the nested trigger has been coded, the pNext value is restored
 * to the pTriggerStack member of the Parse stucture and coding of the parent
 * trigger continues.
 *
 * Before a nested trigger is coded, the linked list pointed to by the 
 * pTriggerStack is scanned to ensure that the trigger is not about to be coded
 * recursively. If this condition is detected, the nested trigger is not coded.
 */
struct TriggerStack {
  Table *pTab;         /* Table that triggers are currently being coded on */
  int newIdx;          /* Index of vdbe cursor to "new" temp table */
  int oldIdx;          /* Index of vdbe cursor to "old" temp table */
  int orconf;          /* Current orconf policy */
  int ignoreJump;      /* where to jump to for a RAISE(IGNORE) */
  Trigger *pTrigger;   /* The trigger currently being coded */
  TriggerStack *pNext; /* Next trigger down on the trigger stack */
};

/*
** The following structure contains information used by the sqliteFix...
** routines as they walk the parse tree to make database references
** explicit.  
*/
typedef struct DbFixer DbFixer;
struct DbFixer {
  Parse *pParse;      /* The parsing context.  Error messages written here */
  const char *zDb;    /* Make sure all objects are contained in this database */
  const char *zType;  /* Type of the container - used for error messages */
  const Token *pName; /* Name of the container - used for error messages */
};

/*
** A pointer to this structure is used to communicate information
** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
*/
typedef struct {
  sqlite3 *db;        /* The database being initialized */
  char **pzErrMsg;    /* Error message stored here */
} InitData;

/*
 * This global flag is set for performance testing of triggers. When it is set
 * SQLite will perform the overhead of building new and old trigger references 
 * even when no triggers exist
 */
extern int sqlite3_always_code_trigger_setup;

/*
** Internal function prototypes
*/
int sqlite3StrICmp(const char *, const char *);
int sqlite3StrNICmp(const char *, const char *, int);
int sqlite3HashNoCase(const char *, int);
int sqlite3IsNumber(const char*, int*, u8);
int sqlite3Compare(const char *, const char *);
int sqlite3SortCompare(const char *, const char *);
void sqlite3RealToSortable(double r, char *);
#ifdef SQLITE_MEMDEBUG
  void *sqlite3Malloc_(int,int,char*,int);
  void sqlite3Free_(void*,char*,int);
  void *sqlite3Realloc_(void*,int,char*,int);
  char *sqlite3StrDup_(const char*,char*,int);
  char *sqlite3StrNDup_(const char*, int,char*,int);
  void sqlite3CheckMemory(void*,int);
#else
  void *sqlite3Malloc(int);
  void *sqlite3MallocRaw(int);
  void sqlite3Free(void*);
  void *sqlite3Realloc(void*,int);
  char *sqlite3StrDup(const char*);
  char *sqlite3StrNDup(const char*, int);
# define sqlite3CheckMemory(a,b)
#endif
void sqlite3FreeX(void*);
char *sqlite3MPrintf(const char*, ...);
char *sqlite3VMPrintf(const char*, va_list);
void sqlite3DebugPrintf(const char*, ...);
void *sqlite3TextToPtr(const char*);
void sqlite3SetString(char **, const char *, ...);
void sqlite3ErrorMsg(Parse*, const char*, ...);
void sqlite3Dequote(char*);
int sqlite3KeywordCode(const char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
void sqlite3FinishCoding(Parse*);
Expr *sqlite3Expr(int, Expr*, Expr*, const Token*);
Expr *sqlite3RegisterExpr(Parse*,Token*);
Expr *sqlite3ExprAnd(Expr*, Expr*);
void sqlite3ExprSpan(Expr*,Token*,Token*);
Expr *sqlite3ExprFunction(ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
void sqlite3ExprDelete(Expr*);
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
void sqlite3ExprListDelete(ExprList*);
int sqlite3Init(sqlite3*, char**);
int sqlite3InitCallback(void*, int, char**, char**);
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
void sqlite3ResetInternalSchema(sqlite3*, int);
void sqlite3BeginParse(Parse*,int);
void sqlite3RollbackInternalChanges(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*);
Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
void sqlite3OpenMasterTable(Vdbe *v, int);
void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
void sqlite3AddColumn(Parse*,Token*);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int);
void sqlite3AddColumnType(Parse*,Token*,Token*);
void sqlite3AddDefaultValue(Parse*,Expr*);
void sqlite3AddCollateType(Parse*, const char*, int);
void sqlite3EndTable(Parse*,Token*,Select*);

#ifndef SQLITE_OMIT_VIEW
  void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int);
  int sqlite3ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite3ViewGetColumnNames(A,B) 0
#endif

void sqlite3DropTable(Parse*, SrcList*, int);
void sqlite3DeleteTable(sqlite3*, Table*);
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
IdList *sqlite3IdListAppend(IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*);
SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
void sqlite3SrcListAddAlias(SrcList*, Token*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(IdList*);
void sqlite3SrcListDelete(SrcList*);
void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                        Token*);
void sqlite3DropIndex(Parse*, SrcList*);
void sqlite3AddKeyType(Vdbe*, ExprList*);
void sqlite3AddIdxKeyType(Vdbe*, Index*);
int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
                        int,Expr*,Expr*);
void sqlite3SelectDelete(Select*);
void sqlite3SelectUnbind(Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*);
void sqlite3OpenTable(Vdbe*, int iCur, Table*, int);
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, Fetch*);
void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCode(Parse*, Expr*);
void sqlite3ExprCodeAndCache(Parse*, Expr*);
int sqlite3ExprCodeExprList(Parse*, ExprList*);
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
void sqlite3NextedParse(Parse*, const char*, ...);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
Table *sqlite3LocateTable(Parse*,const char*, const char*);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*, Token*);
int sqlite3RunVacuum(char**, sqlite3*);
char *sqlite3NameFromToken(Token*);
int sqlite3ExprCheck(Parse*, Expr*, int, int*);
int sqlite3ExprCompare(Expr*, Expr*);
int sqliteFuncId(Token*);
int sqlite3ExprResolveNames(NameContext *, Expr *);
int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
Vdbe *sqlite3GetVdbe(Parse*);
void sqlite3Randomness(int, void*);
void sqlite3RollbackAll(sqlite3*);
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3BeginTransaction(Parse*, int);
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);
void sqlite3GenerateRowIndexDelete(sqlite3*, Vdbe*, Table*, int, char*);
void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
void sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
void sqlite3BeginWriteOperation(Parse*, int, int);
Expr *sqlite3ExprDup(Expr*);
void sqlite3TokenCopy(Token*, Token*);
ExprList *sqlite3ExprListDup(ExprList*);
SrcList *sqlite3SrcListDup(SrcList*);
IdList *sqlite3IdListDup(IdList*);
Select *sqlite3SelectDup(Select*);
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
void sqlite3RegisterBuiltinFunctions(sqlite3*);
void sqlite3RegisterDateTimeFunctions(sqlite3*);
int sqlite3SafetyOn(sqlite3*);
int sqlite3SafetyOff(sqlite3*);
int sqlite3SafetyCheck(sqlite3*);
void sqlite3ChangeCookie(sqlite3*, Vdbe*, int);

#ifndef SQLITE_OMIT_TRIGGER
  void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
                           int,Expr*,int);
  void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
  void sqlite3DropTrigger(Parse*, SrcList*);
  void sqlite3DropTriggerPtr(Parse*, Trigger*, int);
  int sqlite3TriggersExist(Parse*, Table*, int, ExprList*);
  int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, 
                           int, int);
  void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
  void sqlite3DeleteTriggerStep(TriggerStep*);
  TriggerStep *sqlite3TriggerSelectStep(Select*);
  TriggerStep *sqlite3TriggerInsertStep(Token*, IdList*, ExprList*,Select*,int);
  TriggerStep *sqlite3TriggerUpdateStep(Token*, ExprList*, Expr*, int);
  TriggerStep *sqlite3TriggerDeleteStep(Token*, Expr*);
  void sqlite3DeleteTrigger(Trigger*);
  void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
#else
# define sqlite3TriggersExist(A,B,C,D,E,F) 0
# define sqlite3DeleteTrigger(A)
# define sqlite3DropTriggerPtr(A,B,C)
# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) 0
#endif

int sqlite3JoinType(Parse*, Token*, Token*, Token*);
void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
void sqlite3DeferForeignKey(Parse*, int);
#ifndef SQLITE_OMIT_AUTHORIZATION
  void sqlite3AuthRead(Parse*,Expr*,SrcList*);
  int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
  void sqlite3AuthContextPush(Parse*, AuthContext*, const char*);
  void sqlite3AuthContextPop(AuthContext*);
#else
# define sqlite3AuthRead(a,b,c)
# define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a)  ((void)(a))
#endif
void sqlite3Attach(Parse*, Token*, Token*, int, Token*);
void sqlite3Detach(Parse*, Token*);
int sqlite3BtreeFactory(const sqlite3 *db, const char *zFilename,
                       int omitJournal, int nCache, Btree **ppBtree);
int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
double sqlite3AtoF(const char *z, const char **);
char *sqlite3_snprintf(int,char*,const char*,...);
int sqlite3GetInt32(const char *, int*);
int sqlite3FitsIn64Bits(const char *);
int sqlite3utf16ByteLen(const void *pData, int nChar);
int sqlite3utf8CharLen(const char *pData, int nByte);
int sqlite3ReadUtf8(const unsigned char *);
int sqlite3PutVarint(unsigned char *, u64);
int sqlite3GetVarint(const unsigned char *, u64 *);
int sqlite3GetVarint32(const unsigned char *, u32 *);
int sqlite3VarintLen(u64 v);
void sqlite3IndexAffinityStr(Vdbe *, Index *);
void sqlite3TableAffinityStr(Vdbe *, Table *);
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3ExprAffinity(Expr *pExpr);
int sqlite3atoi64(const char*, i64*);
void sqlite3Error(sqlite3*, int, const char*,...);
void *sqlite3HexToBlob(const char *z);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrStr(int);
int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckIndexCollSeq(Parse *, Index *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
void sqlite3utf16Substr(sqlite3_context *,int,sqlite3_value **);

const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*));
void sqlite3ValueFree(sqlite3_value*);
sqlite3_value *sqlite3ValueNew();
sqlite3_value *sqlite3GetTransientValue(sqlite3*db);
extern const unsigned char sqlite3UpperToLower[];
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(sqlite3*);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
void sqlite3CodeSubselect(Parse *, Expr *);
int sqlite3SelectResolve(Parse *, Select *, NameContext *);

#endif
Added SQLite.Interop/src/table.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
/*
** 2001 September 15
**
** 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 file contains the sqlite3_get_table() and sqlite3_free_table()
** interface routines.  These are just wrappers around the main
** interface routine of sqlite3_exec().
**
** These routines are in a separate files so that they will not be linked
** if they are not used.
*/
#include <stdlib.h>
#include <string.h>
#include "sqliteInt.h"

/*
** This structure is used to pass data from sqlite3_get_table() through
** to the callback function is uses to build the result.
*/
typedef struct TabResult {
  char **azResult;
  char *zErrMsg;
  int nResult;
  int nAlloc;
  int nRow;
  int nColumn;
  int nData;
  int rc;
} TabResult;

/*
** This routine is called once for each row in the result table.  Its job
** is to fill in the TabResult structure appropriately, allocating new
** memory as necessary.
*/
static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
  TabResult *p = (TabResult*)pArg;
  int need;
  int i;
  char *z;

  /* Make sure there is enough space in p->azResult to hold everything
  ** we need to remember from this invocation of the callback.
  */
  if( p->nRow==0 && argv!=0 ){
    need = nCol*2;
  }else{
    need = nCol;
  }
  if( p->nData + need >= p->nAlloc ){
    char **azNew;
    p->nAlloc = p->nAlloc*2 + need + 1;
    azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
    if( azNew==0 ) goto malloc_failed;
    p->azResult = azNew;
  }

  /* If this is the first row, then generate an extra row containing
  ** the names of all columns.
  */
  if( p->nRow==0 ){
    p->nColumn = nCol;
    for(i=0; i<nCol; i++){
      if( colv[i]==0 ){
        z = 0;
      }else{
        z = malloc( strlen(colv[i])+1 );
        if( z==0 ) goto malloc_failed;
        strcpy(z, colv[i]);
      }
      p->azResult[p->nData++] = z;
    }
  }else if( p->nColumn!=nCol ){
    sqlite3SetString(&p->zErrMsg,
       "sqlite3_get_table() called with two or more incompatible queries",
       (char*)0);
    p->rc = SQLITE_ERROR;
    return 1;
  }

  /* Copy over the row data
  */
  if( argv!=0 ){
    for(i=0; i<nCol; i++){
      if( argv[i]==0 ){
        z = 0;
      }else{
        z = malloc( strlen(argv[i])+1 );
        if( z==0 ) goto malloc_failed;
        strcpy(z, argv[i]);
      }
      p->azResult[p->nData++] = z;
    }
    p->nRow++;
  }
  return 0;

malloc_failed:
  p->rc = SQLITE_NOMEM;
  return 1;
}

/*
** Query the database.  But instead of invoking a callback for each row,
** malloc() for space to hold the result and return the entire results
** at the conclusion of the call.
**
** The result that is written to ***pazResult is held in memory obtained
** from malloc().  But the caller cannot free this memory directly.  
** Instead, the entire table should be passed to sqlite3_free_table() when
** the calling procedure is finished using it.
*/
int sqlite3_get_table(
  sqlite3 *db,                /* The database on which the SQL executes */
  const char *zSql,           /* The SQL to be executed */
  char ***pazResult,          /* Write the result table here */
  int *pnRow,                 /* Write the number of rows in the result here */
  int *pnColumn,              /* Write the number of columns of result here */
  char **pzErrMsg             /* Write error messages here */
){
  int rc;
  TabResult res;
  if( pazResult==0 ){ return SQLITE_ERROR; }
  *pazResult = 0;
  if( pnColumn ) *pnColumn = 0;
  if( pnRow ) *pnRow = 0;
  res.zErrMsg = 0;
  res.nResult = 0;
  res.nRow = 0;
  res.nColumn = 0;
  res.nData = 1;
  res.nAlloc = 20;
  res.rc = SQLITE_OK;
  res.azResult = malloc( sizeof(char*)*res.nAlloc );
  if( res.azResult==0 ) return SQLITE_NOMEM;
  res.azResult[0] = 0;
  rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
  if( res.azResult ){
    res.azResult[0] = (char*)res.nData;
  }
  if( rc==SQLITE_ABORT ){
    sqlite3_free_table(&res.azResult[1]);
    if( res.zErrMsg ){
      if( pzErrMsg ){
        free(*pzErrMsg);
        *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
      }
      sqliteFree(res.zErrMsg);
    }
    db->errCode = res.rc;
    return res.rc;
  }
  sqliteFree(res.zErrMsg);
  if( rc!=SQLITE_OK ){
    sqlite3_free_table(&res.azResult[1]);
    return rc;
  }
  if( res.nAlloc>res.nData ){
    char **azNew;
    azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
    if( azNew==0 ){
      sqlite3_free_table(&res.azResult[1]);
      return SQLITE_NOMEM;
    }
    res.nAlloc = res.nData+1;
    res.azResult = azNew;
  }
  *pazResult = &res.azResult[1];
  if( pnColumn ) *pnColumn = res.nColumn;
  if( pnRow ) *pnRow = res.nRow;
  return rc;
}

/*
** This routine frees the space the sqlite3_get_table() malloced.
*/
void sqlite3_free_table(
  char **azResult            /* Result returned from from sqlite3_get_table() */
){
  if( azResult ){
    int i, n;
    azResult--;
    if( azResult==0 ) return;
    n = (int)azResult[0];
    for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
    free(azResult);
  }
}
Added SQLite.Interop/src/tclsqlite.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.1 2005/03/01 16:04:36 rmsimpson Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define NUM_PREPARED_STMTS 10
#define MAX_PREPARED_STMTS 100

/*
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
** have to do a translation when going between the two.  Set the 
** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
** this translation.  
*/
#if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8)
# define UTF_TRANSLATION_NEEDED 1
#endif

/*
** New SQL functions can be created as TCL scripts.  Each such function
** is described by an instance of the following structure.
*/
typedef struct SqlFunc SqlFunc;
struct SqlFunc {
  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
  char *zScript;        /* The script to be run */
  SqlFunc *pNext;       /* Next function on the list of them all */
};

/*
** New collation sequences function can be created as TCL scripts.  Each such
** function is described by an instance of the following structure.
*/
typedef struct SqlCollate SqlCollate;
struct SqlCollate {
  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
  char *zScript;        /* The script to be run */
  SqlCollate *pNext;       /* Next function on the list of them all */
};

/*
** Prepared statements are cached for faster execution.  Each prepared
** statement is described by an instance of the following structure.
*/
typedef struct SqlPreparedStmt SqlPreparedStmt;
struct SqlPreparedStmt {
  SqlPreparedStmt *pNext;  /* Next in linked list */
  SqlPreparedStmt *pPrev;  /* Previous on the list */
  sqlite3_stmt *pStmt;     /* The prepared statement */
  int nSql;                /* chars in zSql[] */
  char zSql[1];            /* Text of the SQL statement */
};

/*
** There is one instance of this structure for each SQLite database
** that has been opened by the SQLite TCL interface.
*/
typedef struct SqliteDb SqliteDb;
struct SqliteDb {
  sqlite3 *db;          /* The "real" database structure */
  Tcl_Interp *interp;   /* The interpreter used for this database */
  char *zBusy;          /* The busy callback routine */
  char *zCommit;        /* The commit hook callback routine */
  char *zTrace;         /* The trace callback routine */
  char *zProgress;      /* The progress callback routine */
  char *zAuth;          /* The authorization callback routine */
  SqlFunc *pFunc;       /* List of SQL functions */
  SqlCollate *pCollate; /* List of SQL collation functions */
  int rc;               /* Return code of most recent sqlite3_exec() */
  Tcl_Obj *pCollateNeeded;  /* Collation needed script */
  SqlPreparedStmt *stmtList; /* List of prepared statements*/
  SqlPreparedStmt *stmtLast; /* Last statement in the list */
  int maxStmt;               /* The next maximum number of stmtList */
  int nStmt;                 /* Number of statements in stmtList */
};

/*
** Finalize and free a list of prepared statements
*/
static void flushStmtCache( SqliteDb *pDb ){
  SqlPreparedStmt *pPreStmt;

  while(  pDb->stmtList ){
    sqlite3_finalize( pDb->stmtList->pStmt );
    pPreStmt = pDb->stmtList;
    pDb->stmtList = pDb->stmtList->pNext;
    Tcl_Free( (char*)pPreStmt );
  }
  pDb->nStmt = 0;
  pDb->stmtLast = 0;
}

/*
** TCL calls this procedure when an sqlite3 database command is
** deleted.
*/
static void DbDeleteCmd(void *db){
  SqliteDb *pDb = (SqliteDb*)db;
  flushStmtCache(pDb);
  sqlite3_close(pDb->db);
  while( pDb->pFunc ){
    SqlFunc *pFunc = pDb->pFunc;
    pDb->pFunc = pFunc->pNext;
    Tcl_Free((char*)pFunc);
  }
  while( pDb->pCollate ){
    SqlCollate *pCollate = pDb->pCollate;
    pDb->pCollate = pCollate->pNext;
    Tcl_Free((char*)pCollate);
  }
  if( pDb->zBusy ){
    Tcl_Free(pDb->zBusy);
  }
  if( pDb->zTrace ){
    Tcl_Free(pDb->zTrace);
  }
  if( pDb->zAuth ){
    Tcl_Free(pDb->zAuth);
  }
  Tcl_Free((char*)pDb);
}

/*
** This routine is called when a database file is locked while trying
** to execute SQL.
*/
static int DbBusyHandler(void *cd, int nTries){
  SqliteDb *pDb = (SqliteDb*)cd;
  int rc;
  char zVal[30];
  char *zCmd;
  Tcl_DString cmd;

  Tcl_DStringInit(&cmd);
  Tcl_DStringAppend(&cmd, pDb->zBusy, -1);
  sprintf(zVal, "%d", nTries);
  Tcl_DStringAppendElement(&cmd, zVal);
  zCmd = Tcl_DStringValue(&cmd);
  rc = Tcl_Eval(pDb->interp, zCmd);
  Tcl_DStringFree(&cmd);
  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
    return 0;
  }
  return 1;
}

/*
** This routine is invoked as the 'progress callback' for the database.
*/
static int DbProgressHandler(void *cd){
  SqliteDb *pDb = (SqliteDb*)cd;
  int rc;

  assert( pDb->zProgress );
  rc = Tcl_Eval(pDb->interp, pDb->zProgress);
  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
    return 1;
  }
  return 0;
}

/*
** This routine is called by the SQLite trace handler whenever a new
** block of SQL is executed.  The TCL script in pDb->zTrace is executed.
*/
static void DbTraceHandler(void *cd, const char *zSql){
  SqliteDb *pDb = (SqliteDb*)cd;
  Tcl_DString str;

  Tcl_DStringInit(&str);
  Tcl_DStringAppend(&str, pDb->zTrace, -1);
  Tcl_DStringAppendElement(&str, zSql);
  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
  Tcl_DStringFree(&str);
  Tcl_ResetResult(pDb->interp);
}

/*
** This routine is called when a transaction is committed.  The
** TCL script in pDb->zCommit is executed.  If it returns non-zero or
** if it throws an exception, the transaction is rolled back instead
** of being committed.
*/
static int DbCommitHandler(void *cd){
  SqliteDb *pDb = (SqliteDb*)cd;
  int rc;

  rc = Tcl_Eval(pDb->interp, pDb->zCommit);
  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
    return 1;
  }
  return 0;
}

static void tclCollateNeeded(
  void *pCtx,
  sqlite3 *db,
  int enc,
  const char *zName
){
  SqliteDb *pDb = (SqliteDb *)pCtx;
  Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
  Tcl_IncrRefCount(pScript);
  Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
  Tcl_EvalObjEx(pDb->interp, pScript, 0);
  Tcl_DecrRefCount(pScript);
}

/*
** This routine is called to evaluate an SQL collation function implemented
** using TCL script.
*/
static int tclSqlCollate(
  void *pCtx,
  int nA,
  const void *zA,
  int nB,
  const void *zB
){
  SqlCollate *p = (SqlCollate *)pCtx;
  Tcl_Obj *pCmd;

  pCmd = Tcl_NewStringObj(p->zScript, -1);
  Tcl_IncrRefCount(pCmd);
  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
  Tcl_EvalObjEx(p->interp, pCmd, 0);
  Tcl_DecrRefCount(pCmd);
  return (atoi(Tcl_GetStringResult(p->interp)));
}

/*
** This routine is called to evaluate an SQL function implemented
** using TCL script.
*/
static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
  SqlFunc *p = sqlite3_user_data(context);
  Tcl_DString cmd;
  int i;
  int rc;

  Tcl_DStringInit(&cmd);
  Tcl_DStringAppend(&cmd, p->zScript, -1);
  for(i=0; i<argc; i++){
    if( SQLITE_NULL==sqlite3_value_type(argv[i]) ){
      Tcl_DStringAppendElement(&cmd, "");
    }else{
      Tcl_DStringAppendElement(&cmd, sqlite3_value_text(argv[i]));
    }
  }
  rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd));
  if( rc ){
    sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
  }else{
    sqlite3_result_text(context, Tcl_GetStringResult(p->interp), -1, 
        SQLITE_TRANSIENT);
  }
}

#ifndef SQLITE_OMIT_AUTHORIZATION
/*
** This is the authentication function.  It appends the authentication
** type code and the two arguments to zCmd[] then invokes the result
** on the interpreter.  The reply is examined to determine if the
** authentication fails or succeeds.
*/
static int auth_callback(
  void *pArg,
  int code,
  const char *zArg1,
  const char *zArg2,
  const char *zArg3,
  const char *zArg4
){
  char *zCode;
  Tcl_DString str;
  int rc;
  const char *zReply;
  SqliteDb *pDb = (SqliteDb*)pArg;

  switch( code ){
    case SQLITE_COPY              : zCode="SQLITE_COPY"; break;
    case SQLITE_CREATE_INDEX      : zCode="SQLITE_CREATE_INDEX"; break;
    case SQLITE_CREATE_TABLE      : zCode="SQLITE_CREATE_TABLE"; break;
    case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
    case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
    case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
    case SQLITE_CREATE_TEMP_VIEW  : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
    case SQLITE_CREATE_TRIGGER    : zCode="SQLITE_CREATE_TRIGGER"; break;
    case SQLITE_CREATE_VIEW       : zCode="SQLITE_CREATE_VIEW"; break;
    case SQLITE_DELETE            : zCode="SQLITE_DELETE"; break;
    case SQLITE_DROP_INDEX        : zCode="SQLITE_DROP_INDEX"; break;
    case SQLITE_DROP_TABLE        : zCode="SQLITE_DROP_TABLE"; break;
    case SQLITE_DROP_TEMP_INDEX   : zCode="SQLITE_DROP_TEMP_INDEX"; break;
    case SQLITE_DROP_TEMP_TABLE   : zCode="SQLITE_DROP_TEMP_TABLE"; break;
    case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
    case SQLITE_DROP_TEMP_VIEW    : zCode="SQLITE_DROP_TEMP_VIEW"; break;
    case SQLITE_DROP_TRIGGER      : zCode="SQLITE_DROP_TRIGGER"; break;
    case SQLITE_DROP_VIEW         : zCode="SQLITE_DROP_VIEW"; break;
    case SQLITE_INSERT            : zCode="SQLITE_INSERT"; break;
    case SQLITE_PRAGMA            : zCode="SQLITE_PRAGMA"; break;
    case SQLITE_READ              : zCode="SQLITE_READ"; break;
    case SQLITE_SELECT            : zCode="SQLITE_SELECT"; break;
    case SQLITE_TRANSACTION       : zCode="SQLITE_TRANSACTION"; break;
    case SQLITE_UPDATE            : zCode="SQLITE_UPDATE"; break;
    case SQLITE_ATTACH            : zCode="SQLITE_ATTACH"; break;
    case SQLITE_DETACH            : zCode="SQLITE_DETACH"; break;
    case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
    case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;
    default                       : zCode="????"; break;
  }
  Tcl_DStringInit(&str);
  Tcl_DStringAppend(&str, pDb->zAuth, -1);
  Tcl_DStringAppendElement(&str, zCode);
  Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
  Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
  Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
  rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
  Tcl_DStringFree(&str);
  zReply = Tcl_GetStringResult(pDb->interp);
  if( strcmp(zReply,"SQLITE_OK")==0 ){
    rc = SQLITE_OK;
  }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
    rc = SQLITE_DENY;
  }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
    rc = SQLITE_IGNORE;
  }else{
    rc = 999;
  }
  return rc;
}
#endif /* SQLITE_OMIT_AUTHORIZATION */

/*
** zText is a pointer to text obtained via an sqlite3_result_text()
** or similar interface. This routine returns a Tcl string object, 
** reference count set to 0, containing the text. If a translation
** between iso8859 and UTF-8 is required, it is preformed.
*/
static Tcl_Obj *dbTextToObj(char const *zText){
  Tcl_Obj *pVal;
#ifdef UTF_TRANSLATION_NEEDED
  Tcl_DString dCol;
  Tcl_DStringInit(&dCol);
  Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol);
  pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1);
  Tcl_DStringFree(&dCol);
#else
  pVal = Tcl_NewStringObj(zText, -1);
#endif
  return pVal;
}

/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
** The interface is like "readline" but no command-line editing
** is done.
**
** copied from shell.c from '.import' command
*/
static char *local_getline(char *zPrompt, FILE *in){
  char *zLine;
  int nLine;
  int n;
  int eol;

  nLine = 100;
  zLine = malloc( nLine );
  if( zLine==0 ) return 0;
  n = 0;
  eol = 0;
  while( !eol ){
    if( n+100>nLine ){
      nLine = nLine*2 + 100;
      zLine = realloc(zLine, nLine);
      if( zLine==0 ) return 0;
    }
    if( fgets(&zLine[n], nLine - n, in)==0 ){
      if( n==0 ){
        free(zLine);
        return 0;
      }
      zLine[n] = 0;
      eol = 1;
      break;
    }
    while( zLine[n] ){ n++; }
    if( n>0 && zLine[n-1]=='\n' ){
      n--;
      zLine[n] = 0;
      eol = 1;
    }
  }
  zLine = realloc( zLine, n+1 );
  return zLine;
}

/*
** The "sqlite" command below creates a new Tcl command for each
** connection it opens to an SQLite database.  This routine is invoked
** whenever one of those connection-specific commands is executed
** in Tcl.  For example, if you run Tcl code like this:
**
**       sqlite3 db1  "my_database"
**       db1 close
**
** The first command opens a connection to the "my_database" database
** and calls that connection "db1".  The second command causes this
** subroutine to be invoked.
*/
static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
  SqliteDb *pDb = (SqliteDb*)cd;
  int choice;
  int rc = TCL_OK;
  static const char *DB_strs[] = {
    "authorizer",         "busy",              "cache",
    "changes",            "close",             "collate",
    "collation_needed",   "commit_hook",       "complete",
    "copy",               "errorcode",         "eval",
    "function",           "last_insert_rowid", "onecolumn",
    "progress",           "rekey",             "timeout",
    "total_changes",      "trace",             "version",
    0                    
  };
  enum DB_enum {
    DB_AUTHORIZER,        DB_BUSY,             DB_CACHE,
    DB_CHANGES,           DB_CLOSE,            DB_COLLATE,
    DB_COLLATION_NEEDED,  DB_COMMIT_HOOK,      DB_COMPLETE,
    DB_COPY,              DB_ERRORCODE,        DB_EVAL,
    DB_FUNCTION,          DB_LAST_INSERT_ROWID,DB_ONECOLUMN,
    DB_PROGRESS,          DB_REKEY,            DB_TIMEOUT,
    DB_TOTAL_CHANGES,     DB_TRACE,            DB_VERSION
  };
  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
    return TCL_ERROR;
  }
  if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
    return TCL_ERROR;
  }

  switch( (enum DB_enum)choice ){

  /*    $db authorizer ?CALLBACK?
  **
  ** Invoke the given callback to authorize each SQL operation as it is
  ** compiled.  5 arguments are appended to the callback before it is
  ** invoked:
  **
  **   (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
  **   (2) First descriptive name (depends on authorization type)
  **   (3) Second descriptive name
  **   (4) Name of the database (ex: "main", "temp")
  **   (5) Name of trigger that is doing the access
  **
  ** The callback should return on of the following strings: SQLITE_OK,
  ** SQLITE_IGNORE, or SQLITE_DENY.  Any other return value is an error.
  **
  ** If this method is invoked with no arguments, the current authorization
  ** callback string is returned.
  */
  case DB_AUTHORIZER: {
#ifdef SQLITE_OMIT_AUTHORIZATION
    Tcl_AppendResult(interp, "authorization not available in this build", 0);
    return TCL_ERROR;
#else
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zAuth ){
        Tcl_AppendResult(interp, pDb->zAuth, 0);
      }
    }else{
      char *zAuth;
      int len;
      if( pDb->zAuth ){
        Tcl_Free(pDb->zAuth);
      }
      zAuth = Tcl_GetStringFromObj(objv[2], &len);
      if( zAuth && len>0 ){
        pDb->zAuth = Tcl_Alloc( len + 1 );
        strcpy(pDb->zAuth, zAuth);
      }else{
        pDb->zAuth = 0;
      }
      if( pDb->zAuth ){
        pDb->interp = interp;
        sqlite3_set_authorizer(pDb->db, auth_callback, pDb);
      }else{
        sqlite3_set_authorizer(pDb->db, 0, 0);
      }
    }
#endif
    break;
  }

  /*    $db busy ?CALLBACK?
  **
  ** Invoke the given callback if an SQL statement attempts to open
  ** a locked database file.
  */
  case DB_BUSY: {
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zBusy ){
        Tcl_AppendResult(interp, pDb->zBusy, 0);
      }
    }else{
      char *zBusy;
      int len;
      if( pDb->zBusy ){
        Tcl_Free(pDb->zBusy);
      }
      zBusy = Tcl_GetStringFromObj(objv[2], &len);
      if( zBusy && len>0 ){
        pDb->zBusy = Tcl_Alloc( len + 1 );
        strcpy(pDb->zBusy, zBusy);
      }else{
        pDb->zBusy = 0;
      }
      if( pDb->zBusy ){
        pDb->interp = interp;
        sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
      }else{
        sqlite3_busy_handler(pDb->db, 0, 0);
      }
    }
    break;
  }

  /*     $db cache flush
  **     $db cache size n
  **
  ** Flush the prepared statement cache, or set the maximum number of
  ** cached statements.
  */
  case DB_CACHE: {
    char *subCmd;
    int n;

    if( objc<=2 ){
      Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
      return TCL_ERROR;
    }
    subCmd = Tcl_GetStringFromObj( objv[2], 0 );
    if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "flush");
        return TCL_ERROR;
      }else{
        flushStmtCache( pDb );
      }
    }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
      if( objc!=4 ){
        Tcl_WrongNumArgs(interp, 2, objv, "size n");
        return TCL_ERROR;
      }else{
        if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
          Tcl_AppendResult( interp, "cannot convert \"", 
               Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0);
          return TCL_ERROR;
        }else{
          if( n<0 ){
            flushStmtCache( pDb );
            n = 0;
          }else if( n>MAX_PREPARED_STMTS ){
            n = MAX_PREPARED_STMTS;
          }
          pDb->maxStmt = n;
        }
      }
    }else{
      Tcl_AppendResult( interp, "bad option \"", 
          Tcl_GetStringFromObj(objv[0],0), "\": must be flush or size", 0);
      return TCL_ERROR;
    }
    break;
  }

  /*     $db changes
  **
  ** Return the number of rows that were modified, inserted, or deleted by
  ** the most recent INSERT, UPDATE or DELETE statement, not including 
  ** any changes made by trigger programs.
  */
  case DB_CHANGES: {
    Tcl_Obj *pResult;
    if( objc!=2 ){
      Tcl_WrongNumArgs(interp, 2, objv, "");
      return TCL_ERROR;
    }
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
    break;
  }

  /*    $db close
  **
  ** Shutdown the database
  */
  case DB_CLOSE: {
    Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
    break;
  }

  /*    $db commit_hook ?CALLBACK?
  **
  ** Invoke the given callback just before committing every SQL transaction.
  ** If the callback throws an exception or returns non-zero, then the
  ** transaction is aborted.  If CALLBACK is an empty string, the callback
  ** is disabled.
  */
  case DB_COMMIT_HOOK: {
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zCommit ){
        Tcl_AppendResult(interp, pDb->zCommit, 0);
      }
    }else{
      char *zCommit;
      int len;
      if( pDb->zCommit ){
        Tcl_Free(pDb->zCommit);
      }
      zCommit = Tcl_GetStringFromObj(objv[2], &len);
      if( zCommit && len>0 ){
        pDb->zCommit = Tcl_Alloc( len + 1 );
        strcpy(pDb->zCommit, zCommit);
      }else{
        pDb->zCommit = 0;
      }
      if( pDb->zCommit ){
        pDb->interp = interp;
        sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
      }else{
        sqlite3_commit_hook(pDb->db, 0, 0);
      }
    }
    break;
  }

  /*
  **     $db collate NAME SCRIPT
  **
  ** Create a new SQL collation function called NAME.  Whenever
  ** that function is called, invoke SCRIPT to evaluate the function.
  */
  case DB_COLLATE: {
    SqlCollate *pCollate;
    char *zName;
    char *zScript;
    int nScript;
    if( objc!=4 ){
      Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
      return TCL_ERROR;
    }
    zName = Tcl_GetStringFromObj(objv[2], 0);
    zScript = Tcl_GetStringFromObj(objv[3], &nScript);
    pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
    if( pCollate==0 ) return TCL_ERROR;
    pCollate->interp = interp;
    pCollate->pNext = pDb->pCollate;
    pCollate->zScript = (char*)&pCollate[1];
    pDb->pCollate = pCollate;
    strcpy(pCollate->zScript, zScript);
    if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, 
        pCollate, tclSqlCollate) ){
      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
      return TCL_ERROR;
    }
    break;
  }

  /*
  **     $db collation_needed SCRIPT
  **
  ** Create a new SQL collation function called NAME.  Whenever
  ** that function is called, invoke SCRIPT to evaluate the function.
  */
  case DB_COLLATION_NEEDED: {
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
      return TCL_ERROR;
    }
    if( pDb->pCollateNeeded ){
      Tcl_DecrRefCount(pDb->pCollateNeeded);
    }
    pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
    Tcl_IncrRefCount(pDb->pCollateNeeded);
    sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
    break;
  }

  /*    $db complete SQL
  **
  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
  ** additional lines of input are needed.  This is similar to the
  ** built-in "info complete" command of Tcl.
  */
  case DB_COMPLETE: {
    Tcl_Obj *pResult;
    int isComplete;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
      return TCL_ERROR;
    }
    isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetBooleanObj(pResult, isComplete);
    break;
  }

  /*
  **    $db errorcode
  **
  ** Return the numeric error code that was returned by the most recent
  ** call to sqlite3_exec().
  */
  case DB_ERRORCODE: {
    Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
    break;
  }
   
  /*
  **    $db eval $sql ?array? ?{  ...code... }?
  **    $db onecolumn $sql
  **
  ** The SQL statement in $sql is evaluated.  For each row, the values are
  ** placed in elements of the array named "array" and ...code... is executed.
  ** If "array" and "code" are omitted, then no callback is every invoked.
  ** If "array" is an empty string, then the values are placed in variables
  ** that have the same name as the fields extracted by the query.
  **
  ** The onecolumn method is the equivalent of:
  **     lindex [$db eval $sql] 0
  */
  case DB_ONECOLUMN:
  case DB_EVAL: {
    char const *zSql;      /* Next SQL statement to execute */
    char const *zLeft;     /* What is left after first stmt in zSql */
    sqlite3_stmt *pStmt;   /* Compiled SQL statment */
    Tcl_Obj *pArray;       /* Name of array into which results are written */
    Tcl_Obj *pScript;      /* Script to run for each result set */
    Tcl_Obj **apParm;      /* Parameters that need a Tcl_DecrRefCount() */
    int nParm;             /* Number of entries used in apParm[] */
    Tcl_Obj *aParm[10];    /* Static space for apParm[] in the common case */
    Tcl_Obj *pRet;         /* Value to be returned */
    SqlPreparedStmt *pPreStmt;  /* Pointer to a prepared statement */
    int rc2;

    if( choice==DB_ONECOLUMN ){
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "SQL");
        return TCL_ERROR;
      }
      pRet = 0;
    }else{
      if( objc<3 || objc>5 ){
        Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
        return TCL_ERROR;
      }
      pRet = Tcl_NewObj();
      Tcl_IncrRefCount(pRet);
    }
    if( objc==3 ){
      pArray = pScript = 0;
    }else if( objc==4 ){
      pArray = 0;
      pScript = objv[3];
    }else{
      pArray = objv[3];
      if( Tcl_GetString(pArray)[0]==0 ) pArray = 0;
      pScript = objv[4];
    }

    Tcl_IncrRefCount(objv[2]);
    zSql = Tcl_GetStringFromObj(objv[2], 0);
    while( rc==TCL_OK && zSql[0] ){
      int i;                     /* Loop counter */
      int nVar;                  /* Number of bind parameters in the pStmt */
      int nCol;                  /* Number of columns in the result set */
      Tcl_Obj **apColName = 0;   /* Array of column names */
      int len;                   /* String length of zSql */
  
      /* Try to find a SQL statement that has already been compiled and
      ** which matches the next sequence of SQL.
      */
      pStmt = 0;
      pPreStmt = pDb->stmtList;
      len = strlen(zSql);
      if( pPreStmt && sqlite3_expired(pPreStmt->pStmt) ){
        flushStmtCache(pDb);
        pPreStmt = 0;
      }
      for(; pPreStmt; pPreStmt=pPreStmt->pNext){
        int n = pPreStmt->nSql;
        if( len>=n 
            && memcmp(pPreStmt->zSql, zSql, n)==0
            && (zSql[n]==0 || zSql[n-1]==';')
        ){
          pStmt = pPreStmt->pStmt;
          zLeft = &zSql[pPreStmt->nSql];

          /* When a prepared statement is found, unlink it from the
          ** cache list.  It will later be added back to the beginning
          ** of the cache list in order to implement LRU replacement.
          */
          if( pPreStmt->pPrev ){
            pPreStmt->pPrev->pNext = pPreStmt->pNext;
          }else{
            pDb->stmtList = pPreStmt->pNext;
          }
          if( pPreStmt->pNext ){
            pPreStmt->pNext->pPrev = pPreStmt->pPrev;
          }else{
            pDb->stmtLast = pPreStmt->pPrev;
          }
          pDb->nStmt--;
          break;
        }
      }
  
      /* If no prepared statement was found.  Compile the SQL text
      */
      if( pStmt==0 ){
        if( SQLITE_OK!=sqlite3_prepare(pDb->db, zSql, -1, &pStmt, &zLeft) ){
          Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
          rc = TCL_ERROR;
          break;
        }
        if( pStmt==0 ){
          if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
            /* A compile-time error in the statement
            */
            Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
            rc = TCL_ERROR;
            break;
          }else{
            /* The statement was a no-op.  Continue to the next statement
            ** in the SQL string.
            */
            zSql = zLeft;
            continue;
          }
        }
        assert( pPreStmt==0 );
      }

      /* Bind values to parameters that begin with $ or :
      */  
      nVar = sqlite3_bind_parameter_count(pStmt);
      nParm = 0;
      if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){
        apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0]));
      }else{
        apParm = aParm;
      }
      for(i=1; i<=nVar; i++){
        const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
        if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':') ){
          Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
          if( pVar ){
            int n;
            u8 *data;
            char *zType = pVar->typePtr ? pVar->typePtr->name : "";
            char c = zType[0];
            if( c=='b' && strcmp(zType,"bytearray")==0 ){
              data = Tcl_GetByteArrayFromObj(pVar, &n);
              sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
              Tcl_IncrRefCount(pVar);
              apParm[nParm++] = pVar;
            }else if( (c=='b' && strcmp(zType,"boolean")==0) ||
                  (c=='i' && strcmp(zType,"int")==0) ){
              Tcl_GetIntFromObj(interp, pVar, &n);
              sqlite3_bind_int(pStmt, i, n);
            }else if( c=='d' && strcmp(zType,"double")==0 ){
              double r;
              Tcl_GetDoubleFromObj(interp, pVar, &r);
              sqlite3_bind_double(pStmt, i, r);
            }else{
              data = Tcl_GetStringFromObj(pVar, &n);
              sqlite3_bind_text(pStmt, i, data, n, SQLITE_STATIC);
              Tcl_IncrRefCount(pVar);
              apParm[nParm++] = pVar;
            }
          }else{
            sqlite3_bind_null( pStmt, i );
          }
        }
      }

      /* Compute column names */
      nCol = sqlite3_column_count(pStmt);
      if( pScript ){
        apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
        if( apColName==0 ) break;
        for(i=0; i<nCol; i++){
          apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
          Tcl_IncrRefCount(apColName[i]);
        }
      }

      /* If results are being stored in an array variable, then create
      ** the array(*) entry for that array
      */
      if( pArray ){
        Tcl_Obj *pColList = Tcl_NewObj();
        Tcl_IncrRefCount(pColList);
        for(i=0; i<nCol; i++){
          Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
        }
        Tcl_ObjSetVar2(interp, pArray, Tcl_NewStringObj("*",-1), pColList,0);
      }

      /* Execute the SQL
      */
      while( rc==TCL_OK && pStmt && SQLITE_ROW==sqlite3_step(pStmt) ){
        for(i=0; i<nCol; i++){
          Tcl_Obj *pVal;
          
          /* Set pVal to contain the i'th column of this row. */
          switch( sqlite3_column_type(pStmt, i) ){
            case SQLITE_BLOB: {
              int bytes = sqlite3_column_bytes(pStmt, i);
              pVal = Tcl_NewByteArrayObj(sqlite3_column_blob(pStmt, i), bytes);
              break;
            }
            case SQLITE_INTEGER: {
              sqlite_int64 v = sqlite3_column_int64(pStmt, i);
              if( v>=-2147483647 && v<=2147483647 ){
                pVal = Tcl_NewIntObj(v);
              }else{
                pVal = Tcl_NewWideIntObj(v);
              }
              break;
            }
            case SQLITE_FLOAT: {
              double r = sqlite3_column_double(pStmt, i);
              pVal = Tcl_NewDoubleObj(r);
              break;
            }
            default: {
              pVal = dbTextToObj(sqlite3_column_text(pStmt, i));
              break;
            }
          }
  
          if( pScript ){
            if( pArray==0 ){
              Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
            }else{
              Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
            }
          }else if( choice==DB_ONECOLUMN ){
            if( pRet==0 ){
              pRet = pVal;
              Tcl_IncrRefCount(pRet);
            }
            rc = TCL_BREAK;
          }else{
            Tcl_ListObjAppendElement(interp, pRet, pVal);
          }
        }
  
        if( pScript ){
          rc = Tcl_EvalObjEx(interp, pScript, 0);
          if( rc==TCL_CONTINUE ){
            rc = TCL_OK;
          }
        }
      }
      if( rc==TCL_BREAK ){
        rc = TCL_OK;
      }

      /* Free the column name objects */
      if( pScript ){
        for(i=0; i<nCol; i++){
          Tcl_DecrRefCount(apColName[i]);
        }
        Tcl_Free((char*)apColName);
      }

      /* Free the bound string and blob parameters */
      for(i=0; i<nParm; i++){
        Tcl_DecrRefCount(apParm[i]);
      }
      if( apParm!=aParm ){
        Tcl_Free((char*)apParm);
      }

      /* Reset the statement.  If the result code is SQLITE_SCHEMA, then
      ** flush the statement cache and try the statement again.
      */
      rc2 = sqlite3_reset(pStmt);
      if( SQLITE_SCHEMA==rc2 ){
        /* After a schema change, flush the cache and try to run the
        ** statement again
        */
        flushStmtCache( pDb );
        sqlite3_finalize(pStmt);
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        continue;
      }else if( SQLITE_OK!=rc2 ){
        /* If a run-time error occurs, report the error and stop reading
        ** the SQL
        */
        Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
        sqlite3_finalize(pStmt);
        rc = TCL_ERROR;
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        break;
      }else if( pDb->maxStmt<=0 ){
        /* If the cache is turned off, deallocated the statement */
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        sqlite3_finalize(pStmt);
      }else{
        /* Everything worked and the cache is operational.
        ** Create a new SqlPreparedStmt structure if we need one.
        ** (If we already have one we can just reuse it.)
        */
        if( pPreStmt==0 ){
          len = zLeft - zSql;
          pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) + len );
          if( pPreStmt==0 ) return TCL_ERROR;
          pPreStmt->pStmt = pStmt;
          pPreStmt->nSql = len;
          memcpy(pPreStmt->zSql, zSql, len);
          pPreStmt->zSql[len] = 0;
        }

        /* Add the prepared statement to the beginning of the cache list
        */
        pPreStmt->pNext = pDb->stmtList;
        pPreStmt->pPrev = 0;
        if( pDb->stmtList ){
         pDb->stmtList->pPrev = pPreStmt;
        }
        pDb->stmtList = pPreStmt;
        if( pDb->stmtLast==0 ){
          assert( pDb->nStmt==0 );
          pDb->stmtLast = pPreStmt;
        }else{
          assert( pDb->nStmt>0 );
        }
        pDb->nStmt++;
   
        /* If we have too many statement in cache, remove the surplus from the
        ** end of the cache list.
        */
        while( pDb->nStmt>pDb->maxStmt ){
          sqlite3_finalize(pDb->stmtLast->pStmt);
          pDb->stmtLast = pDb->stmtLast->pPrev;
          Tcl_Free((char*)pDb->stmtLast->pNext);
          pDb->stmtLast->pNext = 0;
          pDb->nStmt--;
        }
      }

      /* Proceed to the next statement */
      zSql = zLeft;
    }
    Tcl_DecrRefCount(objv[2]);

    if( pRet ){
      if( rc==TCL_OK ){
        Tcl_SetObjResult(interp, pRet);
      }
      Tcl_DecrRefCount(pRet);
    }
    break;
  }

  /*
  **     $db function NAME SCRIPT
  **
  ** Create a new SQL function called NAME.  Whenever that function is
  ** called, invoke SCRIPT to evaluate the function.
  */
  case DB_FUNCTION: {
    SqlFunc *pFunc;
    char *zName;
    char *zScript;
    int nScript;
    if( objc!=4 ){
      Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
      return TCL_ERROR;
    }
    zName = Tcl_GetStringFromObj(objv[2], 0);
    zScript = Tcl_GetStringFromObj(objv[3], &nScript);
    pFunc = (SqlFunc*)Tcl_Alloc( sizeof(*pFunc) + nScript + 1 );
    if( pFunc==0 ) return TCL_ERROR;
    pFunc->interp = interp;
    pFunc->pNext = pDb->pFunc;
    pFunc->zScript = (char*)&pFunc[1];
    pDb->pFunc = pFunc;
    strcpy(pFunc->zScript, zScript);
    rc = sqlite3_create_function(pDb->db, zName, -1, SQLITE_UTF8,
        pFunc, tclSqlFunc, 0, 0);
    if( rc!=SQLITE_OK ){
      rc = TCL_ERROR;
      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
    }else{
      /* Must flush any cached statements */
      flushStmtCache( pDb );
    }
    break;
  }

  /*
  **     $db last_insert_rowid 
  **
  ** Return an integer which is the ROWID for the most recent insert.
  */
  case DB_LAST_INSERT_ROWID: {
    Tcl_Obj *pResult;
    int rowid;
    if( objc!=2 ){
      Tcl_WrongNumArgs(interp, 2, objv, "");
      return TCL_ERROR;
    }
    rowid = sqlite3_last_insert_rowid(pDb->db);
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetIntObj(pResult, rowid);
    break;
  }

  /*
  ** The DB_ONECOLUMN method is implemented together with DB_EVAL.
  */

  /*    $db progress ?N CALLBACK?
  ** 
  ** Invoke the given callback every N virtual machine opcodes while executing
  ** queries.
  */
  case DB_PROGRESS: {
    if( objc==2 ){
      if( pDb->zProgress ){
        Tcl_AppendResult(interp, pDb->zProgress, 0);
      }
    }else if( objc==4 ){
      char *zProgress;
      int len;
      int N;
      if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
	return TCL_ERROR;
      };
      if( pDb->zProgress ){
        Tcl_Free(pDb->zProgress);
      }
      zProgress = Tcl_GetStringFromObj(objv[3], &len);
      if( zProgress && len>0 ){
        pDb->zProgress = Tcl_Alloc( len + 1 );
        strcpy(pDb->zProgress, zProgress);
      }else{
        pDb->zProgress = 0;
      }
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
      if( pDb->zProgress ){
        pDb->interp = interp;
        sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
      }else{
        sqlite3_progress_handler(pDb->db, 0, 0, 0);
      }
#endif
    }else{
      Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
      return TCL_ERROR;
    }
    break;
  }

  /*
  **     $db rekey KEY
  **
  ** Change the encryption key on the currently open database.
  */
  case DB_REKEY: {
    int nKey;
    void *pKey;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "KEY");
      return TCL_ERROR;
    }
    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
#ifdef SQLITE_HAS_CODEC
    rc = sqlite3_rekey(pDb->db, pKey, nKey);
    if( rc ){
      Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
      rc = TCL_ERROR;
    }
#endif
    break;
  }

  /*
  **     $db timeout MILLESECONDS
  **
  ** Delay for the number of milliseconds specified when a file is locked.
  */
  case DB_TIMEOUT: {
    int ms;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
      return TCL_ERROR;
    }
    if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
    sqlite3_busy_timeout(pDb->db, ms);
    break;
  }

  /*
  **     $db total_changes
  **
  ** Return the number of rows that were modified, inserted, or deleted 
  ** since the database handle was created.
  */
  case DB_TOTAL_CHANGES: {
    Tcl_Obj *pResult;
    if( objc!=2 ){
      Tcl_WrongNumArgs(interp, 2, objv, "");
      return TCL_ERROR;
    }
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
    break;
  }

  /*    $db trace ?CALLBACK?
  **
  ** Make arrangements to invoke the CALLBACK routine for each SQL statement
  ** that is executed.  The text of the SQL is appended to CALLBACK before
  ** it is executed.
  */
  case DB_TRACE: {
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zTrace ){
        Tcl_AppendResult(interp, pDb->zTrace, 0);
      }
    }else{
      char *zTrace;
      int len;
      if( pDb->zTrace ){
        Tcl_Free(pDb->zTrace);
      }
      zTrace = Tcl_GetStringFromObj(objv[2], &len);
      if( zTrace && len>0 ){
        pDb->zTrace = Tcl_Alloc( len + 1 );
        strcpy(pDb->zTrace, zTrace);
      }else{
        pDb->zTrace = 0;
      }
      if( pDb->zTrace ){
        pDb->interp = interp;
        sqlite3_trace(pDb->db, DbTraceHandler, pDb);
      }else{
        sqlite3_trace(pDb->db, 0, 0);
      }
    }
    break;
  }

  /*    $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
  **
  ** Copy data into table from filename, optionally using SEPARATOR
  ** as column separators.  If a column contains a null string, or the
  ** value of NULLINDICATOR, a NULL is inserted for the column.
  ** conflict-algorithm is one of the sqlite conflict algorithms:
  **    rollback, abort, fail, ignore, replace
  ** On success, return the number of lines processed, not necessarily same
  ** as 'db changes' due to conflict-algorithm selected.
  **
  ** This code is basically an implementation/enhancement of
  ** the sqlite3 shell.c ".import" command.
  **
  ** This command usage is equivalent to the sqlite2.x COPY statement,
  ** which imports file data into a table using the PostgreSQL COPY file format:
  **   $db copy $conflit_algo $table_name $filename \t \\N
  */
  case DB_COPY: {
    char *zTable;               /* Insert data into this table */
    char *zFile;                /* The file from which to extract data */
    char *zConflict;            /* The conflict algorithm to use */
    sqlite3_stmt *pStmt;        /* A statement */
    int rc;                     /* Result code */
    int nCol;                   /* Number of columns in the table */
    int nByte;                  /* Number of bytes in an SQL string */
    int i, j;                   /* Loop counters */
    int nSep;                   /* Number of bytes in zSep[] */
    int nNull;                  /* Number of bytes in zNull[] */
    char *zSql;                 /* An SQL statement */
    char *zLine;                /* A single line of input from the file */
    char **azCol;               /* zLine[] broken up into columns */
    char *zCommit;              /* How to commit changes */
    FILE *in;                   /* The input file */
    int lineno = 0;             /* Line number of input file */
    char zLineNum[80];          /* Line number print buffer */
    Tcl_Obj *pResult;           /* interp result */

    char *zSep;
    char *zNull;
    if( objc<5 || objc>7 ){
      Tcl_WrongNumArgs(interp, 2, objv, 
         "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
      return TCL_ERROR;
    }
    if( objc>=6 ){
      zSep = Tcl_GetStringFromObj(objv[5], 0);
    }else{
      zSep = "\t";
    }
    if( objc>=7 ){
      zNull = Tcl_GetStringFromObj(objv[6], 0);
    }else{
      zNull = "";
    }
    zConflict = Tcl_GetStringFromObj(objv[2], 0);
    zTable = Tcl_GetStringFromObj(objv[3], 0);
    zFile = Tcl_GetStringFromObj(objv[4], 0);
    nSep = strlen(zSep);
    nNull = strlen(zNull);
    if( nSep==0 ){
      Tcl_AppendResult(interp, "Error: non-null separator required for copy", 0);
      return TCL_ERROR;
    }
    if(sqlite3StrICmp(zConflict, "rollback") != 0 &&
       sqlite3StrICmp(zConflict, "abort"   ) != 0 &&
       sqlite3StrICmp(zConflict, "fail"    ) != 0 &&
       sqlite3StrICmp(zConflict, "ignore"  ) != 0 &&
       sqlite3StrICmp(zConflict, "replace" ) != 0 ) {
      Tcl_AppendResult(interp, "Error: \"", zConflict, 
            "\", conflict-algorithm must be one of: rollback, "
            "abort, fail, ignore, or replace", 0);
      return TCL_ERROR;
    }
    zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
    if( zSql==0 ){
      Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0);
      return TCL_ERROR;
    }
    nByte = strlen(zSql);
    rc = sqlite3_prepare(pDb->db, zSql, 0, &pStmt, 0);
    sqlite3_free(zSql);
    if( rc ){
      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
      nCol = 0;
    }else{
      nCol = sqlite3_column_count(pStmt);
    }
    sqlite3_finalize(pStmt);
    if( nCol==0 ) {
      return TCL_ERROR;
    }
    zSql = malloc( nByte + 50 + nCol*2 );
    if( zSql==0 ) {
      Tcl_AppendResult(interp, "Error: can't malloc()", 0);
      return TCL_ERROR;
    }
    sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
         zConflict, zTable);
    j = strlen(zSql);
    for(i=1; i<nCol; i++){
      zSql[j++] = ',';
      zSql[j++] = '?';
    }
    zSql[j++] = ')';
    zSql[j] = 0;
    rc = sqlite3_prepare(pDb->db, zSql, 0, &pStmt, 0);
    free(zSql);
    if( rc ){
      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
      sqlite3_finalize(pStmt);
      return TCL_ERROR;
    }
    in = fopen(zFile, "rb");
    if( in==0 ){
      Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL);
      sqlite3_finalize(pStmt);
      return TCL_ERROR;
    }
    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
    if( azCol==0 ) {
      Tcl_AppendResult(interp, "Error: can't malloc()", 0);
      return TCL_ERROR;
    }
    sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
    zCommit = "COMMIT";
    while( (zLine = local_getline(0, in))!=0 ){
      char *z;
      i = 0;
      lineno++;
      azCol[0] = zLine;
      for(i=0, z=zLine; *z; z++){
        if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
          *z = 0;
          i++;
          if( i<nCol ){
            azCol[i] = &z[nSep];
            z += nSep-1;
          }
        }
      }
      if( i+1!=nCol ){
        char *zErr;
        zErr = malloc(200 + strlen(zFile));
        sprintf(zErr,"Error: %s line %d: expected %d columns of data but found %d",
           zFile, lineno, nCol, i+1);
        Tcl_AppendResult(interp, zErr, 0);
        free(zErr);
        zCommit = "ROLLBACK";
        break;
      }
      for(i=0; i<nCol; i++){
        /* check for null data, if so, bind as null */
        if ((nNull>0 && strcmp(azCol[i], zNull)==0) || strlen(azCol[i])==0) {
          sqlite3_bind_null(pStmt, i+1);
        }else{
          sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
        }
      }
      sqlite3_step(pStmt);
      rc = sqlite3_reset(pStmt);
      free(zLine);
      if( rc!=SQLITE_OK ){
        Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0);
        zCommit = "ROLLBACK";
        break;
      }
    }
    free(azCol);
    fclose(in);
    sqlite3_finalize(pStmt);
    sqlite3_exec(pDb->db, zCommit, 0, 0, 0);

    if( zCommit[0] == 'C' ){
      /* success, set result as number of lines processed */
      pResult = Tcl_GetObjResult(interp);
      Tcl_SetIntObj(pResult, lineno);
      rc = TCL_OK;
    }else{
      /* failure, append lineno where failed */
      sprintf(zLineNum,"%d",lineno);
      Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);
      rc = TCL_ERROR;
    }
    break;
  }

  /*    $db version
  **
  ** Return the version string for this database.
  */
  case DB_VERSION: {
    Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
    break;
  }


  } /* End of the SWITCH statement */
  return rc;
}

/*
**   sqlite3 DBNAME FILENAME ?MODE? ?-key KEY?
**
** This is the main Tcl command.  When the "sqlite" Tcl command is
** invoked, this routine runs to process that command.
**
** The first argument, DBNAME, is an arbitrary name for a new
** database connection.  This command creates a new command named
** DBNAME that is used to control that connection.  The database
** connection is deleted when the DBNAME command is deleted.
**
** The second argument is the name of the directory that contains
** the sqlite database that is to be accessed.
**
** For testing purposes, we also support the following:
**
**  sqlite3 -encoding
**
**       Return the encoding used by LIKE and GLOB operators.  Choices
**       are UTF-8 and iso8859.
**
**  sqlite3 -version
**
**       Return the version number of the SQLite library.
**
**  sqlite3 -tcl-uses-utf
**
**       Return "1" if compiled with a Tcl uses UTF-8.  Return "0" if
**       not.  Used by tests to make sure the library was compiled 
**       correctly.
*/
static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
  SqliteDb *p;
  void *pKey = 0;
  int nKey = 0;
  const char *zArg;
  char *zErrMsg;
  const char *zFile;
  char zBuf[80];
  if( objc==2 ){
    zArg = Tcl_GetStringFromObj(objv[1], 0);
    if( strcmp(zArg,"-version")==0 ){
      Tcl_AppendResult(interp,sqlite3_version,0);
      return TCL_OK;
    }
    if( strcmp(zArg,"-has-codec")==0 ){
#ifdef SQLITE_HAS_CODEC
      Tcl_AppendResult(interp,"1",0);
#else
      Tcl_AppendResult(interp,"0",0);
#endif
      return TCL_OK;
    }
    if( strcmp(zArg,"-tcl-uses-utf")==0 ){
#ifdef TCL_UTF_MAX
      Tcl_AppendResult(interp,"1",0);
#else
      Tcl_AppendResult(interp,"0",0);
#endif
      return TCL_OK;
    }
  }
  if( objc==5 || objc==6 ){
    zArg = Tcl_GetStringFromObj(objv[objc-2], 0);
    if( strcmp(zArg,"-key")==0 ){
      pKey = Tcl_GetByteArrayFromObj(objv[objc-1], &nKey);
      objc -= 2;
    }
  }
  if( objc!=3 && objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, 
#ifdef SQLITE_HAS_CODEC
      "HANDLE FILENAME ?-key CODEC-KEY?"
#else
      "HANDLE FILENAME ?MODE?"
#endif
    );
    return TCL_ERROR;
  }
  zErrMsg = 0;
  p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
  if( p==0 ){
    Tcl_SetResult(interp, "malloc failed", TCL_STATIC);
    return TCL_ERROR;
  }
  memset(p, 0, sizeof(*p));
  zFile = Tcl_GetStringFromObj(objv[2], 0);
  sqlite3_open(zFile, &p->db);
  if( SQLITE_OK!=sqlite3_errcode(p->db) ){
    zErrMsg = strdup(sqlite3_errmsg(p->db));
    sqlite3_close(p->db);
    p->db = 0;
  }
#ifdef SQLITE_HAS_CODEC
  sqlite3_key(p->db, pKey, nKey);
#endif
  if( p->db==0 ){
    Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
    Tcl_Free((char*)p);
    free(zErrMsg);
    return TCL_ERROR;
  }
  p->maxStmt = NUM_PREPARED_STMTS;
  zArg = Tcl_GetStringFromObj(objv[1], 0);
  Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);

  /* The return value is the value of the sqlite* pointer
  */
  sprintf(zBuf, "%p", p->db);
  if( strncmp(zBuf,"0x",2) ){
    sprintf(zBuf, "0x%p", p->db);
  }
  Tcl_AppendResult(interp, zBuf, 0);

  /* If compiled with SQLITE_TEST turned on, then register the "md5sum"
  ** SQL function.
  */
#ifdef SQLITE_TEST
  {
    extern void Md5_Register(sqlite3*);
#ifdef SQLITE_MEMDEBUG
    int mallocfail = sqlite3_iMallocFail;
    sqlite3_iMallocFail = 0;
#endif
    Md5_Register(p->db);
#ifdef SQLITE_MEMDEBUG
    sqlite3_iMallocFail = mallocfail;
#endif
   }
#endif  
  p->interp = interp;
  return TCL_OK;
}

/*
** Provide a dummy Tcl_InitStubs if we are using this as a static
** library.
*/
#ifndef USE_TCL_STUBS
# undef  Tcl_InitStubs
# define Tcl_InitStubs(a,b,c)
#endif

/*
** Initialize this module.
**
** This Tcl module contains only a single new Tcl command named "sqlite".
** (Hence there is no namespace.  There is no point in using a namespace
** if the extension only supplies one new name!)  The "sqlite" command is
** used to open a new SQLite database.  See the DbMain() routine above
** for additional information.
*/
int Sqlite3_Init(Tcl_Interp *interp){
  Tcl_InitStubs(interp, "8.4", 0);
  Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite3", "3.0");
  Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite", "3.0");
  return TCL_OK;
}
int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }

#ifndef SQLITE_3_SUFFIX_ONLY
int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
#endif

#ifdef TCLSH
/*****************************************************************************
** The code that follows is used to build standalone TCL interpreters
*/

/*
** If the macro TCLSH is one, then put in code this for the
** "main" routine that will initialize Tcl and take input from
** standard input.
*/
#if TCLSH==1
static char zMainloop[] =
  "set line {}\n"
  "while {![eof stdin]} {\n"
    "if {$line!=\"\"} {\n"
      "puts -nonewline \"> \"\n"
    "} else {\n"
      "puts -nonewline \"% \"\n"
    "}\n"
    "flush stdout\n"
    "append line [gets stdin]\n"
    "if {[info complete $line]} {\n"
      "if {[catch {uplevel #0 $line} result]} {\n"
        "puts stderr \"Error: $result\"\n"
      "} elseif {$result!=\"\"} {\n"
        "puts $result\n"
      "}\n"
      "set line {}\n"
    "} else {\n"
      "append line \\n\n"
    "}\n"
  "}\n"
;
#endif

/*
** If the macro TCLSH is two, then get the main loop code out of
** the separate file "spaceanal_tcl.h".
*/
#if TCLSH==2
static char zMainloop[] = 
#include "spaceanal_tcl.h"
;
#endif

#define TCLSH_MAIN main   /* Needed to fake out mktclapp */
int TCLSH_MAIN(int argc, char **argv){
  Tcl_Interp *interp;
  Tcl_FindExecutable(argv[0]);
  interp = Tcl_CreateInterp();
  Sqlite3_Init(interp);
#ifdef SQLITE_TEST
  {
    extern int Sqlitetest1_Init(Tcl_Interp*);
    extern int Sqlitetest2_Init(Tcl_Interp*);
    extern int Sqlitetest3_Init(Tcl_Interp*);
    extern int Sqlitetest4_Init(Tcl_Interp*);
    extern int Sqlitetest5_Init(Tcl_Interp*);
    extern int Md5_Init(Tcl_Interp*);
    Sqlitetest1_Init(interp);
    Sqlitetest2_Init(interp);
    Sqlitetest3_Init(interp);
    Sqlitetest4_Init(interp);
    Sqlitetest5_Init(interp);
    Md5_Init(interp);
  }
#endif
  if( argc>=2 || TCLSH==2 ){
    int i;
    Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
    for(i=3-TCLSH; i<argc; i++){
      Tcl_SetVar(interp, "argv", argv[i],
          TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
    }
    if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
      const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
      if( zInfo==0 ) zInfo = interp->result;
      fprintf(stderr,"%s: %s\n", *argv, zInfo);
      return 1;
    }
  }
  if( argc<=1 || TCLSH==2 ){
    Tcl_GlobalEval(interp, zMainloop);
  }
  return 0;
}
#endif /* TCLSH */

#endif /* !defined(NO_TCL) */
Added SQLite.Interop/src/tokenize.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
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
** The sqlite3KeywordCode function looks up an identifier to determine if
** it is a keyword.  If it is a keyword, the token code of that keyword is 
** returned.  If the input is not a keyword, TK_ID is returned.
**
** The implementation of this routine was generated by a program,
** mkkeywordhash.h, located in the tool subdirectory of the distribution.
** The output of the mkkeywordhash.c program is written into a file
** named keywordhash.h and then included into this source file by
** the #include below.
*/
#include "keywordhash.h"


/*
** If X is a character that can be used in an identifier and
** X&0x80==0 then isIdChar[X] will be 1.  If X&0x80==0x80 then
** X is always an identifier character.  (Hence all UTF-8
** characters can be part of an identifier).  isIdChar[X] will
** be 0 for every character in the lower 128 ASCII characters
** that cannot be used as part of an identifier.
**
** In this implementation, an identifier can be a string of
** alphabetic characters, digits, and "_" plus any character
** with the high-order bit set.  The latter rule means that
** any sequence of UTF-8 characters or characters taken from
** an extended ISO8859 character set can form an identifier.
**
** Ticket #1066.  the SQL standard does not allow '$' in the
** middle of identfiers.  But many SQL implementations do. 
** SQLite will allow '$' in identifiers for compatibility.
** But the feature is undocumented.
*/
static const char isIdChar[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 3x */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 4x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 5x */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
};

#define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && isIdChar[c-0x20]))

/*
** Return the length of the token that begins at z[0]. 
** Store the token type in *tokenType before returning.
*/
static int getToken(const unsigned char *z, int *tokenType){
  int i, c;
  switch( *z ){
    case ' ': case '\t': case '\n': case '\f': case '\r': {
      for(i=1; isspace(z[i]); i++){}
      *tokenType = TK_SPACE;
      return i;
    }
    case '-': {
      if( z[1]=='-' ){
        for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
        *tokenType = TK_COMMENT;
        return i;
      }
      *tokenType = TK_MINUS;
      return 1;
    }
    case '(': {
      *tokenType = TK_LP;
      return 1;
    }
    case ')': {
      *tokenType = TK_RP;
      return 1;
    }
    case ';': {
      *tokenType = TK_SEMI;
      return 1;
    }
    case '+': {
      *tokenType = TK_PLUS;
      return 1;
    }
    case '*': {
      *tokenType = TK_STAR;
      return 1;
    }
    case '/': {
      if( z[1]!='*' || z[2]==0 ){
        *tokenType = TK_SLASH;
        return 1;
      }
      for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
      if( c ) i++;
      *tokenType = TK_COMMENT;
      return i;
    }
    case '%': {
      *tokenType = TK_REM;
      return 1;
    }
    case '=': {
      *tokenType = TK_EQ;
      return 1 + (z[1]=='=');
    }
    case '<': {
      if( (c=z[1])=='=' ){
        *tokenType = TK_LE;
        return 2;
      }else if( c=='>' ){
        *tokenType = TK_NE;
        return 2;
      }else if( c=='<' ){
        *tokenType = TK_LSHIFT;
        return 2;
      }else{
        *tokenType = TK_LT;
        return 1;
      }
    }
    case '>': {
      if( (c=z[1])=='=' ){
        *tokenType = TK_GE;
        return 2;
      }else if( c=='>' ){
        *tokenType = TK_RSHIFT;
        return 2;
      }else{
        *tokenType = TK_GT;
        return 1;
      }
    }
    case '!': {
      if( z[1]!='=' ){
        *tokenType = TK_ILLEGAL;
        return 2;
      }else{
        *tokenType = TK_NE;
        return 2;
      }
    }
    case '|': {
      if( z[1]!='|' ){
        *tokenType = TK_BITOR;
        return 1;
      }else{
        *tokenType = TK_CONCAT;
        return 2;
      }
    }
    case ',': {
      *tokenType = TK_COMMA;
      return 1;
    }
    case '&': {
      *tokenType = TK_BITAND;
      return 1;
    }
    case '~': {
      *tokenType = TK_BITNOT;
      return 1;
    }
    case '#': {
      for(i=1; isdigit(z[i]) || (i==1 && z[1]=='-'); i++){}
      *tokenType = TK_REGISTER;
      return i;
    }
    case '\'': case '"': {
      int delim = z[0];
      for(i=1; (c=z[i])!=0; i++){
        if( c==delim ){
          if( z[i+1]==delim ){
            i++;
          }else{
            break;
          }
        }
      }
      if( c ) i++;
      *tokenType = TK_STRING;
      return i;
    }
    case '.': {
      *tokenType = TK_DOT;
      return 1;
    }
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9': {
      *tokenType = TK_INTEGER;
      for(i=1; isdigit(z[i]); i++){}
#ifndef SQLITE_OMIT_FLOATING_POINT
      if( z[i]=='.' && isdigit(z[i+1]) ){
        i += 2;
        while( isdigit(z[i]) ){ i++; }
        *tokenType = TK_FLOAT;
      }
      if( (z[i]=='e' || z[i]=='E') &&
           ( isdigit(z[i+1]) 
            || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
           )
      ){
        i += 2;
        while( isdigit(z[i]) ){ i++; }
        *tokenType = TK_FLOAT;
      }
#endif
      return i;
    }
    case '[': {
      for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
      *tokenType = TK_ID;
      return i;
    }
    case '?': {
      *tokenType = TK_VARIABLE;
      for(i=1; isdigit(z[i]); i++){}
      return i;
    }
    case ':': {
      for(i=1; IdChar(z[i]); i++){}
      *tokenType = i>1 ? TK_VARIABLE : TK_ILLEGAL;
      return i;
    }
#ifndef SQLITE_OMIT_TCL_VARIABLE
    case '$': {
      *tokenType = TK_VARIABLE;
      if( z[1]=='{' ){
        int nBrace = 1;
        for(i=2; (c=z[i])!=0 && nBrace; i++){
          if( c=='{' ){
            nBrace++;
          }else if( c=='}' ){
            nBrace--;
          }
        }
        if( c==0 ) *tokenType = TK_ILLEGAL;
      }else{
        int n = 0;
        for(i=1; (c=z[i])!=0; i++){
          if( isalnum(c) || c=='_' ){
            n++;
          }else if( c=='(' && n>0 ){
            do{
              i++;
            }while( (c=z[i])!=0 && !isspace(c) && c!=')' );
            if( c==')' ){
              i++;
            }else{
              *tokenType = TK_ILLEGAL;
            }
            break;
          }else if( c==':' && z[i+1]==':' ){
            i++;
          }else{
            break;
          }
        }
        if( n==0 ) *tokenType = TK_ILLEGAL;
      }
      return i;
    }
#endif
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case 'x': case 'X': {
      if( (c=z[1])=='\'' || c=='"' ){
        int delim = c;
        *tokenType = TK_BLOB;
        for(i=2; (c=z[i])!=0; i++){
          if( c==delim ){
            if( i%2 ) *tokenType = TK_ILLEGAL;
            break;
          }
          if( !isxdigit(c) ){
            *tokenType = TK_ILLEGAL;
            return i;
          }
        }
        if( c ) i++;
        return i;
      }
      /* Otherwise fall through to the next case */
    }
#endif
    default: {
      if( !IdChar(*z) ){
        break;
      }
      for(i=1; IdChar(z[i]); i++){}
      *tokenType = keywordCode((char*)z, i);
      return i;
    }
  }
  *tokenType = TK_ILLEGAL;
  return 1;
}
int sqlite3GetToken(const unsigned char *z, int *tokenType){
  return getToken(z, tokenType);
}

/*
** Run the parser on the given SQL string.  The parser structure is
** passed in.  An SQLITE_ status code is returned.  If an error occurs
** and pzErrMsg!=NULL then an error message might be written into 
** memory obtained from malloc() and *pzErrMsg made to point to that
** error message.  Or maybe not.
*/
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
  int nErr = 0;
  int i;
  void *pEngine;
  int tokenType;
  int lastTokenParsed = -1;
  sqlite3 *db = pParse->db;
  extern void *sqlite3ParserAlloc(void*(*)(int));
  extern void sqlite3ParserFree(void*, void(*)(void*));
  extern int sqlite3Parser(void*, int, Token, Parse*);

  db->flags &= ~SQLITE_Interrupt;
  pParse->rc = SQLITE_OK;
  i = 0;
  pEngine = sqlite3ParserAlloc((void*(*)(int))malloc);
  if( pEngine==0 ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    return 1;
  }
  assert( pParse->sLastToken.dyn==0 );
  assert( pParse->pNewTable==0 );
  assert( pParse->pNewTrigger==0 );
  assert( pParse->nVar==0 );
  assert( pParse->nVarExpr==0 );
  assert( pParse->nVarExprAlloc==0 );
  assert( pParse->apVarExpr==0 );
  pParse->zTail = pParse->zSql = zSql;
  while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){
    assert( i>=0 );
    pParse->sLastToken.z = &zSql[i];
    assert( pParse->sLastToken.dyn==0 );
    pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
    i += pParse->sLastToken.n;
    switch( tokenType ){
      case TK_SPACE:
      case TK_COMMENT: {
        if( (db->flags & SQLITE_Interrupt)!=0 ){
          pParse->rc = SQLITE_INTERRUPT;
          sqlite3SetString(pzErrMsg, "interrupt", (char*)0);
          goto abort_parse;
        }
        break;
      }
      case TK_ILLEGAL: {
        if( pzErrMsg ){
          sqliteFree(*pzErrMsg);
          *pzErrMsg = sqlite3MPrintf("unrecognized token: \"%T\"",
                          &pParse->sLastToken);
        }
        nErr++;
        goto abort_parse;
      }
      case TK_SEMI: {
        pParse->zTail = &zSql[i];
        /* Fall thru into the default case */
      }
      default: {
        sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
        lastTokenParsed = tokenType;
        if( pParse->rc!=SQLITE_OK ){
          goto abort_parse;
        }
        break;
      }
    }
  }
abort_parse:
  if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
    if( lastTokenParsed!=TK_SEMI ){
      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
      pParse->zTail = &zSql[i];
    }
    sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
  }
  sqlite3ParserFree(pEngine, free);
  if( sqlite3_malloc_failed ){
    pParse->rc = SQLITE_NOMEM;
  }
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc),
                    (char*)0);
  }
  if( pParse->zErrMsg ){
    if( pzErrMsg && *pzErrMsg==0 ){
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqliteFree(pParse->zErrMsg);
    }
    pParse->zErrMsg = 0;
    if( !nErr ) nErr++;
  }
  if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
    sqlite3VdbeDelete(pParse->pVdbe);
    pParse->pVdbe = 0;
  }
  sqlite3DeleteTable(pParse->db, pParse->pNewTable);
  sqlite3DeleteTrigger(pParse->pNewTrigger);
  sqliteFree(pParse->apVarExpr);
  if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
    pParse->rc = SQLITE_ERROR;
  }
  return nErr;
}

/*
** Token types used by the sqlite3_complete() routine.  See the header
** comments on that procedure for additional information.
*/
#define tkSEMI    0
#define tkWS      1
#define tkOTHER   2
#define tkEXPLAIN 3
#define tkCREATE  4
#define tkTEMP    5
#define tkTRIGGER 6
#define tkEND     7

/*
** Return TRUE if the given SQL string ends in a semicolon.
**
** Special handling is require for CREATE TRIGGER statements.
** Whenever the CREATE TRIGGER keywords are seen, the statement
** must end with ";END;".
**
** This implementation uses a state machine with 7 states:
**
**   (0) START     At the beginning or end of an SQL statement.  This routine
**                 returns 1 if it ends in the START state and 0 if it ends
**                 in any other state.
**
**   (1) NORMAL    We are in the middle of statement which ends with a single
**                 semicolon.
**
**   (2) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of 
**                 a statement.
**
**   (3) CREATE    The keyword CREATE has been seen at the beginning of a
**                 statement, possibly preceeded by EXPLAIN and/or followed by
**                 TEMP or TEMPORARY
**
**   (4) TRIGGER   We are in the middle of a trigger definition that must be
**                 ended by a semicolon, the keyword END, and another semicolon.
**
**   (5) SEMI      We've seen the first semicolon in the ";END;" that occurs at
**                 the end of a trigger definition.
**
**   (6) END       We've seen the ";END" of the ";END;" that occurs at the end
**                 of a trigger difinition.
**
** Transitions between states above are determined by tokens extracted
** from the input.  The following tokens are significant:
**
**   (0) tkSEMI      A semicolon.
**   (1) tkWS        Whitespace
**   (2) tkOTHER     Any other SQL token.
**   (3) tkEXPLAIN   The "explain" keyword.
**   (4) tkCREATE    The "create" keyword.
**   (5) tkTEMP      The "temp" or "temporary" keyword.
**   (6) tkTRIGGER   The "trigger" keyword.
**   (7) tkEND       The "end" keyword.
**
** Whitespace never causes a state transition and is always ignored.
**
** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
** to recognize the end of a trigger can be omitted.  All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
int sqlite3_complete(const char *zSql){
  u8 state = 0;   /* Current state, using numbers defined in header comment */
  u8 token;       /* Value of the next token */

#ifndef SQLITE_OMIT_TRIGGER
  /* A complex statement machine used to detect the end of a CREATE TRIGGER
  ** statement.  This is the normal case.
  */
  static const u8 trans[7][8] = {
                     /* Token:                                                */
     /* State:       **  SEMI  WS  OTHER EXPLAIN  CREATE  TEMP  TRIGGER  END  */
     /* 0   START: */ {    0,  0,     1,      2,      3,    1,       1,   1,  },
     /* 1  NORMAL: */ {    0,  1,     1,      1,      1,    1,       1,   1,  },
     /* 2 EXPLAIN: */ {    0,  2,     1,      1,      3,    1,       1,   1,  },
     /* 3  CREATE: */ {    0,  3,     1,      1,      1,    3,       4,   1,  },
     /* 4 TRIGGER: */ {    5,  4,     4,      4,      4,    4,       4,   4,  },
     /* 5    SEMI: */ {    5,  5,     4,      4,      4,    4,       4,   6,  },
     /* 6     END: */ {    0,  6,     4,      4,      4,    4,       4,   4,  },
  };
#else
  /* If triggers are not suppored by this compile then the statement machine
  ** used to detect the end of a statement is much simplier
  */
  static const u8 trans[2][3] = {
                     /* Token:           */
     /* State:       **  SEMI  WS  OTHER */
     /* 0   START: */ {    0,  0,     1, },
     /* 1  NORMAL: */ {    0,  1,     1, },
  };
#endif /* SQLITE_OMIT_TRIGGER */

  while( *zSql ){
    switch( *zSql ){
      case ';': {  /* A semicolon */
        token = tkSEMI;
        break;
      }
      case ' ':
      case '\r':
      case '\t':
      case '\n':
      case '\f': {  /* White space is ignored */
        token = tkWS;
        break;
      }
      case '/': {   /* C-style comments */
        if( zSql[1]!='*' ){
          token = tkOTHER;
          break;
        }
        zSql += 2;
        while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
        if( zSql[0]==0 ) return 0;
        zSql++;
        token = tkWS;
        break;
      }
      case '-': {   /* SQL-style comments from "--" to end of line */
        if( zSql[1]!='-' ){
          token = tkOTHER;
          break;
        }
        while( *zSql && *zSql!='\n' ){ zSql++; }
        if( *zSql==0 ) return state==0;
        token = tkWS;
        break;
      }
      case '[': {   /* Microsoft-style identifiers in [...] */
        zSql++;
        while( *zSql && *zSql!=']' ){ zSql++; }
        if( *zSql==0 ) return 0;
        token = tkOTHER;
        break;
      }
      case '"':     /* single- and double-quoted strings */
      case '\'': {
        int c = *zSql;
        zSql++;
        while( *zSql && *zSql!=c ){ zSql++; }
        if( *zSql==0 ) return 0;
        token = tkOTHER;
        break;
      }
      default: {
        int c;
        if( IdChar((u8)*zSql) ){
          /* Keywords and unquoted identifiers */
          int nId;
          for(nId=1; IdChar(zSql[nId]); nId++){}
#ifdef SQLITE_OMIT_TRIGGER
          token = tkOTHER;
#else
          switch( *zSql ){
            case 'c': case 'C': {
              if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
                token = tkCREATE;
              }else{
                token = tkOTHER;
              }
              break;
            }
            case 't': case 'T': {
              if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
                token = tkTRIGGER;
              }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
                token = tkTEMP;
              }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
                token = tkTEMP;
              }else{
                token = tkOTHER;
              }
              break;
            }
            case 'e':  case 'E': {
              if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
                token = tkEND;
              }else
#ifndef SQLITE_OMIT_EXPLAIN
              if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
                token = tkEXPLAIN;
              }else
#endif
              {
                token = tkOTHER;
              }
              break;
            }
            default: {
              token = tkOTHER;
              break;
            }
          }
#endif /* SQLITE_OMIT_TRIGGER */
          zSql += nId-1;
        }else{
          /* Operators and special symbols */
          token = tkOTHER;
        }
        break;
      }
    }
    state = trans[state][token];
    zSql++;
  }
  return state==0;
}

#ifndef SQLITE_OMIT_UTF16
/*
** This routine is the same as the sqlite3_complete() routine described
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
int sqlite3_complete16(const void *zSql){
  sqlite3_value *pVal;
  char const *zSql8;
  int rc = 0;

  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zSql8 ){
    rc = sqlite3_complete(zSql8);
  }
  sqlite3ValueFree(pVal);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
Added SQLite.Interop/src/trigger.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
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
/*
**
** 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.
**
*************************************************************************
*
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_TRIGGER
/*
** Delete a linked list of TriggerStep structures.
*/
void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){
  while( pTriggerStep ){
    TriggerStep * pTmp = pTriggerStep;
    pTriggerStep = pTriggerStep->pNext;

    if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
    sqlite3ExprDelete(pTmp->pWhere);
    sqlite3ExprListDelete(pTmp->pExprList);
    sqlite3SelectDelete(pTmp->pSelect);
    sqlite3IdListDelete(pTmp->pIdList);

    sqliteFree(pTmp);
  }
}

/*
** This is called by the parser when it sees a CREATE TRIGGER statement
** up to the point of the BEGIN before the trigger actions.  A Trigger
** structure is generated based on the information available and stored
** in pParse->pNewTrigger.  After the trigger actions have been parsed, the
** sqlite3FinishTrigger() function is called to complete the trigger
** construction process.
*/
void sqlite3BeginTrigger(
  Parse *pParse,      /* The parse context of the CREATE TRIGGER statement */
  Token *pName1,      /* The name of the trigger */
  Token *pName2,      /* The name of the trigger */
  int tr_tm,          /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
  int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
  IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
  SrcList *pTableName,/* The name of the table/view the trigger applies to */
  int foreach,        /* One of TK_ROW or TK_STATEMENT */
  Expr *pWhen,        /* WHEN clause */
  int isTemp          /* True if the TEMPORARY keyword is present */
){
  Trigger *pTrigger;
  Table *pTab;
  char *zName = 0;        /* Name of the trigger */
  sqlite3 *db = pParse->db;
  int iDb;                /* The database to store the trigger in */
  Token *pName;           /* The unqualified db name */
  DbFixer sFix;

  if( isTemp ){
    /* If TEMP was specified, then the trigger name may not be qualified. */
    if( pName2 && pName2->n>0 ){
      sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
      goto trigger_cleanup;
    }
    iDb = 1;
    pName = pName1;
  }else{
    /* Figure out the db that the the trigger will be created in */
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ){
      goto trigger_cleanup;
    }
  }

  /* If the trigger name was unqualified, and the table is a temp table,
  ** then set iDb to 1 to create the trigger in the temporary database.
  ** If sqlite3SrcListLookup() returns 0, indicating the table does not
  ** exist, the error is caught by the block below.
  */
  if( !pTableName || sqlite3_malloc_failed ) goto trigger_cleanup;
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( pName2->n==0 && pTab && pTab->iDb==1 ){
    iDb = 1;
  }

  /* Ensure the table name matches database name and that the table exists */
  if( sqlite3_malloc_failed ) goto trigger_cleanup;
  assert( pTableName->nSrc==1 );
  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
      sqlite3FixSrcList(&sFix, pTableName) ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( !pTab ){
    /* The table does not exist. */
    goto trigger_cleanup;
  }

  /* Check that the trigger name is not reserved and that no trigger of the
  ** specified name exists */
  zName = sqlite3NameFromToken(pName);
  if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto trigger_cleanup;
  }
  if( sqlite3HashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
    sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
    goto trigger_cleanup;
  }

  /* Do not create a trigger on a system table */
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
    pParse->nErr++;
    goto trigger_cleanup;
  }

  /* INSTEAD of triggers are only for views and views only support INSTEAD
  ** of triggers.
  */
  if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
    sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", 
        (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
    goto trigger_cleanup;
  }
  if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
    sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
        " trigger on table: %S", pTableName, 0);
    goto trigger_cleanup;
  }

#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_CREATE_TRIGGER;
    const char *zDb = db->aDb[pTab->iDb].zName;
    const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
    if( pTab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
      goto trigger_cleanup;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(pTab->iDb),0,zDb)){
      goto trigger_cleanup;
    }
  }
#endif

  /* INSTEAD OF triggers can only appear on views and BEFORE triggers
  ** cannot appear on views.  So we might as well translate every
  ** INSTEAD OF trigger into a BEFORE trigger.  It simplifies code
  ** elsewhere.
  */
  if (tr_tm == TK_INSTEAD){
    tr_tm = TK_BEFORE;
  }

  /* Build the Trigger object */
  pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger));
  if( pTrigger==0 ) goto trigger_cleanup;
  pTrigger->name = zName;
  zName = 0;
  pTrigger->table = sqliteStrDup(pTableName->a[0].zName);
  if( sqlite3_malloc_failed ) goto trigger_cleanup;
  pTrigger->iDb = iDb;
  pTrigger->iTabDb = pTab->iDb;
  pTrigger->op = op;
  pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
  pTrigger->pWhen = sqlite3ExprDup(pWhen);
  pTrigger->pColumns = sqlite3IdListDup(pColumns);
  pTrigger->foreach = foreach;
  sqlite3TokenCopy(&pTrigger->nameToken,pName);
  assert( pParse->pNewTrigger==0 );
  pParse->pNewTrigger = pTrigger;

trigger_cleanup:
  sqliteFree(zName);
  sqlite3SrcListDelete(pTableName);
  sqlite3IdListDelete(pColumns);
  sqlite3ExprDelete(pWhen);
}

/*
** This routine is called after all of the trigger actions have been parsed
** in order to complete the process of building the trigger.
*/
void sqlite3FinishTrigger(
  Parse *pParse,          /* Parser context */
  TriggerStep *pStepList, /* The triggered program */
  Token *pAll             /* Token that describes the complete CREATE TRIGGER */
){
  Trigger *pTrig = 0;     /* The trigger whose construction is finishing up */
  sqlite3 *db = pParse->db;  /* The database */
  DbFixer sFix;

  if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
  pTrig = pParse->pNewTrigger;
  pParse->pNewTrigger = 0;
  pTrig->step_list = pStepList;
  while( pStepList ){
    pStepList->pTrig = pTrig;
    pStepList = pStepList->pNext;
  }
  if( sqlite3FixInit(&sFix, pParse, pTrig->iDb, "trigger", &pTrig->nameToken) 
          && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
    goto triggerfinish_cleanup;
  }

  /* if we are not initializing, and this trigger is not on a TEMP table, 
  ** build the sqlite_master entry
  */
  if( !db->init.busy ){
    static const VdbeOpList insertTrig[] = {
      { OP_NewRecno,   0, 0,  0          },
      { OP_String8,    0, 0,  "trigger"  },
      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
      { OP_String8,    0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String8,    0, 0,  "CREATE TRIGGER "},
      { OP_String8,    0, 0,  0          },  /* 6: SQL */
      { OP_Concat,     0, 0,  0          }, 
      { OP_MakeRecord, 5, 0,  "tttit"    },
      { OP_PutIntKey,  0, 0,  0          },
    };
    int addr;
    Vdbe *v;

    /* Make an entry in the sqlite_master table */
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqlite3BeginWriteOperation(pParse, 0, pTrig->iDb);
    sqlite3OpenMasterTable(v, pTrig->iDb);
    addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
    sqlite3VdbeChangeP3(v, addr+2, pTrig->name, 0); 
    sqlite3VdbeChangeP3(v, addr+3, pTrig->table, 0); 
    sqlite3VdbeChangeP3(v, addr+6, pAll->z, pAll->n);
    sqlite3ChangeCookie(db, v, pTrig->iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_ParseSchema, pTrig->iDb, 0, 
       sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC);
  }

  if( db->init.busy ){
    Table *pTab;
    sqlite3HashInsert(&db->aDb[pTrig->iDb].trigHash, 
                     pTrig->name, strlen(pTrig->name)+1, pTrig);
    pTab = sqlite3LocateTable(pParse,pTrig->table,db->aDb[pTrig->iTabDb].zName);
    assert( pTab!=0 );
    pTrig->pNext = pTab->pTrigger;
    pTab->pTrigger = pTrig;
    pTrig = 0;
  }

triggerfinish_cleanup:
  sqlite3DeleteTrigger(pTrig);
  assert( !pParse->pNewTrigger );
  sqlite3DeleteTriggerStep(pStepList);
}

/*
** Make a copy of all components of the given trigger step.  This has
** the effect of copying all Expr.token.z values into memory obtained
** from sqliteMalloc().  As initially created, the Expr.token.z values
** all point to the input string that was fed to the parser.  But that
** string is ephemeral - it will go away as soon as the sqlite3_exec()
** call that started the parser exits.  This routine makes a persistent
** copy of all the Expr.token.z strings so that the TriggerStep structure
** will be valid even after the sqlite3_exec() call returns.
*/
static void sqlitePersistTriggerStep(TriggerStep *p){
  if( p->target.z ){
    p->target.z = sqliteStrNDup(p->target.z, p->target.n);
    p->target.dyn = 1;
  }
  if( p->pSelect ){
    Select *pNew = sqlite3SelectDup(p->pSelect);
    sqlite3SelectDelete(p->pSelect);
    p->pSelect = pNew;
  }
  if( p->pWhere ){
    Expr *pNew = sqlite3ExprDup(p->pWhere);
    sqlite3ExprDelete(p->pWhere);
    p->pWhere = pNew;
  }
  if( p->pExprList ){
    ExprList *pNew = sqlite3ExprListDup(p->pExprList);
    sqlite3ExprListDelete(p->pExprList);
    p->pExprList = pNew;
  }
  if( p->pIdList ){
    IdList *pNew = sqlite3IdListDup(p->pIdList);
    sqlite3IdListDelete(p->pIdList);
    p->pIdList = pNew;
  }
}

/*
** Turn a SELECT statement (that the pSelect parameter points to) into
** a trigger step.  Return a pointer to a TriggerStep structure.
**
** The parser calls this routine when it finds a SELECT statement in
** body of a TRIGGER.  
*/
TriggerStep *sqlite3TriggerSelectStep(Select *pSelect){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  pTriggerStep->op = TK_SELECT;
  pTriggerStep->pSelect = pSelect;
  pTriggerStep->orconf = OE_Default;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

/*
** Build a trigger step out of an INSERT statement.  Return a pointer
** to the new trigger step.
**
** The parser calls this routine when it sees an INSERT inside the
** body of a trigger.
*/
TriggerStep *sqlite3TriggerInsertStep(
  Token *pTableName,  /* Name of the table into which we insert */
  IdList *pColumn,    /* List of columns in pTableName to insert into */
  ExprList *pEList,   /* The VALUE clause: a list of values to be inserted */
  Select *pSelect,    /* A SELECT statement that supplies values */
  int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  assert(pEList == 0 || pSelect == 0);
  assert(pEList != 0 || pSelect != 0);

  pTriggerStep->op = TK_INSERT;
  pTriggerStep->pSelect = pSelect;
  pTriggerStep->target  = *pTableName;
  pTriggerStep->pIdList = pColumn;
  pTriggerStep->pExprList = pEList;
  pTriggerStep->orconf = orconf;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

/*
** Construct a trigger step that implements an UPDATE statement and return
** a pointer to that trigger step.  The parser calls this routine when it
** sees an UPDATE statement inside the body of a CREATE TRIGGER.
*/
TriggerStep *sqlite3TriggerUpdateStep(
  Token *pTableName,   /* Name of the table to be updated */
  ExprList *pEList,    /* The SET clause: list of column and new values */
  Expr *pWhere,        /* The WHERE clause */
  int orconf           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  pTriggerStep->op = TK_UPDATE;
  pTriggerStep->target  = *pTableName;
  pTriggerStep->pExprList = pEList;
  pTriggerStep->pWhere = pWhere;
  pTriggerStep->orconf = orconf;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

/*
** Construct a trigger step that implements a DELETE statement and return
** a pointer to that trigger step.  The parser calls this routine when it
** sees a DELETE statement inside the body of a CREATE TRIGGER.
*/
TriggerStep *sqlite3TriggerDeleteStep(Token *pTableName, Expr *pWhere){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  pTriggerStep->op = TK_DELETE;
  pTriggerStep->target  = *pTableName;
  pTriggerStep->pWhere = pWhere;
  pTriggerStep->orconf = OE_Default;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

/* 
** Recursively delete a Trigger structure
*/
void sqlite3DeleteTrigger(Trigger *pTrigger){
  if( pTrigger==0 ) return;
  sqlite3DeleteTriggerStep(pTrigger->step_list);
  sqliteFree(pTrigger->name);
  sqliteFree(pTrigger->table);
  sqlite3ExprDelete(pTrigger->pWhen);
  sqlite3IdListDelete(pTrigger->pColumns);
  if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
  sqliteFree(pTrigger);
}

/*
** This function is called to drop a trigger from the database schema. 
**
** This may be called directly from the parser and therefore identifies
** the trigger by name.  The sqlite3DropTriggerPtr() routine does the
** same job as this routine except it takes a pointer to the trigger
** instead of the trigger name.
**/
void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
  Trigger *pTrigger = 0;
  int i;
  const char *zDb;
  const char *zName;
  int nName;
  sqlite3 *db = pParse->db;

  if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto drop_trigger_cleanup;
  }

  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;
  nName = strlen(zName);
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
    pTrigger = sqlite3HashFind(&(db->aDb[j].trigHash), zName, nName+1);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
    goto drop_trigger_cleanup;
  }
  sqlite3DropTriggerPtr(pParse, pTrigger, 0);

drop_trigger_cleanup:
  sqlite3SrcListDelete(pName);
}

/*
** Return a pointer to the Table structure for the table that a trigger
** is set on.
*/
static Table *tableOfTrigger(sqlite3 *db, Trigger *pTrigger){
  return sqlite3FindTable(db,pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
}


/*
** Drop a trigger given a pointer to that trigger.  If nested is false,
** then also generate code to remove the trigger from the SQLITE_MASTER
** table.
*/
void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
  Table   *pTable;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  iDb = pTrigger->iDb;
  assert( iDb>=0 && iDb<db->nDb );
  pTable = tableOfTrigger(db, pTrigger);
  assert(pTable);
  assert( pTable->iDb==iDb || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[iDb].zName;
    const char *zTab = SCHEMA_TABLE(iDb);
    if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
      sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      return;
    }
  }
#endif

  /* Generate code to destroy the database record of the trigger.
  */
  if( pTable!=0 && (v = sqlite3GetVdbe(pParse))!=0 ){
    int base;
    static const VdbeOpList dropTrigger[] = {
      { OP_Rewind,     0, ADDR(9),  0},
      { OP_String8,    0, 0,        0}, /* 1 */
      { OP_Column,     0, 1,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_String8,    0, 0,        "trigger"},
      { OP_Column,     0, 0,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_Delete,     0, 0,        0},
      { OP_Next,       0, ADDR(1),  0}, /* 8 */
    };

    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3OpenMasterTable(v, iDb);
    base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
    sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
    sqlite3ChangeCookie(db, v, iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_DropTrigger, iDb, 0, pTrigger->name, 0);
  }
}

/*
** Remove a trigger from the hash tables of the sqlite* pointer.
*/
void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
  Trigger *pTrigger;
  int nName = strlen(zName);
  pTrigger = sqlite3HashInsert(&(db->aDb[iDb].trigHash), zName, nName+1, 0);
  if( pTrigger ){
    Table *pTable = tableOfTrigger(db, pTrigger);
    assert( pTable!=0 );
    if( pTable->pTrigger == pTrigger ){
      pTable->pTrigger = pTrigger->pNext;
    }else{
      Trigger *cc = pTable->pTrigger;
      while( cc ){ 
        if( cc->pNext == pTrigger ){
          cc->pNext = cc->pNext->pNext;
          break;
        }
        cc = cc->pNext;
      }
      assert(cc);
    }
    sqlite3DeleteTrigger(pTrigger);
    db->flags |= SQLITE_InternChanges;
  }
}

/*
** pEList is the SET clause of an UPDATE statement.  Each entry
** in pEList is of the format <id>=<expr>.  If any of the entries
** in pEList have an <id> which matches an identifier in pIdList,
** then return TRUE.  If pIdList==NULL, then it is considered a
** wildcard that matches anything.  Likewise if pEList==NULL then
** it matches anything so always return true.  Return false only
** if there is no match.
*/
static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
  int e;
  if( !pIdList || !pEList ) return 1;
  for(e=0; e<pEList->nExpr; e++){
    if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
  }
  return 0; 
}

/*
** Return a bit vector to indicate what kind of triggers exist for operation
** "op" on table pTab.  If pChanges is not NULL then it is a list of columns
** that are being updated.  Triggers only match if the ON clause of the
** trigger definition overlaps the set of columns being updated.
**
** The returned bit vector is some combination of TRIGGER_BEFORE and
** TRIGGER_AFTER.
*/
int sqlite3TriggersExist(
  Parse *pParse,          /* Used to check for recursive triggers */
  Table *pTab,            /* The table the contains the triggers */
  int op,                 /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
  ExprList *pChanges      /* Columns that change in an UPDATE statement */
){
  Trigger *pTrigger = pTab->pTrigger;
  int mask = 0;

  while( pTrigger ){
    if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){
      TriggerStack *ss;
      ss = pParse->trigStack;
      while( ss && ss->pTrigger!=pTab->pTrigger ){
	ss = ss->pNext;
      }
      if( ss==0 ){
        mask |= pTrigger->tr_tm;
      }
    }
    pTrigger = pTrigger->pNext;
  }
  return mask;
}

/*
** Convert the pStep->target token into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
** forming the SrcList.  This prevents a trigger in one database from
** referring to a target in another database.  An exception is when the
** trigger is in TEMP in which case it can refer to any other database it
** wants.
*/
static SrcList *targetSrcList(
  Parse *pParse,       /* The parsing context */
  TriggerStep *pStep   /* The trigger containing the target token */
){
  Token sDb;           /* Dummy database name token */
  int iDb;             /* Index of the database to use */
  SrcList *pSrc;       /* SrcList to be returned */

  iDb = pStep->pTrig->iDb;
  if( iDb==0 || iDb>=2 ){
    assert( iDb<pParse->db->nDb );
    sDb.z = pParse->db->aDb[iDb].zName;
    sDb.n = strlen(sDb.z);
    pSrc = sqlite3SrcListAppend(0, &sDb, &pStep->target);
  } else {
    pSrc = sqlite3SrcListAppend(0, &pStep->target, 0);
  }
  return pSrc;
}

/*
** Generate VDBE code for zero or more statements inside the body of a
** trigger.  
*/
static int codeTriggerProgram(
  Parse *pParse,            /* The parser context */
  TriggerStep *pStepList,   /* List of statements inside the trigger body */
  int orconfin              /* Conflict algorithm. (OE_Abort, etc) */  
){
  TriggerStep * pTriggerStep = pStepList;
  int orconf;
  Vdbe *v = pParse->pVdbe;

  assert( pTriggerStep!=0 );
  assert( v!=0 );
  sqlite3VdbeAddOp(v, OP_ContextPush, 0, 0);
  VdbeComment((v, "# begin trigger %s", pStepList->pTrig->name));
  while( pTriggerStep ){
    orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
    pParse->trigStack->orconf = orconf;
    switch( pTriggerStep->op ){
      case TK_SELECT: {
	Select * ss = sqlite3SelectDup(pTriggerStep->pSelect);		  
	assert(ss);
	assert(ss->pSrc);
        sqlite3SelectResolve(pParse, ss, 0);
	sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
	sqlite3SelectDelete(ss);
	break;
      }
      case TK_UPDATE: {
        SrcList *pSrc;
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
        sqlite3Update(pParse, pSrc,
		sqlite3ExprListDup(pTriggerStep->pExprList), 
		sqlite3ExprDup(pTriggerStep->pWhere), orconf);
        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
        break;
      }
      case TK_INSERT: {
        SrcList *pSrc;
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
        sqlite3Insert(pParse, pSrc,
          sqlite3ExprListDup(pTriggerStep->pExprList), 
          sqlite3SelectDup(pTriggerStep->pSelect), 
          sqlite3IdListDup(pTriggerStep->pIdList), orconf);
        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
        break;
      }
      case TK_DELETE: {
        SrcList *pSrc;
        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3DeleteFrom(pParse, pSrc, sqlite3ExprDup(pTriggerStep->pWhere));
        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
        break;
      }
      default:
        assert(0);
    } 
    pTriggerStep = pTriggerStep->pNext;
  }
  sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
  VdbeComment((v, "# end trigger %s", pStepList->pTrig->name));

  return 0;
}

/*
** This is called to code FOR EACH ROW triggers.
**
** When the code that this function generates is executed, the following 
** must be true:
**
** 1. No cursors may be open in the main database.  (But newIdx and oldIdx
**    can be indices of cursors in temporary tables.  See below.)
**
** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
**    a temporary vdbe cursor (index newIdx) must be open and pointing at
**    a row containing values to be substituted for new.* expressions in the
**    trigger program(s).
**
** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
**    a temporary vdbe cursor (index oldIdx) must be open and pointing at
**    a row containing values to be substituted for old.* expressions in the
**    trigger program(s).
**
*/
int sqlite3CodeRowTrigger(
  Parse *pParse,       /* Parse context */
  int op,              /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
  ExprList *pChanges,  /* Changes list for any UPDATE OF triggers */
  int tr_tm,           /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Table *pTab,         /* The table to code triggers from */
  int newIdx,          /* The indice of the "new" row to access */
  int oldIdx,          /* The indice of the "old" row to access */
  int orconf,          /* ON CONFLICT policy */
  int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
){
  Trigger *pTrigger;
  TriggerStack *pStack;
  TriggerStack trigStackEntry;

  assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
  assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );

  assert(newIdx != -1 || oldIdx != -1);

  pTrigger = pTab->pTrigger;
  while( pTrigger ){
    int fire_this = 0;

    /* determine whether we should code this trigger */
    if( pTrigger->op == op && pTrigger->tr_tm == tr_tm ){
      fire_this = 1;
      for(pStack=pParse->trigStack; pStack; pStack=pStack->pNext){
        if( pStack->pTrigger==pTrigger ){
	  fire_this = 0;
	}
      }
      if( op == TK_UPDATE && pTrigger->pColumns &&
          !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
        fire_this = 0;
      }
    }
 
    if( fire_this ){
      int endTrigger;
      Expr * whenExpr;
      AuthContext sContext;
      NameContext sNC;

      memset(&sNC, 0, sizeof(sNC));
      sNC.pParse = pParse;

      /* Push an entry on to the trigger stack */
      trigStackEntry.pTrigger = pTrigger;
      trigStackEntry.newIdx = newIdx;
      trigStackEntry.oldIdx = oldIdx;
      trigStackEntry.pTab = pTab;
      trigStackEntry.pNext = pParse->trigStack;
      trigStackEntry.ignoreJump = ignoreJump;
      pParse->trigStack = &trigStackEntry;
      sqlite3AuthContextPush(pParse, &sContext, pTrigger->name);

      /* code the WHEN clause */
      endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
      whenExpr = sqlite3ExprDup(pTrigger->pWhen);
      if( sqlite3ExprResolveNames(&sNC, whenExpr) ){
        pParse->trigStack = trigStackEntry.pNext;
        sqlite3ExprDelete(whenExpr);
        return 1;
      }
      sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
      sqlite3ExprDelete(whenExpr);

      codeTriggerProgram(pParse, pTrigger->step_list, orconf); 

      /* Pop the entry off the trigger stack */
      pParse->trigStack = trigStackEntry.pNext;
      sqlite3AuthContextPop(&sContext);

      sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
    }
    pTrigger = pTrigger->pNext;
  }
  return 0;
}
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
Added SQLite.Interop/src/update.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
/*
** 2001 September 15
**
** 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 file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
**          \_______/ \________/     \______/       \________________/
*            onError   pTabList      pChanges             pWhere
*/
void sqlite3Update(
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table in which we should change things */
  ExprList *pChanges,    /* Things to be changed */
  Expr *pWhere,          /* The WHERE clause.  May be null */
  int onError            /* How to handle constraint errors */
){
  int i, j;              /* Loop counters */
  Table *pTab;           /* The table to be updated */
  int addr = 0;          /* VDBE instruction address of the start of the loop */
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Vdbe *v;               /* The virtual database engine */
  Index *pIdx;           /* For looping over indices */
  int nIdx;              /* Number of indices that need updating */
  int nIdxTotal;         /* Total number of indices */
  int iCur;              /* VDBE Cursor number of pTab */
  sqlite3 *db;           /* The database structure */
  Index **apIdx = 0;     /* An array of indices that need updating too */
  char *aIdxUsed = 0;    /* aIdxUsed[i]==1 if the i-th index is used */
  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                         ** an expression for the i-th column of the table.
                         ** aXRef[i]==-1 if the i-th column is not changed. */
  int chngRecno;         /* True if the record number is being changed */
  Expr *pRecnoExpr = 0;  /* Expression defining the new record number */
  int openAll = 0;       /* True if all indices need to be opened */
  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* Trying to update a view */
  int triggers_exist = 0;      /* True if any row triggers exist */
#endif

  int newIdx      = -1;  /* index of trigger "new" temp table       */
  int oldIdx      = -1;  /* index of trigger "old" temp table       */

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3_malloc_failed ) goto update_cleanup;
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to update. 
  */
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ) goto update_cleanup;

  /* Figure out if we have any triggers and if the table being
  ** updated is a view
  */
#ifndef SQLITE_OMIT_TRIGGER
  triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges);
  isView = pTab->pSelect!=0;
#else
# define triggers_exist 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
    goto update_cleanup;
  }
  if( isView ){
    if( sqlite3ViewGetColumnNames(pParse, pTab) ){
      goto update_cleanup;
    }
  }
  aXRef = sqliteMallocRaw( sizeof(int) * pTab->nCol );
  if( aXRef==0 ) goto update_cleanup;
  for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;

  /* If there are FOR EACH ROW triggers, allocate cursors for the
  ** special OLD and NEW tables
  */
  if( triggers_exist ){
    newIdx = pParse->nTab++;
    oldIdx = pParse->nTab++;
  }

  /* Allocate a cursors for the main database table and for all indices.
  ** The index cursors might not be used, but if they are used they
  ** need to occur right after the database cursor.  So go ahead and
  ** allocate enough space, just in case.
  */
  pTabList->a[0].iCursor = iCur = pParse->nTab++;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    pParse->nTab++;
  }

  /* Initialize the name-context */
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pParse;
  sNC.pSrcList = pTabList;

  /* Resolve the column names in all the expressions of the
  ** of the UPDATE statement.  Also find the column index
  ** for each column to be updated in the pChanges array.  For each
  ** column to be updated, make sure we have authorization to change
  ** that column.
  */
  chngRecno = 0;
  for(i=0; i<pChanges->nExpr; i++){
    if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
      goto update_cleanup;
    }
    for(j=0; j<pTab->nCol; j++){
      if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
        if( j==pTab->iPKey ){
          chngRecno = 1;
          pRecnoExpr = pChanges->a[i].pExpr;
        }
        aXRef[j] = i;
        break;
      }
    }
    if( j>=pTab->nCol ){
      if( sqlite3IsRowid(pChanges->a[i].zName) ){
        chngRecno = 1;
        pRecnoExpr = pChanges->a[i].pExpr;
      }else{
        sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
        goto update_cleanup;
      }
    }
#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      int rc;
      rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
                           pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
      if( rc==SQLITE_DENY ){
        goto update_cleanup;
      }else if( rc==SQLITE_IGNORE ){
        aXRef[j] = -1;
      }
    }
#endif
  }

  /* Allocate memory for the array apIdx[] and fill it with pointers to every
  ** index that needs to be updated.  Indices only need updating if their
  ** key includes one of the columns named in pChanges or if the record
  ** number of the original table entry is changing.
  */
  for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
    if( chngRecno ){
      i = 0;
    }else {
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
      }
    }
    if( i<pIdx->nColumn ) nIdx++;
  }
  if( nIdxTotal>0 ){
    apIdx = sqliteMallocRaw( sizeof(Index*) * nIdx + nIdxTotal );
    if( apIdx==0 ) goto update_cleanup;
    aIdxUsed = (char*)&apIdx[nIdx];
  }
  for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    if( chngRecno ){
      i = 0;
    }else{
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
      }
    }
    if( i<pIdx->nColumn ){
      if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto update_cleanup;
      apIdx[nIdx++] = pIdx;
      aIdxUsed[j] = 1;
    }else{
      aIdxUsed[j] = 0;
    }
  }

  /* Resolve the column names in all the expressions in the
  ** WHERE clause.
  */
  if( sqlite3ExprResolveNames(&sNC, pWhere) ){
    goto update_cleanup;
  }

  /* Start the view context
  */
  if( isView ){
    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
  }

  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto update_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, 1, pTab->iDb);

  /* If we are trying to update a view, construct that view into
  ** a temporary table.
  */
  if( isView ){
    Select *pView;
    pView = sqlite3SelectDup(pTab->pSelect);
    sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0);
    sqlite3SelectDelete(pView);
  }

  /* Begin the database scan
  */
  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0);
  if( pWInfo==0 ) goto update_cleanup;

  /* Remember the index of every item to be updated.
  */
  sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
  sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);

  /* End the database scan loop.
  */
  sqlite3WhereEnd(pWInfo);

  /* Initialize the count of updated rows
  */
  if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
  }

  if( triggers_exist ){
    /* Create pseudo-tables for NEW and OLD
    */
    sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
    sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);

    /* The top of the update loop for when there are triggers.
    */
    sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
    addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);

    /* Open a cursor and make it point to the record that is
    ** being updated.
    */
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    if( !isView ){
      sqlite3OpenTableForReading(v, iCur, pTab);
    }
    sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);

    /* Generate the OLD table
    */
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);

    /* Generate the NEW table
    */
    if( chngRecno ){
      sqlite3ExprCodeAndCache(pParse, pRecnoExpr);
    }else{
      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    }
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        continue;
      }
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
      }else{
        sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr);
      }
    }
    sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    if( pParse->nErr ) goto update_cleanup;
    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }

    /* Fire the BEFORE and INSTEAD OF triggers
    */
    if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
          newIdx, oldIdx, onError, addr) ){
      goto update_cleanup;
    }
  }

  if( !isView ){
    /* 
    ** Open every index that needs updating.  Note that if any
    ** index could potentially invoke a REPLACE conflict resolution 
    ** action, then we need to open all indices because we might need
    ** to be deleting some records.
    */
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
    if( onError==OE_Replace ){
      openAll = 1;
    }else{
      openAll = 0;
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        if( pIdx->onError==OE_Replace ){
          openAll = 1;
          break;
        }
      }
    }
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( openAll || aIdxUsed[i] ){
        sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
        sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
                       (char*)&pIdx->keyInfo, P3_KEYINFO);
        assert( pParse->nTab>iCur+i+1 );
      }
    }

    /* Loop over every record that needs updating.  We have to load
    ** the old data for each record to be updated because some columns
    ** might not change and we will need to copy the old value.
    ** Also, the old data is needed to delete the old index entires.
    ** So make the cursor point at the old record.
    */
    if( !triggers_exist ){
      sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
      addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    }
    sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);

    /* If the record number will change, push the record number as it
    ** will be after the update. (The old record number is currently
    ** on top of the stack.)
    */
    if( chngRecno ){
      sqlite3ExprCode(pParse, pRecnoExpr);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    }

    /* Compute new data for this record.  
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        continue;
      }
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
      }else{
        sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
      }
    }

    /* Do constraint checks
    */
    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
                                   onError, addr);

    /* Delete the old indices for the current record.
    */
    sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);

    /* If changing the record number, delete the old record.
    */
    if( chngRecno ){
      sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
    }

    /* Create the new index entries and the new record.
    */
    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
  }

  /* Increment the row counter 
  */
  if( db->flags & SQLITE_CountRows && !pParse->trigStack){
    sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
  }

  /* If there are triggers, close all the cursors after each iteration
  ** through the loop.  The fire the after triggers.
  */
  if( triggers_exist ){
    if( !isView ){
      for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
        if( openAll || aIdxUsed[i] )
          sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
      }
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
    if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab, 
          newIdx, oldIdx, onError, addr) ){
      goto update_cleanup;
    }
  }

  /* Repeat the above with the next record to be updated, until
  ** all record selected by the WHERE clause have been updated.
  */
  sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
  sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
  sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);

  /* Close all tables if there were no FOR EACH ROW triggers */
  if( !triggers_exist ){
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( openAll || aIdxUsed[i] ){
        sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
      }
    }
    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
  }else{
    sqlite3VdbeAddOp(v, OP_Close, newIdx, 0);
    sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
  }

  /*
  ** Return the number of rows that were changed. If this routine is 
  ** generating code because of a call to sqlite3NestedParse(), do not
  ** invoke the callback function.
  */
  if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "rows updated", P3_STATIC);
  }

update_cleanup:
  sqlite3AuthContextPop(&sContext);
  sqliteFree(apIdx);
  sqliteFree(aXRef);
  sqlite3SrcListDelete(pTabList);
  sqlite3ExprListDelete(pChanges);
  sqlite3ExprDelete(pWhere);
  return;
}
Added SQLite.Interop/src/utf.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
/*
** 2004 April 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.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
**  11110uuu  10uuzzzz  10yyyyyy  10xxxxxx   000uuuuu zzzzyyyy yyxxxxxx
**
**
** Notes on UTF-16:  (with wwww+1==uuuuu)
**
**      Word-0               Word-1          Value
**  110110ww wwzzzzyy   110111yy yyxxxxxx    000uuuuu zzzzyyyy yyxxxxxx
**  zzzzyyyy yyxxxxxx                        00000000 zzzzyyyy yyxxxxxx
**
**
** BOM or Byte Order Mark:
**     0xff 0xfe   little-endian utf-16 follows
**     0xfe 0xff   big-endian utf-16 follows
**
**
** Handling of malformed strings:
**
** SQLite accepts and processes malformed strings without an error wherever
** possible. However this is not possible when converting between UTF-8 and
** UTF-16.
**
** When converting malformed UTF-8 strings to UTF-16, one instance of the
** replacement character U+FFFD for each byte that cannot be interpeted as
** part of a valid unicode character.
**
** When converting malformed UTF-16 strings to UTF-8, one instance of the
** replacement character U+FFFD for each pair of bytes that cannot be
** interpeted as part of a valid unicode character.
**
** This file contains the following public routines:
**
** sqlite3VdbeMemTranslate() - Translate the encoding used by a Mem* string.
** sqlite3VdbeMemHandleBom() - Handle byte-order-marks in UTF16 Mem* strings.
** sqlite3utf16ByteLen()     - Calculate byte-length of a void* UTF16 string.
** sqlite3utf8CharLen()      - Calculate char-length of a char* UTF8 string.
** sqlite3utf8LikeCompare()  - Do a LIKE match given two UTF8 char* strings.
**
*/
#include "sqliteInt.h"
#include <assert.h>
#include "vdbeInt.h"

/*
** This table maps from the first byte of a UTF-8 character to the number
** of trailing bytes expected. A value '255' indicates that the table key
** is not a legal first byte for a UTF-8 character.
*/
static const u8 xtra_utf8_bytes[256]  = {
/* 0xxxxxxx */
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,

/* 10wwwwww */
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,

/* 110yyyyy */
1, 1, 1, 1, 1, 1, 1, 1,     1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,     1, 1, 1, 1, 1, 1, 1, 1,

/* 1110zzzz */
2, 2, 2, 2, 2, 2, 2, 2,     2, 2, 2, 2, 2, 2, 2, 2,

/* 11110yyy */
3, 3, 3, 3, 3, 3, 3, 3,     255, 255, 255, 255, 255, 255, 255, 255,
};

/*
** This table maps from the number of trailing bytes in a UTF-8 character
** to an integer constant that is effectively calculated for each character
** read by a naive implementation of a UTF-8 character reader. The code
** in the READ_UTF8 macro explains things best.
*/
static const int xtra_utf8_bits[4] =  {
0,
12416,          /* (0xC0 << 6) + (0x80) */
925824,         /* (0xE0 << 12) + (0x80 << 6) + (0x80) */
63447168        /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */
};

#define READ_UTF8(zIn, c) { \
  int xtra;                                            \
  c = *(zIn)++;                                        \
  xtra = xtra_utf8_bytes[c];                           \
  switch( xtra ){                                      \
    case 255: c = (int)0xFFFD; break;                  \
    case 3: c = (c<<6) + *(zIn)++;                     \
    case 2: c = (c<<6) + *(zIn)++;                     \
    case 1: c = (c<<6) + *(zIn)++;                     \
    c -= xtra_utf8_bits[xtra];                         \
  }                                                    \
}
int sqlite3ReadUtf8(const unsigned char *z){
  int c;
  READ_UTF8(z, c);
  return c;
}

#define SKIP_UTF8(zIn) {                               \
  zIn += (xtra_utf8_bytes[*(u8 *)zIn] + 1);            \
}

#define WRITE_UTF8(zOut, c) {                          \
  if( c<0x00080 ){                                     \
    *zOut++ = (c&0xFF);                                \
  }                                                    \
  else if( c<0x00800 ){                                \
    *zOut++ = 0xC0 + ((c>>6)&0x1F);                    \
    *zOut++ = 0x80 + (c & 0x3F);                       \
  }                                                    \
  else if( c<0x10000 ){                                \
    *zOut++ = 0xE0 + ((c>>12)&0x0F);                   \
    *zOut++ = 0x80 + ((c>>6) & 0x3F);                  \
    *zOut++ = 0x80 + (c & 0x3F);                       \
  }else{                                               \
    *zOut++ = 0xF0 + ((c>>18) & 0x07);                 \
    *zOut++ = 0x80 + ((c>>12) & 0x3F);                 \
    *zOut++ = 0x80 + ((c>>6) & 0x3F);                  \
    *zOut++ = 0x80 + (c & 0x3F);                       \
  }                                                    \
}

#define WRITE_UTF16LE(zOut, c) {                                \
  if( c<=0xFFFF ){                                              \
    *zOut++ = (c&0x00FF);                                       \
    *zOut++ = ((c>>8)&0x00FF);                                  \
  }else{                                                        \
    *zOut++ = (((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
    *zOut++ = (0x00D8 + (((c-0x10000)>>18)&0x03));              \
    *zOut++ = (c&0x00FF);                                       \
    *zOut++ = (0x00DC + ((c>>8)&0x03));                         \
  }                                                             \
}

#define WRITE_UTF16BE(zOut, c) {                                \
  if( c<=0xFFFF ){                                              \
    *zOut++ = ((c>>8)&0x00FF);                                  \
    *zOut++ = (c&0x00FF);                                       \
  }else{                                                        \
    *zOut++ = (0x00D8 + (((c-0x10000)>>18)&0x03));              \
    *zOut++ = (((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
    *zOut++ = (0x00DC + ((c>>8)&0x03));                         \
    *zOut++ = (c&0x00FF);                                       \
  }                                                             \
}

#define READ_UTF16LE(zIn, c){                                         \
  c = (*zIn++);                                                       \
  c += ((*zIn++)<<8);                                                 \
  if( c>=0xD800 && c<=0xE000 ){                                       \
    int c2 = (*zIn++);                                                \
    c2 += ((*zIn++)<<8);                                              \
    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
  }                                                                   \
}

#define READ_UTF16BE(zIn, c){                                         \
  c = ((*zIn++)<<8);                                                  \
  c += (*zIn++);                                                      \
  if( c>=0xD800 && c<=0xE000 ){                                       \
    int c2 = ((*zIn++)<<8);                                           \
    c2 += (*zIn++);                                                   \
    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
  }                                                                   \
}

#define SKIP_UTF16BE(zIn){                                            \
  if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn+1)==0x00)) ){  \
    zIn += 4;                                                         \
  }else{                                                              \
    zIn += 2;                                                         \
  }                                                                   \
}
#define SKIP_UTF16LE(zIn){                                            \
  zIn++;                                                              \
  if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn-1)==0x00)) ){  \
    zIn += 3;                                                         \
  }else{                                                              \
    zIn += 1;                                                         \
  }                                                                   \
}

#define RSKIP_UTF16LE(zIn){                                            \
  if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn-1)==0x00)) ){  \
    zIn -= 4;                                                         \
  }else{                                                              \
    zIn -= 2;                                                         \
  }                                                                   \
}
#define RSKIP_UTF16BE(zIn){                                            \
  zIn--;                                                              \
  if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn+1)==0x00)) ){  \
    zIn -= 3;                                                         \
  }else{                                                              \
    zIn -= 1;                                                         \
  }                                                                   \
}

/*
** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
*/ 
/* #define TRANSLATE_TRACE 1 */

#ifndef SQLITE_OMIT_UTF16
/*
** This routine transforms the internal text encoding used by pMem to
** desiredEnc. It is an error if the string is already of the desired
** encoding, or if *pMem does not contain a string value.
*/
int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
  unsigned char zShort[NBFS]; /* Temporary short output buffer */
  int len;                    /* Maximum length of output string in bytes */
  unsigned char *zOut;                  /* Output buffer */
  unsigned char *zIn;                   /* Input iterator */
  unsigned char *zTerm;                 /* End of input */
  unsigned char *z;                     /* Output iterator */
  int c;

  assert( pMem->flags&MEM_Str );
  assert( pMem->enc!=desiredEnc );
  assert( pMem->enc!=0 );
  assert( pMem->n>=0 );

#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
  {
    char zBuf[100];
    sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
    fprintf(stderr, "INPUT:  %s\n", zBuf);
  }
#endif

  /* If the translation is between UTF-16 little and big endian, then 
  ** all that is required is to swap the byte order. This case is handled
  ** differently from the others.
  */
  if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
    u8 temp;
    int rc;
    rc = sqlite3VdbeMemMakeWriteable(pMem);
    if( rc!=SQLITE_OK ){
      assert( rc==SQLITE_NOMEM );
      return SQLITE_NOMEM;
    }
    zIn = pMem->z;
    zTerm = &zIn[pMem->n];
    while( zIn<zTerm ){
      temp = *zIn;
      *zIn = *(zIn+1);
      zIn++;
      *zIn++ = temp;
    }
    pMem->enc = desiredEnc;
    goto translate_out;
  }

  /* Set len to the maximum number of bytes required in the output buffer. */
  if( desiredEnc==SQLITE_UTF8 ){
    /* When converting from UTF-16, the maximum growth results from
    ** translating a 2-byte character to a 3-byte UTF-8 character (i.e.
    ** code-point 0xFFFC). A single byte is required for the output string
    ** nul-terminator.
    */
    len = (pMem->n/2) * 3 + 1;
  }else{
    /* When converting from UTF-8 to UTF-16 the maximum growth is caused
    ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
    ** character. Two bytes are required in the output buffer for the
    ** nul-terminator.
    */
    len = pMem->n * 2 + 2;
  }

  /* Set zIn to point at the start of the input buffer and zTerm to point 1
  ** byte past the end.
  **
  ** Variable zOut is set to point at the output buffer. This may be space
  ** obtained from malloc(), or Mem.zShort, if it large enough and not in
  ** use, or the zShort array on the stack (see above).
  */
  zIn = pMem->z;
  zTerm = &zIn[pMem->n];
  if( len>NBFS ){
    zOut = sqliteMallocRaw(len);
    if( !zOut ) return SQLITE_NOMEM;
  }else{
    zOut = zShort;
  }
  z = zOut;

  if( pMem->enc==SQLITE_UTF8 ){
    if( desiredEnc==SQLITE_UTF16LE ){
      /* UTF-8 -> UTF-16 Little-endian */
      while( zIn<zTerm ){
        READ_UTF8(zIn, c); 
        WRITE_UTF16LE(z, c);
      }
    }else{
      assert( desiredEnc==SQLITE_UTF16BE );
      /* UTF-8 -> UTF-16 Big-endian */
      while( zIn<zTerm ){
        READ_UTF8(zIn, c); 
        WRITE_UTF16BE(z, c);
      }
    }
    pMem->n = z - zOut;
    *z++ = 0;
  }else{
    assert( desiredEnc==SQLITE_UTF8 );
    if( pMem->enc==SQLITE_UTF16LE ){
      /* UTF-16 Little-endian -> UTF-8 */
      while( zIn<zTerm ){
        READ_UTF16LE(zIn, c); 
        WRITE_UTF8(z, c);
      }
    }else{
      /* UTF-16 Little-endian -> UTF-8 */
      while( zIn<zTerm ){
        READ_UTF16BE(zIn, c); 
        WRITE_UTF8(z, c);
      }
    }
    pMem->n = z - zOut;
  }
  *z = 0;
  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );

  sqlite3VdbeMemRelease(pMem);
  pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
  pMem->enc = desiredEnc;
  if( zOut==zShort ){
    memcpy(pMem->zShort, zOut, len);
    zOut = pMem->zShort;
    pMem->flags |= (MEM_Term|MEM_Short);
  }else{
    pMem->flags |= (MEM_Term|MEM_Dyn);
  }
  pMem->z = zOut;

translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
  {
    char zBuf[100];
    sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
    fprintf(stderr, "OUTPUT: %s\n", zBuf);
  }
#endif
  return SQLITE_OK;
}

/*
** This routine checks for a byte-order mark at the beginning of the 
** UTF-16 string stored in *pMem. If one is present, it is removed and
** the encoding of the Mem adjusted. This routine does not do any
** byte-swapping, it just sets Mem.enc appropriately.
**
** The allocation (static, dynamic etc.) and encoding of the Mem may be
** changed by this function.
*/
int sqlite3VdbeMemHandleBom(Mem *pMem){
  int rc = SQLITE_OK;
  u8 bom = 0;

  if( pMem->n<0 || pMem->n>1 ){
    u8 b1 = *(u8 *)pMem->z;
    u8 b2 = *(((u8 *)pMem->z) + 1);
    if( b1==0xFE && b2==0xFF ){
      bom = SQLITE_UTF16BE;
    }
    if( b1==0xFF && b2==0xFE ){
      bom = SQLITE_UTF16LE;
    }
  }
  
  if( bom ){
    /* This function is called as soon as a string is stored in a Mem*,
    ** from within sqlite3VdbeMemSetStr(). At that point it is not possible
    ** for the string to be stored in Mem.zShort, or for it to be stored
    ** in dynamic memory with no destructor.
    */
    assert( !(pMem->flags&MEM_Short) );
    assert( !(pMem->flags&MEM_Dyn) || pMem->xDel );
    if( pMem->flags & MEM_Dyn ){
      void (*xDel)(void*) = pMem->xDel;
      char *z = pMem->z;
      pMem->z = 0;
      pMem->xDel = 0;
      rc = sqlite3VdbeMemSetStr(pMem, &z[2], pMem->n-2, bom, SQLITE_TRANSIENT);
      xDel(z);
    }else{
      rc = sqlite3VdbeMemSetStr(pMem, &pMem->z[2], pMem->n-2, bom, 
          SQLITE_TRANSIENT);
    }
  }
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
** return the number of unicode characters in pZ up to (but not including)
** the first 0x00 byte. If nByte is not less than zero, return the
** number of unicode characters in the first nByte of pZ (or up to 
** the first 0x00, whichever comes first).
*/
int sqlite3utf8CharLen(const char *z, int nByte){
  int r = 0;
  const char *zTerm;
  if( nByte>=0 ){
    zTerm = &z[nByte];
  }else{
    zTerm = (const char *)(-1);
  }
  assert( z<=zTerm );
  while( *z!=0 && z<zTerm ){
    SKIP_UTF8(z);
    r++;
  }
  return r;
}

#ifndef SQLITE_OMIT_UTF16
/*
** pZ is a UTF-16 encoded unicode string. If nChar is less than zero,
** return the number of bytes up to (but not including), the first pair
** of consecutive 0x00 bytes in pZ. If nChar is not less than zero,
** then return the number of bytes in the first nChar unicode characters
** in pZ (or up until the first pair of 0x00 bytes, whichever comes first).
*/
int sqlite3utf16ByteLen(const void *zIn, int nChar){
  int c = 1;
  char const *z = zIn;
  int n = 0;
  if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
    while( c && ((nChar<0) || n<nChar) ){
      READ_UTF16BE(z, c);
      n++;
    }
  }else{
    while( c && ((nChar<0) || n<nChar) ){
      READ_UTF16LE(z, c);
      n++;
    }
  }
  return (z-(char const *)zIn)-((c==0)?2:0);
}

/*
** UTF-16 implementation of the substr()
*/
void sqlite3utf16Substr(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int y, z;
  unsigned char const *zStr;
  unsigned char const *zStrEnd;
  unsigned char const *zStart;
  unsigned char const *zEnd;
  int i;

  zStr = (unsigned char const *)sqlite3_value_text16(argv[0]);
  zStrEnd = &zStr[sqlite3_value_bytes16(argv[0])];
  y = sqlite3_value_int(argv[1]);
  z = sqlite3_value_int(argv[2]);

  if( y>0 ){
    y = y-1;
    zStart = zStr;
    if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
      for(i=0; i<y && zStart<zStrEnd; i++) SKIP_UTF16BE(zStart);
    }else{
      for(i=0; i<y && zStart<zStrEnd; i++) SKIP_UTF16LE(zStart);
    }
  }else{
    zStart = zStrEnd;
    if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
      for(i=y; i<0 && zStart>zStr; i++) RSKIP_UTF16BE(zStart);
    }else{
      for(i=y; i<0 && zStart>zStr; i++) RSKIP_UTF16LE(zStart);
    }
    for(; i<0; i++) z -= 1;
  }

  zEnd = zStart;
  if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
    for(i=0; i<z && zEnd<zStrEnd; i++) SKIP_UTF16BE(zEnd);
  }else{
    for(i=0; i<z && zEnd<zStrEnd; i++) SKIP_UTF16LE(zEnd);
  }

  sqlite3_result_text16(context, zStart, zEnd-zStart, SQLITE_TRANSIENT);
}

#if defined(SQLITE_TEST)
/*
** This routine is called from the TCL test function "translate_selftest".
** It checks that the primitives for serializing and deserializing
** characters in each encoding are inverses of each other.
*/
void sqlite3utfSelfTest(){
  int i;
  unsigned char zBuf[20];
  unsigned char *z;
  int n;
  int c;

  for(i=0; i<0x00110000; i++){
    z = zBuf;
    WRITE_UTF8(z, i);
    n = z-zBuf;
    z = zBuf;
    READ_UTF8(z, c);
    assert( c==i );
    assert( (z-zBuf)==n );
  }
  for(i=0; i<0x00110000; i++){
    if( i>=0xD800 && i<=0xE000 ) continue;
    z = zBuf;
    WRITE_UTF16LE(z, i);
    n = z-zBuf;
    z = zBuf;
    READ_UTF16LE(z, c);
    assert( c==i );
    assert( (z-zBuf)==n );
  }
  for(i=0; i<0x00110000; i++){
    if( i>=0xD800 && i<=0xE000 ) continue;
    z = zBuf;
    WRITE_UTF16BE(z, i);
    n = z-zBuf;
    z = zBuf;
    READ_UTF16BE(z, c);
    assert( c==i );
    assert( (z-zBuf)==n );
  }
}
#endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_UTF16 */
Added SQLite.Interop/src/util.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
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
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

#if SQLITE_MEMDEBUG>2 && defined(__GLIBC__)
#include <execinfo.h>
void print_stack_trace(){
  void *bt[30];
  int i;
  int n = backtrace(bt, 30);

  fprintf(stderr, "STACK: ");
  for(i=0; i<n;i++){
    fprintf(stderr, "%p ", bt[i]);
  }
  fprintf(stderr, "\n");
}
#else
#define print_stack_trace()
#endif

/*
** If malloc() ever fails, this global variable gets set to 1.
** This causes the library to abort and never again function.
*/
int sqlite3_malloc_failed = 0;

/*
** If SQLITE_MEMDEBUG is defined, then use versions of malloc() and
** free() that track memory usage and check for buffer overruns.
*/
#ifdef SQLITE_MEMDEBUG

/*
** For keeping track of the number of mallocs and frees.   This
** is used to check for memory leaks.  The iMallocFail and iMallocReset
** values are used to simulate malloc() failures during testing in 
** order to verify that the library correctly handles an out-of-memory
** condition.
*/
int sqlite3_nMalloc;         /* Number of sqliteMalloc() calls */
int sqlite3_nFree;           /* Number of sqliteFree() calls */
int sqlite3_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */
#if SQLITE_MEMDEBUG>1
static int memcnt = 0;
#endif

/*
** Number of 32-bit guard words
*/
#define N_GUARD 1

/*
** Allocate new memory and set it to zero.  Return NULL if
** no memory is available.
*/
void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){
  void *p;
  int *pi;
  int i, k;
  if( sqlite3_iMallocFail>=0 ){
    sqlite3_iMallocFail--;
    if( sqlite3_iMallocFail==0 ){
      sqlite3_malloc_failed++;
#if SQLITE_MEMDEBUG>1
      fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",
              n, zFile,line);
#endif
      sqlite3_iMallocFail = sqlite3_iMallocReset;
      return 0;
    }
  }
  if( n==0 ) return 0;
  k = (n+sizeof(int)-1)/sizeof(int);
  pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
  if( pi==0 ){
    if( n>0 ) sqlite3_malloc_failed++;
    return 0;
  }
  sqlite3_nMalloc++;
  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
  pi[N_GUARD] = n;
  for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;
  p = &pi[N_GUARD+1];
  memset(p, bZero==0, n);
#if SQLITE_MEMDEBUG>1
  print_stack_trace();
  fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",
      ++memcnt, n, (int)p, zFile,line);
#endif
  return p;
}

/*
** Check to see if the given pointer was obtained from sqliteMalloc()
** and is able to hold at least N bytes.  Raise an exception if this
** is not the case.
**
** This routine is used for testing purposes only.
*/
void sqlite3CheckMemory(void *p, int N){
  int *pi = p;
  int n, i, k;
  pi -= N_GUARD+1;
  for(i=0; i<N_GUARD; i++){
    assert( pi[i]==0xdead1122 );
  }
  n = pi[N_GUARD];
  assert( N>=0 && N<n );
  k = (n+sizeof(int)-1)/sizeof(int);
  for(i=0; i<N_GUARD; i++){
    assert( pi[k+N_GUARD+1+i]==0xdead3344 );
  }
}

/*
** Free memory previously obtained from sqliteMalloc()
*/
void sqlite3Free_(void *p, char *zFile, int line){
  if( p ){
    int *pi, i, k, n;
    pi = p;
    pi -= N_GUARD+1;
    sqlite3_nFree++;
    for(i=0; i<N_GUARD; i++){
      if( pi[i]!=0xdead1122 ){
        fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
        return;
      }
    }
    n = pi[N_GUARD];
    k = (n+sizeof(int)-1)/sizeof(int);
    for(i=0; i<N_GUARD; i++){
      if( pi[k+N_GUARD+1+i]!=0xdead3344 ){
        fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
        return;
      }
    }
    memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));
#if SQLITE_MEMDEBUG>1
    fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",
         ++memcnt, n, (int)p, zFile,line);
#endif
    free(pi);
  }
}

/*
** Resize a prior allocation.  If p==0, then this routine
** works just like sqliteMalloc().  If n==0, then this routine
** works just like sqliteFree().
*/
void *sqlite3Realloc_(void *oldP, int n, char *zFile, int line){
  int *oldPi, *pi, i, k, oldN, oldK;
  void *p;
  if( oldP==0 ){
    return sqlite3Malloc_(n,1,zFile,line);
  }
  if( n==0 ){
    sqlite3Free_(oldP,zFile,line);
    return 0;
  }
  oldPi = oldP;
  oldPi -= N_GUARD+1;
  if( oldPi[0]!=0xdead1122 ){
    fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)oldP);
    return 0;
  }
  oldN = oldPi[N_GUARD];
  oldK = (oldN+sizeof(int)-1)/sizeof(int);
  for(i=0; i<N_GUARD; i++){
    if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){
      fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n",
              (int)oldP);
      return 0;
    }
  }
  k = (n + sizeof(int) - 1)/sizeof(int);
  pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
  if( pi==0 ){
    if( n>0 ) sqlite3_malloc_failed++;
    return 0;
  }
  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
  pi[N_GUARD] = n;
  for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;
  p = &pi[N_GUARD+1];
  memcpy(p, oldP, n>oldN ? oldN : n);
  if( n>oldN ){
    memset(&((char*)p)[oldN], 0x55, n-oldN);
  }
  memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));
  free(oldPi);
#if SQLITE_MEMDEBUG>1
  print_stack_trace();
  fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",
    ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line);
#endif
  return p;
}

/*
** Make a copy of a string in memory obtained from sqliteMalloc()
*/
char *sqlite3StrDup_(const char *z, char *zFile, int line){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqlite3Malloc_(strlen(z)+1, 0, zFile, line);
  if( zNew ) strcpy(zNew, z);
  return zNew;
}
char *sqlite3StrNDup_(const char *z, int n, char *zFile, int line){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqlite3Malloc_(n+1, 0, zFile, line);
  if( zNew ){
    memcpy(zNew, z, n);
    zNew[n] = 0;
  }
  return zNew;
}

/*
** A version of sqliteFree that is always a function, not a macro.
*/
void sqlite3FreeX(void *p){
  sqliteFree(p);
}
#endif /* SQLITE_MEMDEBUG */

/*
** The following versions of malloc() and free() are for use in a
** normal build.
*/
#if !defined(SQLITE_MEMDEBUG)

/*
** Allocate new memory and set it to zero.  Return NULL if
** no memory is available.  See also sqliteMallocRaw().
*/
void *sqlite3Malloc(int n){
  void *p;
  if( (p = malloc(n))==0 ){
    if( n>0 ) sqlite3_malloc_failed++;
  }else{
    memset(p, 0, n);
  }
  return p;
}

/*
** Allocate new memory but do not set it to zero.  Return NULL if
** no memory is available.  See also sqliteMalloc().
*/
void *sqlite3MallocRaw(int n){
  void *p;
  if( (p = malloc(n))==0 ){
    if( n>0 ) sqlite3_malloc_failed++;
  }
  return p;
}

/*
** Free memory previously obtained from sqliteMalloc()
*/
void sqlite3FreeX(void *p){
  if( p ){
    free(p);
  }
}

/*
** Resize a prior allocation.  If p==0, then this routine
** works just like sqliteMalloc().  If n==0, then this routine
** works just like sqliteFree().
*/
void *sqlite3Realloc(void *p, int n){
  void *p2;
  if( p==0 ){
    return sqliteMalloc(n);
  }
  if( n==0 ){
    sqliteFree(p);
    return 0;
  }
  p2 = realloc(p, n);
  if( p2==0 ){
    if( n>0 ) sqlite3_malloc_failed++;
  }
  return p2;
}

/*
** Make a copy of a string in memory obtained from sqliteMalloc()
*/
char *sqlite3StrDup(const char *z){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqliteMallocRaw(strlen(z)+1);
  if( zNew ) strcpy(zNew, z);
  return zNew;
}
char *sqlite3StrNDup(const char *z, int n){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqliteMallocRaw(n+1);
  if( zNew ){
    memcpy(zNew, z, n);
    zNew[n] = 0;
  }
  return zNew;
}
#endif /* !defined(SQLITE_MEMDEBUG) */

/*
** Create a string from the 2nd and subsequent arguments (up to the
** first NULL argument), store the string in memory obtained from
** sqliteMalloc() and make the pointer indicated by the 1st argument
** point to that string.  The 1st argument must either be NULL or 
** point to memory obtained from sqliteMalloc().
*/
void sqlite3SetString(char **pz, const char *zFirst, ...){
  va_list ap;
  int nByte;
  const char *z;
  char *zResult;

  if( pz==0 ) return;
  nByte = strlen(zFirst) + 1;
  va_start(ap, zFirst);
  while( (z = va_arg(ap, const char*))!=0 ){
    nByte += strlen(z);
  }
  va_end(ap);
  sqliteFree(*pz);
  *pz = zResult = sqliteMallocRaw( nByte );
  if( zResult==0 ){
    return;
  }
  strcpy(zResult, zFirst);
  zResult += strlen(zResult);
  va_start(ap, zFirst);
  while( (z = va_arg(ap, const char*))!=0 ){
    strcpy(zResult, z);
    zResult += strlen(zResult);
  }
  va_end(ap);
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG>1
  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
#endif
#endif
}

/*
** Set the most recent error code and error string for the sqlite
** handle "db". The error code is set to "err_code".
**
** If it is not NULL, string zFormat specifies the format of the
** error string in the style of the printf functions: The following
** format characters are allowed:
**
**      %s      Insert a string
**      %z      A string that should be freed after use
**      %d      Insert an integer
**      %T      Insert a token
**      %S      Insert the first element of a SrcList
**
** zFormat and any string tokens that follow it are assumed to be
** encoded in UTF-8.
**
** To clear the most recent error for slqite handle "db", sqlite3Error
** should be called with err_code set to SQLITE_OK and zFormat set
** to NULL.
*/
void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
  if( db && (db->pErr || (db->pErr = sqlite3ValueNew())) ){
    db->errCode = err_code;
    if( zFormat ){
      char *z;
      va_list ap;
      va_start(ap, zFormat);
      z = sqlite3VMPrintf(zFormat, ap);
      va_end(ap);
      sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, sqlite3FreeX);
    }else{
      sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
    }
  }
}

/*
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
** The following formatting characters are allowed:
**
**      %s      Insert a string
**      %z      A string that should be freed after use
**      %d      Insert an integer
**      %T      Insert a token
**      %S      Insert the first element of a SrcList
**
** This function should be used to report any error that occurs whilst
** compiling an SQL statement (i.e. within sqlite3_prepare()). The
** last thing the sqlite3_prepare() function does is copy the error
** stored by this function into the database handle using sqlite3Error().
** Function sqlite3Error() should be used during statement execution
** (sqlite3_step() etc.).
*/
void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  pParse->nErr++;
  sqliteFree(pParse->zErrMsg);
  va_start(ap, zFormat);
  pParse->zErrMsg = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
}

/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters.  The conversion is done in-place.  If the
** input does not begin with a quote character, then this routine
** is a no-op.
**
** 2002-Feb-14: This routine is extended to remove MS-Access style
** brackets from around identifers.  For example:  "[a-b-c]" becomes
** "a-b-c".
*/
void sqlite3Dequote(char *z){
  int quote;
  int i, j;
  if( z==0 ) return;
  quote = z[0];
  switch( quote ){
    case '\'':  break;
    case '"':   break;
    case '[':   quote = ']';  break;
    default:    return;
  }
  for(i=1, j=0; z[i]; i++){
    if( z[i]==quote ){
      if( z[i+1]==quote ){
        z[j++] = quote;
        i++;
      }else{
        z[j++] = 0;
        break;
      }
    }else{
      z[j++] = z[i];
    }
  }
}

/* An array to map all upper-case characters into their corresponding
** lower-case character. 
*/
const unsigned char sqlite3UpperToLower[] = {
      0,  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, 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, 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
};
#define UpperToLower sqlite3UpperToLower

/*
** Some systems have stricmp().  Others have strcasecmp().  Because
** there is no consistency, we will define our own.
*/
int sqlite3StrICmp(const char *zLeft, const char *zRight){
  register unsigned char *a, *b;
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return UpperToLower[*a] - UpperToLower[*b];
}
int sqlite3StrNICmp(const char *zLeft, const char *zRight, int N){
  register unsigned char *a, *b;
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}

/*
** Return TRUE if z is a pure numeric string.  Return FALSE if the
** string contains any character which is not part of a number. If
** the string is numeric and contains the '.' character, set *realnum
** to TRUE (otherwise FALSE).
**
** An empty string is considered non-numeric.
*/
int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
  int incr = (enc==SQLITE_UTF8?1:2);
  if( enc==SQLITE_UTF16BE ) z++;
  if( *z=='-' || *z=='+' ) z += incr;
  if( !isdigit(*(u8*)z) ){
    return 0;
  }
  z += incr;
  if( realnum ) *realnum = 0;
  while( isdigit(*(u8*)z) ){ z += incr; }
  if( *z=='.' ){
    z += incr;
    if( !isdigit(*(u8*)z) ) return 0;
    while( isdigit(*(u8*)z) ){ z += incr; }
    if( realnum ) *realnum = 1;
  }
  if( *z=='e' || *z=='E' ){
    z += incr;
    if( *z=='+' || *z=='-' ) z += incr;
    if( !isdigit(*(u8*)z) ) return 0;
    while( isdigit(*(u8*)z) ){ z += incr; }
    if( realnum ) *realnum = 1;
  }
  return *z==0;
}

/*
** The string z[] is an ascii representation of a real number.
** Convert this string to a double.
**
** This routine assumes that z[] really is a valid number.  If it
** is not, the result is undefined.
**
** This routine is used instead of the library atof() function because
** the library atof() might want to use "," as the decimal point instead
** of "." depending on how locale is set.  But that would cause problems
** for SQL.  So this routine always uses "." regardless of locale.
*/
double sqlite3AtoF(const char *z, const char **pzEnd){
  int sign = 1;
  LONGDOUBLE_TYPE v1 = 0.0;
  if( *z=='-' ){
    sign = -1;
    z++;
  }else if( *z=='+' ){
    z++;
  }
  while( isdigit(*(u8*)z) ){
    v1 = v1*10.0 + (*z - '0');
    z++;
  }
  if( *z=='.' ){
    LONGDOUBLE_TYPE divisor = 1.0;
    z++;
    while( isdigit(*(u8*)z) ){
      v1 = v1*10.0 + (*z - '0');
      divisor *= 10.0;
      z++;
    }
    v1 /= divisor;
  }
  if( *z=='e' || *z=='E' ){
    int esign = 1;
    int eval = 0;
    LONGDOUBLE_TYPE scale = 1.0;
    z++;
    if( *z=='-' ){
      esign = -1;
      z++;
    }else if( *z=='+' ){
      z++;
    }
    while( isdigit(*(u8*)z) ){
      eval = eval*10 + *z - '0';
      z++;
    }
    while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
    while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
    while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
    if( esign<0 ){
      v1 /= scale;
    }else{
      v1 *= scale;
    }
  }
  if( pzEnd ) *pzEnd = z;
  return sign<0 ? -v1 : v1;
}

/*
** Return TRUE if zNum is a 64-bit signed integer and write
** the value of the integer into *pNum.  If zNum is not an integer
** or is an integer that is too large to be expressed with 64 bits,
** then return false.  If n>0 and the integer is string is not
** exactly n bytes long, return false.
**
** When this routine was originally written it dealt with only
** 32-bit numbers.  At that time, it was much faster than the
** atoi() library routine in RedHat 7.2.
*/
int sqlite3atoi64(const char *zNum, i64 *pNum){
  i64 v = 0;
  int neg;
  int i, c;
  if( *zNum=='-' ){
    neg = 1;
    zNum++;
  }else if( *zNum=='+' ){
    neg = 0;
    zNum++;
  }else{
    neg = 0;
  }
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
    v = v*10 + c - '0';
  }
  *pNum = neg ? -v : v;
  return c==0 && i>0 && 
      (i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0));
}

/*
** The string zNum represents an integer.  There might be some other
** information following the integer too, but that part is ignored.
** If the integer that the prefix of zNum represents will fit in a
** 32-bit signed integer, return TRUE.  Otherwise return FALSE.
**
** This routine returns FALSE for the string -2147483648 even that
** that number will in fact fit in a 32-bit integer.  But positive
** 2147483648 will not fit in 32 bits.  So it seems safer to return
** false.
*/
static int sqlite3FitsIn32Bits(const char *zNum){
  int i, c;
  if( *zNum=='-' || *zNum=='+' ) zNum++;
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
  return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);
}

/*
** If zNum represents an integer that will fit in 32-bits, then set
** *pValue to that integer and return true.  Otherwise return false.
*/
int sqlite3GetInt32(const char *zNum, int *pValue){
  if( sqlite3FitsIn32Bits(zNum) ){
    *pValue = atoi(zNum);
    return 1;
  }
  return 0;
}

/*
** The string zNum represents an integer.  There might be some other
** information following the integer too, but that part is ignored.
** If the integer that the prefix of zNum represents will fit in a
** 64-bit signed integer, return TRUE.  Otherwise return FALSE.
**
** This routine returns FALSE for the string -9223372036854775808 even that
** that number will, in theory fit in a 64-bit integer.  Positive
** 9223373036854775808 will not fit in 64 bits.  So it seems safer to return
** false.
*/
int sqlite3FitsIn64Bits(const char *zNum){
  int i, c;
  if( *zNum=='-' || *zNum=='+' ) zNum++;
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
  return i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0);
}


/*
** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.
** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
** when this routine is called.
**
** This routine is a attempt to detect if two threads use the
** same sqlite* pointer at the same time.  There is a race 
** condition so it is possible that the error is not detected.
** But usually the problem will be seen.  The result will be an
** error which can be used to debug the application that is
** using SQLite incorrectly.
**
** Ticket #202:  If db->magic is not a valid open value, take care not
** to modify the db structure at all.  It could be that db is a stale
** pointer.  In other words, it could be that there has been a prior
** call to sqlite3_close(db) and db has been deallocated.  And we do
** not want to write into deallocated memory.
*/
int sqlite3SafetyOn(sqlite3 *db){
  if( db->magic==SQLITE_MAGIC_OPEN ){
    db->magic = SQLITE_MAGIC_BUSY;
    return 0;
  }else if( db->magic==SQLITE_MAGIC_BUSY || db->magic==SQLITE_MAGIC_ERROR ){
    db->magic = SQLITE_MAGIC_ERROR;
    db->flags |= SQLITE_Interrupt;
  }
  return 1;
}

/*
** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
** when this routine is called.
*/
int sqlite3SafetyOff(sqlite3 *db){
  if( db->magic==SQLITE_MAGIC_BUSY ){
    db->magic = SQLITE_MAGIC_OPEN;
    return 0;
  }else if( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ERROR ){
    db->magic = SQLITE_MAGIC_ERROR;
    db->flags |= SQLITE_Interrupt;
  }
  return 1;
}

/*
** Check to make sure we have a valid db pointer.  This test is not
** foolproof but it does provide some measure of protection against
** misuse of the interface such as passing in db pointers that are
** NULL or which have been previously closed.  If this routine returns
** TRUE it means that the db pointer is invalid and should not be
** dereferenced for any reason.  The calling function should invoke
** SQLITE_MISUSE immediately.
*/
int sqlite3SafetyCheck(sqlite3 *db){
  int magic;
  if( db==0 ) return 1;
  magic = db->magic;
  if( magic!=SQLITE_MAGIC_CLOSED &&
         magic!=SQLITE_MAGIC_OPEN &&
         magic!=SQLITE_MAGIC_BUSY ) return 1;
  return 0;
}

/*
** The variable-length integer encoding is as follows:
**
** KEY:
**         A = 0xxxxxxx    7 bits of data and one flag bit
**         B = 1xxxxxxx    7 bits of data and one flag bit
**         C = xxxxxxxx    8 bits of data
**
**  7 bits - A
** 14 bits - BA
** 21 bits - BBA
** 28 bits - BBBA
** 35 bits - BBBBA
** 42 bits - BBBBBA
** 49 bits - BBBBBBA
** 56 bits - BBBBBBBA
** 64 bits - BBBBBBBBC
*/

/*
** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data write will be between 1 and 9 bytes.  The number
** of bytes written is returned.
**
** A variable-length integer consists of the lower 7 bits of each byte
** for all bytes that have the 8th bit set and one byte with the 8th
** bit clear.  Except, if we get to the 9th byte, it stores the full
** 8 bits and is the last byte.
*/
int sqlite3PutVarint(unsigned char *p, u64 v){
  int i, j, n;
  u8 buf[10];
  if( v & (((u64)0xff000000)<<32) ){
    p[8] = v;
    v >>= 8;
    for(i=7; i>=0; i--){
      p[i] = (v & 0x7f) | 0x80;
      v >>= 7;
    }
    return 9;
  }    
  n = 0;
  do{
    buf[n++] = (v & 0x7f) | 0x80;
    v >>= 7;
  }while( v!=0 );
  buf[0] &= 0x7f;
  assert( n<=9 );
  for(i=0, j=n-1; j>=0; j--, i++){
    p[i] = buf[j];
  }
  return n;
}

/*
** Read a 64-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read.  The value is stored in *v.
*/
int sqlite3GetVarint(const unsigned char *p, u64 *v){
  u32 x;
  u64 x64;
  int n;
  unsigned char c;
  if( ((c = p[0]) & 0x80)==0 ){
    *v = c;
    return 1;
  }
  x = c & 0x7f;
  if( ((c = p[1]) & 0x80)==0 ){
    *v = (x<<7) | c;
    return 2;
  }
  x = (x<<7) | (c&0x7f);
  if( ((c = p[2]) & 0x80)==0 ){
    *v = (x<<7) | c;
    return 3;
  }
  x = (x<<7) | (c&0x7f);
  if( ((c = p[3]) & 0x80)==0 ){
    *v = (x<<7) | c;
    return 4;
  }
  x64 = (x<<7) | (c&0x7f);
  n = 4;
  do{
    c = p[n++];
    if( n==9 ){
      x64 = (x64<<8) | c;
      break;
    }
    x64 = (x64<<7) | (c&0x7f);
  }while( (c & 0x80)!=0 );
  *v = x64;
  return n;
}

/*
** Read a 32-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read.  The value is stored in *v.
*/
int sqlite3GetVarint32(const unsigned char *p, u32 *v){
  u32 x;
  int n;
  unsigned char c;
#if 0
  if( ((c = p[0]) & 0x80)==0 ){
    *v = c;
    return 1;
  }
  x = c & 0x7f;
  if( ((c = p[1]) & 0x80)==0 ){
    *v = (x<<7) | c;
    return 2;
  }
  x = (x<<7) | (c & 0x7f);
#else
  if( ((signed char*)p)[0]>=0 ){
    *v = p[0];
    return 1;
  }
  x = p[0] & 0x7f;
  if( ((signed char*)p)[1]>=0 ){
    *v = (x<<7) | p[1];
    return 2;
  }
  x = (x<<7) | (p[1] & 0x7f);
#endif
  n = 2;
  do{
    x = (x<<7) | ((c = p[n++])&0x7f);
  }while( (c & 0x80)!=0 && n<9 );
  *v = x;
  return n;
}

/*
** Return the number of bytes that will be needed to store the given
** 64-bit integer.
*/
int sqlite3VarintLen(u64 v){
  int i = 0;
  do{
    i++;
    v >>= 7;
  }while( v!=0 && i<9 );
  return i;
}

#if (!defined(SQLITE_OMIT_BLOB_LITERAL) && !defined(SQLITE_HAS_CODEC)) \
    || defined(SQLITE_TEST)
/*
** Translate a single byte of Hex into an integer.
*/
static int hexToInt(int h){
  if( h>='0' && h<='9' ){
    return h - '0';
  }else if( h>='a' && h<='f' ){
    return h - 'a' + 10;
  }else{
    assert( h>='A' && h<='F' );
    return h - 'A' + 10;
  }
}
#endif /* (!SQLITE_OMIT_BLOB_LITERAL && !SQLITE_HAS_CODEC) || SQLITE_TEST */

#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
/*
** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
** value.  Return a pointer to its binary value.  Space to hold the
** binary value has been obtained from malloc and must be freed by
** the calling routine.
*/
void *sqlite3HexToBlob(const char *z){
  char *zBlob;
  int i;
  int n = strlen(z);
  if( n%2 ) return 0;

  zBlob = (char *)sqliteMalloc(n/2);
  for(i=0; i<n; i+=2){
    zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]);
  }
  return zBlob;
}
#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */

#if defined(SQLITE_TEST)
/*
** Convert text generated by the "%p" conversion format back into
** a pointer.
*/
void *sqlite3TextToPtr(const char *z){
  void *p;
  u64 v;
  u32 v2;
  if( z[0]=='0' && z[1]=='x' ){
    z += 2;
  }
  v = 0;
  while( *z ){
    v = (v<<4) + hexToInt(*z);
    z++;
  }
  if( sizeof(p)==sizeof(v) ){
    p = *(void**)&v;
  }else{
    assert( sizeof(p)==sizeof(v2) );
    v2 = (u32)v;
    p = *(void**)&v2;
  }
  return p;
}
#endif
Added SQLite.Interop/src/vacuum.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
/*
** 2003 April 6
**
** 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 file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"

#ifndef SQLITE_OMIT_VACUUM
/*
** Generate a random name of 20 character in length.
*/
static void randomName(unsigned char *zBuf){
  static const unsigned char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789";
  int i;
  sqlite3Randomness(20, zBuf);
  for(i=0; i<20; i++){
    zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
  }
}

/*
** Execute zSql on database db. Return an error code.
*/
static int execSql(sqlite3 *db, const char *zSql){
  sqlite3_stmt *pStmt;
  if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
    return sqlite3_errcode(db);
  }
  while( SQLITE_ROW==sqlite3_step(pStmt) );
  return sqlite3_finalize(pStmt);
}

/*
** Execute zSql on database db. The statement returns exactly
** one column. Execute this as SQL on the same database.
*/
static int execExecSql(sqlite3 *db, const char *zSql){
  sqlite3_stmt *pStmt;
  int rc;

  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  if( rc!=SQLITE_OK ) return rc;

  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    rc = execSql(db, sqlite3_column_text(pStmt, 0));
    if( rc!=SQLITE_OK ){
      sqlite3_finalize(pStmt);
      return rc;
    }
  }

  return sqlite3_finalize(pStmt);
}

#endif

/*
** The non-standard VACUUM command is used to clean up the database,
** collapse free space, etc.  It is modelled after the VACUUM command
** in PostgreSQL.
**
** In version 1.0.x of SQLite, the VACUUM command would call
** gdbm_reorganize() on all the database tables.  But beginning
** with 2.0.0, SQLite no longer uses GDBM so this command has
** become a no-op.
*/
void sqlite3Vacuum(Parse *pParse, Token *pTableName){
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);
  }
  return;
}

/*
** This routine implements the OP_Vacuum opcode of the VDBE.
*/
int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
  int rc = SQLITE_OK;     /* Return code from service routines */
#ifndef SQLITE_OMIT_VACUUM
  const char *zFilename;  /* full pathname of the database file */
  int nFilename;          /* number of characters  in zFilename[] */
  char *zTemp = 0;        /* a temporary file in same directory as zFilename */
  Btree *pMain;           /* The database being vacuumed */
  Btree *pTemp;
  char *zSql = 0;

  if( !db->autoCommit ){
    sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
       (char*)0);
    rc = SQLITE_ERROR;
    goto end_of_vacuum;
  }

  /* Get the full pathname of the database file and create a
  ** temporary filename in the same directory as the original file.
  */
  pMain = db->aDb[0].pBt;
  zFilename = sqlite3BtreeGetFilename(pMain);
  assert( zFilename );
  if( zFilename[0]=='\0' ){
    /* The in-memory database. Do nothing. Return directly to avoid causing
    ** an error trying to DETACH the vacuum_db (which never got attached)
    ** in the exit-handler.
    */
    return SQLITE_OK;
  }
  nFilename = strlen(zFilename);
  zTemp = sqliteMalloc( nFilename+100 );
  if( zTemp==0 ){
    rc = SQLITE_NOMEM;
    goto end_of_vacuum;
  }
  strcpy(zTemp, zFilename);

  /* The randomName() procedure in the following loop uses an excellent
  ** source of randomness to generate a name from a space of 1.3e+31 
  ** possibilities.  So unless the directory already contains on the order
  ** of 1.3e+31 files, the probability that the following loop will
  ** run more than once or twice is vanishingly small.  We are certain
  ** enough that this loop will always terminate (and terminate quickly)
  ** that we don't even bother to set a maximum loop count.
  */
  do {
    zTemp[nFilename] = '-';
    randomName((unsigned char*)&zTemp[nFilename+1]);
  } while( sqlite3OsFileExists(zTemp) );

  /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
  ** can be set to 'off' for this file, as it is not recovered if a crash
  ** occurs anyway. The integrity of the database is maintained by a
  ** (possibly synchronous) transaction opened on the main database before
  ** sqlite3BtreeCopyFile() is called.
  **
  ** An optimisation would be to use a non-journaled pager.
  */
  zSql = sqlite3MPrintf("ATTACH '%q' AS vacuum_db;", zTemp);
  if( !zSql ){
    rc = SQLITE_NOMEM;
    goto end_of_vacuum;
  }
  rc = execSql(db, zSql);
  sqliteFree(zSql);
  zSql = 0;
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
  pTemp = db->aDb[db->nDb-1].pBt;
  sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain),
     sqlite3BtreeGetReserve(pMain));
  assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
  execSql(db, "PRAGMA vacuum_db.synchronous=OFF");

#ifndef SQLITE_OMIT_AUTOVACUUM
  sqlite3BtreeSetAutoVacuum(pTemp, sqlite3BtreeGetAutoVacuum(pMain));
#endif

  /* Begin a transaction */
  rc = execSql(db, "BEGIN;");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Query the schema of the main database. Create a mirror schema
  ** in the temporary database.
  */
  rc = execExecSql(db, 
      "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) "
      "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, 
      "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14,100000000)"
      "  FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, 
      "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21,100000000) "
      "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, 
      "SELECT 'CREATE VIEW vacuum_db.' || substr(sql,13,100000000) "
      "  FROM sqlite_master WHERE type='view'"
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Loop through the tables in the main database. For each, do
  ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy
  ** the contents to the temporary database.
  */
  rc = execExecSql(db, 
      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
      "|| ' SELECT * FROM ' || quote(name) || ';'"
      "FROM sqlite_master "
      "WHERE type = 'table' AND name!='sqlite_sequence';"
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Copy over the sequence table
  */
  rc = execExecSql(db, 
      "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
      "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, 
      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
      "|| ' SELECT * FROM ' || quote(name) || ';' "
      "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;


  /* Copy the triggers from the main database to the temporary database.
  ** This was deferred before in case the triggers interfered with copying
  ** the data. It's possible the indices should be deferred until this
  ** point also.
  */
  rc = execExecSql(db, 
      "SELECT 'CREATE TRIGGER  vacuum_db.' || substr(sql, 16, 1000000) "
      "FROM sqlite_master WHERE type='trigger'"
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;


  /* At this point, unless the main db was completely empty, there is now a
  ** transaction open on the vacuum database, but not on the main database.
  ** Open a btree level transaction on the main database. This allows a
  ** call to sqlite3BtreeCopyFile(). The main database btree level
  ** transaction is then committed, so the SQL level never knows it was
  ** opened for writing. This way, the SQL transaction used to create the
  ** temporary database never needs to be committed.
  */
  if( sqlite3BtreeIsInTrans(pTemp) ){
    u32 meta;
    int i;

    /* This array determines which meta meta values are preserved in the
    ** vacuum.  Even entries are the meta value number and odd entries
    ** are an increment to apply to the meta value after the vacuum.
    ** The increment is used to increase the schema cookie so that other
    ** connections to the same database will know to reread the schema.
    */
    static const unsigned char aCopy[] = {
       1, 1,    /* Add one to the old schema cookie */
       3, 0,    /* Preserve the default page cache size */
       5, 0,    /* Preserve the default text encoding */
       6, 0,    /* Preserve the user version */
    };

    assert( 0==sqlite3BtreeIsInTrans(pMain) );
    rc = sqlite3BtreeBeginTrans(pMain, 1);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;

    /* Copy Btree meta values */
    for(i=0; i<sizeof(aCopy)/sizeof(aCopy[0]); i+=2){
      rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
      if( rc!=SQLITE_OK ) goto end_of_vacuum;
      rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
    }

    rc = sqlite3BtreeCopyFile(pMain, pTemp);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;
    rc = sqlite3BtreeCommit(pMain);
  }

end_of_vacuum:
  /* Currently there is an SQL level transaction open on the vacuum
  ** database. No locks are held on any other files (since the main file
  ** was committed at the btree level). So it safe to end the transaction
  ** by manually setting the autoCommit flag to true and detaching the
  ** vacuum database. The vacuum_db journal file is deleted when the pager
  ** is closed by the DETACH.
  */
  db->autoCommit = 1;
  if( rc==SQLITE_OK ){
    rc = execSql(db, "DETACH vacuum_db;");
  }else{
    execSql(db, "DETACH vacuum_db;");
  }
  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  if( zSql ) sqliteFree( zSql );
  sqlite3ResetInternalSchema(db, 0);
#endif
  return rc;
}
Added SQLite.Interop/src/vdbe.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
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
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
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
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
/*
** 2001 September 15
**
** 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 execution method of the 
** Virtual Database Engine (VDBE).  A separate file ("vdbeaux.c")
** handles housekeeping details such as creating and deleting
** VDBE instances.  This file is solely interested in executing
** the VDBE program.
**
** In the external interface, an "sqlite3_stmt*" is an opaque pointer
** to a VDBE.
**
** The SQL parser generates a program which is then executed by
** the VDBE to do the work of the SQL statement.  VDBE programs are 
** similar in form to assembly language.  The program consists of
** a linear sequence of operations.  Each operation has an opcode 
** and 3 operands.  Operands P1 and P2 are integers.  Operand P3 
** is a null-terminated string.   The P2 operand must be non-negative.
** Opcodes will typically ignore one or more operands.  Many opcodes
** ignore all three operands.
**
** Computation results are stored on a stack.  Each entry on the
** stack is either an integer, a null-terminated string, a floating point
** number, or the SQL "NULL" value.  An inplicit conversion from one
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqlite3VdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.1 2005/03/01 16:04:38 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_MoveXX, OP_Next, or OP_Prev opcodes.  The test
** procedures use this information to make sure that indices are
** working correctly.  This variable has no function other than to
** help verify the correct operation of the library.
*/
int sqlite3_search_count = 0;

/*
** When this global variable is positive, it gets decremented once before
** each instruction in the VDBE.  When reaches zero, the SQLITE_Interrupt
** of the db.flags field is set in order to simulate and interrupt.
**
** This facility is used for testing purposes only.  It does not function
** in an ordinary build.
*/
int sqlite3_interrupt_count = 0;

/*
** The next global variable is incremented each type the OP_Sort opcode
** is executed.  The test procedures use this information to make sure that
** sorting is occurring or not occuring at appropriate times.   This variable
** has no function other than to help verify the correct operation of the
** library.
*/
int sqlite3_sort_count = 0;

/*
** Release the memory associated with the given stack level.  This
** leaves the Mem.flags field in an inconsistent state.
*/
#define Release(P) if((P)->flags&MEM_Dyn){ sqlite3VdbeMemRelease(P); }

/*
** Convert the given stack entity into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
     { goto no_mem; }

/*
** Convert the given stack entity into a string that has been obtained
** from sqliteMalloc().  This is different from Stringify() above in that
** Stringify() will use the NBFS bytes of static string space if the string
** will fit but this routine always mallocs for space.
** Return non-zero if we run out of memory.
*/
#define Dynamicify(P,enc) sqlite3VdbeMemDynamicify(P)


/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
** is responsible for deallocating that string.  Because the stack entry
** does not control the string, it might be deleted without the stack
** entry knowing it.
**
** This routine converts an ephemeral string into a dynamically allocated
** string that the stack entry itself controls.  In other words, it
** converts an MEM_Ephem string into an MEM_Dyn string.
*/
#define Deephemeralize(P) \
   if( ((P)->flags&MEM_Ephem)!=0 \
       && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}

/*
** Convert the given stack entity into a integer if it isn't one
** already.
**
** Any prior string or real representation is invalidated.  
** NULLs are converted into 0.
*/
#define Integerify(P) sqlite3VdbeMemIntegerify(P)

/*
** Convert P so that it has type MEM_Real.
**
** Any prior string or integer representation is invalidated.
** NULLs are converted into 0.0.
*/
#define Realify(P) sqlite3VdbeMemRealify(P)

/*
** Argument pMem points at a memory cell that will be passed to a
** user-defined function or returned to the user as the result of a query.
** The second argument, 'db_enc' is the text encoding used by the vdbe for
** stack variables.  This routine sets the pMem->enc and pMem->type
** variables used by the sqlite3_value_*() routines.
*/
#define storeTypeInfo(A,B) _storeTypeInfo(A)
static void _storeTypeInfo(Mem *pMem){
  int flags = pMem->flags;
  if( flags & MEM_Null ){
    pMem->type = SQLITE_NULL;
  }
  else if( flags & MEM_Int ){
    pMem->type = SQLITE_INTEGER;
  }
  else if( flags & MEM_Real ){
    pMem->type = SQLITE_FLOAT;
  }
  else if( flags & MEM_Str ){
    pMem->type = SQLITE_TEXT;
  }else{
    pMem->type = SQLITE_BLOB;
  }
}

/*
** Insert a new aggregate element and make it the element that
** has focus.
**
** Return 0 on success and 1 if memory is exhausted.
*/
static int AggInsert(Agg *p, char *zKey, int nKey){
  AggElem *pElem;
  int i;
  int rc;
  pElem = sqliteMalloc( sizeof(AggElem) + nKey +
                        (p->nMem-1)*sizeof(pElem->aMem[0]) );
  if( pElem==0 ) return SQLITE_NOMEM;
  pElem->zKey = (char*)&pElem->aMem[p->nMem];
  memcpy(pElem->zKey, zKey, nKey);
  pElem->nKey = nKey;

  if( p->pCsr ){
    rc = sqlite3BtreeInsert(p->pCsr, zKey, nKey, &pElem, sizeof(AggElem*));
    if( rc!=SQLITE_OK ){
      sqliteFree(pElem);
      return rc;
    }
  }

  for(i=0; i<p->nMem; i++){
    pElem->aMem[i].flags = MEM_Null;
  }
  p->pCurrent = pElem;
  return 0;
}

/*
** Pop the stack N times.
*/
static void popStack(Mem **ppTos, int N){
  Mem *pTos = *ppTos;
  while( N>0 ){
    N--;
    Release(pTos);
    pTos--;
  }
  *ppTos = pTos;
}

/*
** The parameters are pointers to the head of two sorted lists
** of Sorter structures.  Merge these two lists together and return
** a single sorted list.  This routine forms the core of the merge-sort
** algorithm.
**
** In the case of a tie, left sorts in front of right.
*/
static Sorter *Merge(Sorter *pLeft, Sorter *pRight, KeyInfo *pKeyInfo){
  Sorter sHead;
  Sorter *pTail;
  pTail = &sHead;
  pTail->pNext = 0;
  while( pLeft && pRight ){
    int c = sqlite3VdbeRecordCompare(pKeyInfo, pLeft->nKey, pLeft->zKey,
                                     pRight->nKey, pRight->zKey);
    if( c<=0 ){
      pTail->pNext = pLeft;
      pLeft = pLeft->pNext;
    }else{
      pTail->pNext = pRight;
      pRight = pRight->pNext;
    }
    pTail = pTail->pNext;
  }
  if( pLeft ){
    pTail->pNext = pLeft;
  }else if( pRight ){
    pTail->pNext = pRight;
  }
  return sHead.pNext;
}

/*
** Allocate cursor number iCur.  Return a pointer to it.  Return NULL
** if we run out of memory.
*/
static Cursor *allocateCursor(Vdbe *p, int iCur){
  Cursor *pCx;
  assert( iCur<p->nCursor );
  if( p->apCsr[iCur] ){
    sqlite3VdbeFreeCursor(p->apCsr[iCur]);
  }
  p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
  return pCx;
}

/*
** Apply any conversion required by the supplied column affinity to
** memory cell pRec. affinity may be one of:
**
** SQLITE_AFF_NUMERIC
** SQLITE_AFF_TEXT
** SQLITE_AFF_NONE
** SQLITE_AFF_INTEGER
**
*/
static void applyAffinity(Mem *pRec, char affinity, u8 enc){
  if( affinity==SQLITE_AFF_NONE ){
    /* do nothing */
  }else if( affinity==SQLITE_AFF_TEXT ){
    /* Only attempt the conversion to TEXT if there is an integer or real
    ** representation (blob and NULL do not get converted) but no string
    ** representation.
    */
    if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
      sqlite3VdbeMemStringify(pRec, enc);
    }
    pRec->flags &= ~(MEM_Real|MEM_Int);
  }else{
    if( 0==(pRec->flags&(MEM_Real|MEM_Int)) ){
      /* pRec does not have a valid integer or real representation. 
      ** Attempt a conversion if pRec has a string representation and
      ** it looks like a number.
      */
      int realnum;
      sqlite3VdbeMemNulTerminate(pRec);
      if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum, enc) ){
        if( realnum ){
          Realify(pRec);
        }else{
          Integerify(pRec);
        }
      }
    }

    if( affinity==SQLITE_AFF_INTEGER ){
      /* For INTEGER affinity, try to convert a real value to an int */
      if( (pRec->flags&MEM_Real) && !(pRec->flags&MEM_Int) ){
        pRec->i = pRec->r;
        if( ((double)pRec->i)==pRec->r ){
          pRec->flags |= MEM_Int;
        }
      }
    }
  }
}

#ifdef SQLITE_DEBUG
/*
** Write a nice string representation of the contents of cell pMem
** into buffer zBuf, length nBuf.
*/
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf){
  char *zCsr = zBuf;
  int f = pMem->flags;

  static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};

  if( f&MEM_Blob ){
    int i;
    char c;
    if( f & MEM_Dyn ){
      c = 'z';
      assert( (f & (MEM_Static|MEM_Ephem))==0 );
    }else if( f & MEM_Static ){
      c = 't';
      assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
    }else if( f & MEM_Ephem ){
      c = 'e';
      assert( (f & (MEM_Static|MEM_Dyn))==0 );
    }else{
      c = 's';
    }

    zCsr += sprintf(zCsr, "%c", c);
    zCsr += sprintf(zCsr, "%d[", pMem->n);
    for(i=0; i<16 && i<pMem->n; i++){
      zCsr += sprintf(zCsr, "%02X ", ((int)pMem->z[i] & 0xFF));
    }
    for(i=0; i<16 && i<pMem->n; i++){
      char z = pMem->z[i];
      if( z<32 || z>126 ) *zCsr++ = '.';
      else *zCsr++ = z;
    }

    zCsr += sprintf(zCsr, "]");
    *zCsr = '\0';
  }else if( f & MEM_Str ){
    int j, k;
    zBuf[0] = ' ';
    if( f & MEM_Dyn ){
      zBuf[1] = 'z';
      assert( (f & (MEM_Static|MEM_Ephem))==0 );
    }else if( f & MEM_Static ){
      zBuf[1] = 't';
      assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
    }else if( f & MEM_Ephem ){
      zBuf[1] = 'e';
      assert( (f & (MEM_Static|MEM_Dyn))==0 );
    }else{
      zBuf[1] = 's';
    }
    k = 2;
    k += sprintf(&zBuf[k], "%d", pMem->n);
    zBuf[k++] = '[';
    for(j=0; j<15 && j<pMem->n; j++){
      u8 c = pMem->z[j];
      if( c>=0x20 && c<0x7f ){
        zBuf[k++] = c;
      }else{
        zBuf[k++] = '.';
      }
    }
    zBuf[k++] = ']';
    k += sprintf(&zBuf[k], encnames[pMem->enc]);
    zBuf[k++] = 0;
  }
}
#endif


#ifdef VDBE_PROFILE
/*
** The following routine only works on pentium-class processors.
** It uses the RDTSC opcode to read the cycle count value out of the
** processor and returns that value.  This can be used for high-res
** profiling.
*/
__inline__ unsigned long long int hwtime(void){
  unsigned long long int x;
  __asm__("rdtsc\n\t"
          "mov %%edx, %%ecx\n\t"
          :"=A" (x));
  return x;
}
#endif

/*
** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
** sqlite3_interrupt() routine has been called.  If it has been, then
** processing of the VDBE program is interrupted.
**
** This macro added to every instruction that does a jump in order to
** implement a loop.  This test used to be on every single instruction,
** but that meant we more testing that we needed.  By only testing the
** flag on jump instructions, we get a (small) speed improvement.
*/
#define CHECK_FOR_INTERRUPT \
   if( db->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt;


/*
** Execute as much of a VDBE program as we can then return.
**
** sqlite3VdbeMakeReady() must be called before this routine in order to
** close the program with a final OP_Halt and to set up the callbacks
** and the error message pointer.
**
** Whenever a row or result data is available, this routine will either
** invoke the result callback (if there is one) or return with
** SQLITE_ROW.
**
** If an attempt is made to open a locked database, then this routine
** will either invoke the busy callback (if there is one) or it will
** return SQLITE_BUSY.
**
** If an error occurs, an error message is written to memory obtained
** from sqliteMalloc() and p->zErrMsg is made to point to that memory.
** The error code is stored in p->rc and this routine returns SQLITE_ERROR.
**
** If the callback ever returns non-zero, then the program exits
** immediately.  There will be no error message but the p->rc field is
** set to SQLITE_ABORT and this routine will return SQLITE_ERROR.
**
** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this
** routine to return SQLITE_ERROR.
**
** Other fatal errors return SQLITE_ERROR.
**
** After this routine has finished, sqlite3VdbeFinalize() should be
** used to clean up the mess that was left behind.
*/
int sqlite3VdbeExec(
  Vdbe *p                    /* The VDBE */
){
  int pc;                    /* The program counter */
  Op *pOp;                   /* Current operation */
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  Mem *pTos;                 /* Top entry in the operand stack */
  char zBuf[100];            /* Space to sprintf() an integer */
#ifdef VDBE_PROFILE
  unsigned long long start;  /* CPU clock count at start of opcode */
  int origPc;                /* Program counter at start of opcode */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int nProgressOps = 0;      /* Opcodes executed since progress callback. */
#endif

  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
  assert( db->magic==SQLITE_MAGIC_BUSY );
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
  p->rc = SQLITE_OK;
  assert( p->explain==0 );
  pTos = p->pTos;
  if( sqlite3_malloc_failed ) goto no_mem;
  if( p->popStack ){
    popStack(&pTos, p->popStack);
    p->popStack = 0;
  }
  p->resOnStack = 0;
  CHECK_FOR_INTERRUPT;
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    assert( pTos<=&p->aStack[pc] );
#ifdef VDBE_PROFILE
    origPc = pc;
    start = hwtime();
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if SQLITE_DEBUG is defined.
    */
#ifdef SQLITE_DEBUG
    if( p->trace ){
      if( pc==0 ){
        printf("VDBE Execution Trace:\n");
        sqlite3VdbePrintSql(p);
      }
      sqlite3VdbePrintOp(p->trace, pc, pOp);
    }
    if( p->trace==0 && pc==0 && sqlite3OsFileExists("vdbe_sqltrace") ){
      sqlite3VdbePrintSql(p);
    }
#endif
      

    /* Check to see if we need to simulate an interrupt.  This only happens
    ** if we have a special test build.
    */
#ifdef SQLITE_TEST
    if( sqlite3_interrupt_count>0 ){
      sqlite3_interrupt_count--;
      if( sqlite3_interrupt_count==0 ){
        sqlite3_interrupt(db);
      }
    }
#endif

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
    /* Call the progress callback if it is configured and the required number
    ** of VDBE ops have been executed (either since this invocation of
    ** sqlite3VdbeExec() or since last time the progress callback was called).
    ** If the progress callback returns non-zero, exit the virtual machine with
    ** a return code SQLITE_ABORT.
    */
    if( db->xProgress ){
      if( db->nProgressOps==nProgressOps ){
        if( db->xProgress(db->pProgressArg)!=0 ){
          rc = SQLITE_ABORT;
          continue; /* skip to the next iteration of the for loop */
        }
        nProgressOps = 0;
      }
      nProgressOps++;
    }
#endif

    switch( pOp->opcode ){

/*****************************************************************************
** What follows is a massive switch statement where each case implements a
** separate instruction in the virtual machine.  If we follow the usual
** indentation conventions, each case should be indented by 6 spaces.  But
** that is a lot of wasted space on the left margin.  So the code within
** the switch statement will break with convention and be flush-left. Another
** big comment (similar to this one) will mark the point in the code where
** we transition back to normal indentation.
**
** The formatting of each case is important.  The makefile for SQLite
** generates two C files "opcodes.h" and "opcodes.c" by scanning this
** file looking for lines that begin with "case OP_".  The opcodes.h files
** will be filled with #defines that give unique integer values to each
** opcode and the opcodes.c file is filled with an array of strings where
** each string is the symbolic name for the corresponding opcode.  If the
** case statement is followed by a comment of the form "/# same as ... #/"
** that comment is used to determine the particular value of the opcode.
**
** Documentation about VDBE opcodes is generated by scanning this file
** for lines of that contain "Opcode:".  That line and all subsequent
** comment lines are used in the generation of the opcode.html documentation
** file.
**
** SUMMARY:
**
**     Formatting is important to scripts that scan this file.
**     Do not deviate from the formatting style currently in use.
**
*****************************************************************************/

/* Opcode:  Goto * P2 *
**
** An unconditional jump to address P2.
** The next instruction executed will be 
** the one at index P2 from the beginning of
** the program.
*/
case OP_Goto: {
  CHECK_FOR_INTERRUPT;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Gosub * P2 *
**
** Push the current address plus 1 onto the return address stack
** and then jump to address P2.
**
** The return address stack is of limited depth.  If too many
** OP_Gosub operations occur without intervening OP_Returns, then
** the return address stack will fill up and processing will abort
** with a fatal error.
*/
case OP_Gosub: {
  assert( p->returnDepth<sizeof(p->returnStack)/sizeof(p->returnStack[0]) );
  p->returnStack[p->returnDepth++] = pc+1;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Return * * *
**
** Jump immediately to the next instruction after the last unreturned
** OP_Gosub.  If an OP_Return has occurred for all OP_Gosubs, then
** processing aborts with a fatal error.
*/
case OP_Return: {
  assert( p->returnDepth>0 );
  p->returnDepth--;
  pc = p->returnStack[p->returnDepth] - 1;
  break;
}

/* Opcode:  Halt P1 P2 *
**
** Exit immediately.  All open cursors, Lists, Sorts, etc are closed
** automatically.
**
** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
** or sqlite3_finalize().  For a normal halt, this should be SQLITE_OK (0).
** For errors, it can be some other value.  If P1!=0 then P2 will determine
** whether or not to rollback the current transaction.  Do not rollback
** if P2==OE_Fail. Do the rollback if P2==OE_Rollback.  If P2==OE_Abort,
** then back out all changes that have occurred during this execution of the
** VDBE, but do not rollback the transaction. 
**
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program.  So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {
  p->pTos = pTos;
  p->rc = pOp->p1;
  p->pc = pc;
  p->errorAction = pOp->p2;
  if( pOp->p3 ){
    sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
  }
  rc = sqlite3VdbeHalt(p);
  assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
  if( rc==SQLITE_BUSY ){
    p->rc = SQLITE_BUSY;
    return SQLITE_BUSY;
  }
  return p->rc ? SQLITE_ERROR : SQLITE_DONE;
}

/* Opcode: Integer P1 * P3
**
** The integer value P1 is pushed onto the stack.  If P3 is not zero
** then it is assumed to be a string representation of the same integer.
** If P1 is zero and P3 is not zero, then the value is derived from P3.
**
** If the value cannot be represented as a 32-bits then its value
** will be in P3.
*/
case OP_Integer: {
  pTos++;
  if( pOp->p3==0 ){
    pTos->flags = MEM_Int;
    pTos->i = pOp->p1;
  }else{
    pTos->flags = MEM_Str|MEM_Static|MEM_Term;
    pTos->z = pOp->p3;
    pTos->n = strlen(pTos->z);
    pTos->enc = SQLITE_UTF8;
    pTos->i = sqlite3VdbeIntValue(pTos);
    pTos->flags |= MEM_Int;
  }
  break;
}

/* Opcode: Real * * P3
**
** The string value P3 is converted to a real and pushed on to the stack.
*/
case OP_Real: {            /* same as TK_FLOAT */
  pTos++;
  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
  pTos->z = pOp->p3;
  pTos->n = strlen(pTos->z);
  pTos->enc = SQLITE_UTF8;
  pTos->r = sqlite3VdbeRealValue(pTos);
  pTos->flags |= MEM_Real;
  sqlite3VdbeChangeEncoding(pTos, db->enc);
  break;
}

/* Opcode: String8 * * P3
**
** P3 points to a nul terminated UTF-8 string. This opcode is transformed
** into an OP_String before it is executed for the first time.
*/
case OP_String8: {         /* same as TK_STRING */
#ifndef SQLITE_OMIT_UTF16
  pOp->opcode = OP_String;

  if( db->enc!=SQLITE_UTF8 && pOp->p3 ){
    pTos++;
    sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, db->enc) ) goto no_mem;
    if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
    pTos->flags &= ~(MEM_Dyn);
    pTos->flags |= MEM_Static;
    if( pOp->p3type==P3_DYNAMIC ){
      sqliteFree(pOp->p3);
    }
    pOp->p3type = P3_DYNAMIC;
    pOp->p3 = pTos->z;
    break;
  }
#endif
  /* Otherwise fall through to the next case, OP_String */
}
  
/* Opcode: String * * P3
**
** The string value P3 is pushed onto the stack.  If P3==0 then a
** NULL is pushed onto the stack. P3 is assumed to be a nul terminated
** string encoded with the database native encoding.
*/
case OP_String: {
  pTos++;
  if( pOp->p3 ){
    pTos->flags = MEM_Str|MEM_Static|MEM_Term;
    pTos->z = pOp->p3;
#ifndef SQLITE_OMIT_UTF16
    if( db->enc==SQLITE_UTF8 ){
      pTos->n = strlen(pTos->z);
    }else{
      pTos->n  = sqlite3utf16ByteLen(pTos->z, -1);
    }
#else
    assert( db->enc==SQLITE_UTF8 );
    pTos->n = strlen(pTos->z);
#endif
    pTos->enc = db->enc;
  }else{
    pTos->flags = MEM_Null;
  }
  break;
}

#ifndef SQLITE_OMIT_BLOB_LITERAL
/* Opcode: HexBlob * * P3
**
** P3 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the
** vdbe stack.
**
** The first time this instruction executes, in transforms itself into a
** 'Blob' opcode with a binary blob as P3.
*/
case OP_HexBlob: {            /* same as TK_BLOB */
  pOp->opcode = OP_Blob;
  pOp->p1 = strlen(pOp->p3)/2;
  if( pOp->p1 ){
    char *zBlob = sqlite3HexToBlob(pOp->p3);
    if( !zBlob ) goto no_mem;
    if( pOp->p3type==P3_DYNAMIC ){
      sqliteFree(pOp->p3);
    }
    pOp->p3 = zBlob;
    pOp->p3type = P3_DYNAMIC;
  }else{
    if( pOp->p3type==P3_DYNAMIC ){
      sqliteFree(pOp->p3);
    }
    pOp->p3type = P3_STATIC;
    pOp->p3 = "";
  }

  /* Fall through to the next case, OP_Blob. */
}

/* Opcode: Blob P1 * P3
**
** P3 points to a blob of data P1 bytes long. Push this
** value onto the stack. This instruction is not coded directly
** by the compiler. Instead, the compiler layer specifies
** an OP_HexBlob opcode, with the hex string representation of
** the blob as P3. This opcode is transformed to an OP_Blob
** the first time it is executed.
*/
case OP_Blob: {
  pTos++;
  sqlite3VdbeMemSetStr(pTos, pOp->p3, pOp->p1, 0, 0);
  break;
}
#endif /* SQLITE_OMIT_BLOB_LITERAL */

/* Opcode: Variable P1 * *
**
** Push the value of variable P1 onto the stack.  A variable is
** an unknown in the original SQL string as handed to sqlite3_compile().
** Any occurance of the '?' character in the original SQL is considered
** a variable.  Variables in the SQL string are number from left to
** right beginning with 1.  The values of variables are set using the
** sqlite3_bind() API.
*/
case OP_Variable: {
  int j = pOp->p1 - 1;
  assert( j>=0 && j<p->nVar );

  pTos++;
  sqlite3VdbeMemShallowCopy(pTos, &p->aVar[j], MEM_Static);
  break;
}

/* Opcode: Pop P1 * *
**
** P1 elements are popped off of the top of stack and discarded.
*/
case OP_Pop: {
  assert( pOp->p1>=0 );
  popStack(&pTos, pOp->p1);
  assert( pTos>=&p->aStack[-1] );
  break;
}

/* Opcode: Dup P1 P2 *
**
** A copy of the P1-th element of the stack 
** is made and pushed onto the top of the stack.
** The top of the stack is element 0.  So the
** instruction "Dup 0 0 0" will make a copy of the
** top of the stack.
**
** If the content of the P1-th element is a dynamically
** allocated string, then a new copy of that string
** is made if P2==0.  If P2!=0, then just a pointer
** to the string is copied.
**
** Also see the Pull instruction.
*/
case OP_Dup: {
  Mem *pFrom = &pTos[-pOp->p1];
  assert( pFrom<=pTos && pFrom>=p->aStack );
  pTos++;
  sqlite3VdbeMemShallowCopy(pTos, pFrom, MEM_Ephem);
  if( pOp->p2 ){
    Deephemeralize(pTos);
  }
  break;
}

/* Opcode: Pull P1 * *
**
** The P1-th element is removed from its current location on 
** the stack and pushed back on top of the stack.  The
** top of the stack is element 0, so "Pull 0 0 0" is
** a no-op.  "Pull 1 0 0" swaps the top two elements of
** the stack.
**
** See also the Dup instruction.
*/
case OP_Pull: {
  Mem *pFrom = &pTos[-pOp->p1];
  int i;
  Mem ts;

  ts = *pFrom;
  Deephemeralize(pTos);
  for(i=0; i<pOp->p1; i++, pFrom++){
    Deephemeralize(&pFrom[1]);
    assert( (pFrom->flags & MEM_Ephem)==0 );
    *pFrom = pFrom[1];
    if( pFrom->flags & MEM_Short ){
      assert( pFrom->flags & (MEM_Str|MEM_Blob) );
      assert( pFrom->z==pFrom[1].zShort );
      pFrom->z = pFrom->zShort;
    }
  }
  *pTos = ts;
  if( pTos->flags & MEM_Short ){
    assert( pTos->flags & (MEM_Str|MEM_Blob) );
    assert( pTos->z==pTos[-pOp->p1].zShort );
    pTos->z = pTos->zShort;
  }
  break;
}

/* Opcode: Push P1 * *
**
** Overwrite the value of the P1-th element down on the
** stack (P1==0 is the top of the stack) with the value
** of the top of the stack.  Then pop the top of the stack.
*/
case OP_Push: {
  Mem *pTo = &pTos[-pOp->p1];

  assert( pTo>=p->aStack );
  sqlite3VdbeMemMove(pTo, pTos);
  pTos--;
  break;
}

/* Opcode: Callback P1 * *
**
** Pop P1 values off the stack and form them into an array.  Then
** invoke the callback function using the newly formed array as the
** 3rd parameter.
*/
case OP_Callback: {
  int i;
  assert( p->nResColumn==pOp->p1 );

  for(i=0; i<pOp->p1; i++){
    Mem *pVal = &pTos[0-i];
    sqlite3VdbeMemNulTerminate(pVal);
    storeTypeInfo(pVal, db->enc);
  }

  p->resOnStack = 1;
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
  return SQLITE_ROW;
}

/* Opcode: Concat P1 P2 *
**
** Look at the first P1+2 elements of the stack.  Append them all 
** together with the lowest element first.  The original P1+2 elements
** are popped from the stack if P2==0 and retained if P2==1.  If
** any element of the stack is NULL, then the result is NULL.
**
** When P1==1, this routine makes a copy of the top stack element
** into memory obtained from sqliteMalloc().
*/
case OP_Concat: {           /* same as TK_CONCAT */
  char *zNew;
  int nByte;
  int nField;
  int i, j;
  Mem *pTerm;

  /* Loop through the stack elements to see how long the result will be. */
  nField = pOp->p1 + 2;
  pTerm = &pTos[1-nField];
  nByte = 0;
  for(i=0; i<nField; i++, pTerm++){
    assert( pOp->p2==0 || (pTerm->flags&MEM_Str) );
    if( pTerm->flags&MEM_Null ){
      nByte = -1;
      break;
    }
    Stringify(pTerm, db->enc);
    nByte += pTerm->n;
  }

  if( nByte<0 ){
    /* If nByte is less than zero, then there is a NULL value on the stack.
    ** In this case just pop the values off the stack (if required) and
    ** push on a NULL.
    */
    if( pOp->p2==0 ){
      popStack(&pTos, nField);
    }
    pTos++;
    pTos->flags = MEM_Null;
  }else{
    /* Otherwise malloc() space for the result and concatenate all the
    ** stack values.
    */
    zNew = sqliteMallocRaw( nByte+2 );
    if( zNew==0 ) goto no_mem;
    j = 0;
    pTerm = &pTos[1-nField];
    for(i=j=0; i<nField; i++, pTerm++){
      int n = pTerm->n;
      assert( pTerm->flags & MEM_Str );
      memcpy(&zNew[j], pTerm->z, n);
      j += n;
    }
    zNew[j] = 0;
    zNew[j+1] = 0;
    assert( j==nByte );

    if( pOp->p2==0 ){
      popStack(&pTos, nField);
    }
    pTos++;
    pTos->n = j;
    pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;
    pTos->xDel = 0;
    pTos->enc = db->enc;
    pTos->z = zNew;
  }
  break;
}

/* Opcode: Add * * *
**
** Pop the top two elements from the stack, add them together,
** and push the result back onto the stack.  If either element
** is a string then it is converted to a double using the atof()
** function before the addition.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: Multiply * * *
**
** Pop the top two elements from the stack, multiply them together,
** and push the result back onto the stack.  If either element
** is a string then it is converted to a double using the atof()
** function before the multiplication.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: Subtract * * *
**
** Pop the top two elements from the stack, subtract the
** first (what was on top of the stack) from the second (the
** next on stack)
** and push the result back onto the stack.  If either element
** is a string then it is converted to a double using the atof()
** function before the subtraction.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: Divide * * *
**
** Pop the top two elements from the stack, divide the
** first (what was on top of the stack) from the second (the
** next on stack)
** and push the result back onto the stack.  If either element
** is a string then it is converted to a double using the atof()
** function before the division.  Division by zero returns NULL.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: Remainder * * *
**
** Pop the top two elements from the stack, divide the
** first (what was on top of the stack) from the second (the
** next on stack)
** and push the remainder after division onto the stack.  If either element
** is a string then it is converted to a double using the atof()
** function before the division.  Division by zero returns NULL.
** If either operand is NULL, the result is NULL.
*/
case OP_Add:                   /* same as TK_PLUS */
case OP_Subtract:              /* same as TK_MINUS */
case OP_Multiply:              /* same as TK_STAR */
case OP_Divide:                /* same as TK_SLASH */
case OP_Remainder: {           /* same as TK_REM */
  Mem *pNos = &pTos[-1];
  assert( pNos>=p->aStack );
  if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
    Release(pTos);
    pTos--;
    Release(pTos);
    pTos->flags = MEM_Null;
  }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
    i64 a, b;
    a = pTos->i;
    b = pNos->i;
    switch( pOp->opcode ){
      case OP_Add:         b += a;       break;
      case OP_Subtract:    b -= a;       break;
      case OP_Multiply:    b *= a;       break;
      case OP_Divide: {
        if( a==0 ) goto divide_by_zero;
        b /= a;
        break;
      }
      default: {
        if( a==0 ) goto divide_by_zero;
        b %= a;
        break;
      }
    }
    Release(pTos);
    pTos--;
    Release(pTos);
    pTos->i = b;
    pTos->flags = MEM_Int;
  }else{
    double a, b;
    a = sqlite3VdbeRealValue(pTos);
    b = sqlite3VdbeRealValue(pNos);
    switch( pOp->opcode ){
      case OP_Add:         b += a;       break;
      case OP_Subtract:    b -= a;       break;
      case OP_Multiply:    b *= a;       break;
      case OP_Divide: {
        if( a==0.0 ) goto divide_by_zero;
        b /= a;
        break;
      }
      default: {
        int ia = (int)a;
        int ib = (int)b;
        if( ia==0.0 ) goto divide_by_zero;
        b = ib % ia;
        break;
      }
    }
    Release(pTos);
    pTos--;
    Release(pTos);
    pTos->r = b;
    pTos->flags = MEM_Real;
  }
  break;

divide_by_zero:
  Release(pTos);
  pTos--;
  Release(pTos);
  pTos->flags = MEM_Null;
  break;
}

/* Opcode: CollSeq * * P3
**
** P3 is a pointer to a CollSeq struct. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
**
** The interface used by the implementation of the aforementioned functions
** to retrieve the collation sequence set by this opcode is not available
** publicly, only to user functions defined in func.c.
*/
case OP_CollSeq: {
  assert( pOp->p3type==P3_COLLSEQ );
  break;
}

/* Opcode: Function P1 P2 P3
**
** Invoke a user function (P3 is a pointer to a Function structure that
** defines the function) with P1 arguments taken from the stack.  Pop all
** arguments from the stack and push back the result.
**
** P2 is a 32-bit bitmask indicating whether or not each argument to the 
** function was determined to be constant at compile time. If the first
** argument was constant then bit 0 of P2 is set. This is used to determine
** whether meta data associated with a user function argument using the
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** See also: AggFunc
*/
case OP_Function: {
  int i;
  Mem *pArg;
  sqlite3_context ctx;
  sqlite3_value **apVal;
  int n = pOp->p1;

  n = pOp->p1;
  apVal = p->apArg;
  assert( apVal || n==0 );

  pArg = &pTos[1-n];
  for(i=0; i<n; i++, pArg++){
    apVal[i] = pArg;
    storeTypeInfo(pArg, db->enc);
  }

  assert( pOp->p3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC );
  if( pOp->p3type==P3_FUNCDEF ){
    ctx.pFunc = (FuncDef*)pOp->p3;
    ctx.pVdbeFunc = 0;
  }else{
    ctx.pVdbeFunc = (VdbeFunc*)pOp->p3;
    ctx.pFunc = ctx.pVdbeFunc->pFunc;
  }

  ctx.s.flags = MEM_Null;
  ctx.s.z = 0;
  ctx.s.xDel = 0;
  ctx.isError = 0;
  if( ctx.pFunc->needCollSeq ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  (*ctx.pFunc->xFunc)(&ctx, n, apVal);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  if( sqlite3_malloc_failed ) goto no_mem;
  popStack(&pTos, n);

  /* If any auxilary data functions have been called by this user function,
  ** immediately call the destructor for any non-static values.
  */
  if( ctx.pVdbeFunc ){
    sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p2);
    pOp->p3 = (char *)ctx.pVdbeFunc;
    pOp->p3type = P3_VDBEFUNC;
  }

  /* Copy the result of the function to the top of the stack */
  sqlite3VdbeChangeEncoding(&ctx.s, db->enc);
  pTos++;
  pTos->flags = 0;
  sqlite3VdbeMemMove(pTos, &ctx.s);

  /* If the function returned an error, throw an exception */
  if( ctx.isError ){
    if( !(pTos->flags&MEM_Str) ){
      sqlite3SetString(&p->zErrMsg, "user function error", (char*)0);
    }else{
      sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pTos), (char*)0);
      sqlite3VdbeChangeEncoding(pTos, db->enc);
    }
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: BitAnd * * *
**
** Pop the top two elements from the stack.  Convert both elements
** to integers.  Push back onto the stack the bit-wise AND of the
** two elements.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: BitOr * * *
**
** Pop the top two elements from the stack.  Convert both elements
** to integers.  Push back onto the stack the bit-wise OR of the
** two elements.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: ShiftLeft * * *
**
** Pop the top two elements from the stack.  Convert both elements
** to integers.  Push back onto the stack the second element shifted
** left by N bits where N is the top element on the stack.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: ShiftRight * * *
**
** Pop the top two elements from the stack.  Convert both elements
** to integers.  Push back onto the stack the second element shifted
** right by N bits where N is the top element on the stack.
** If either operand is NULL, the result is NULL.
*/
case OP_BitAnd:                 /* same as TK_BITAND */
case OP_BitOr:                  /* same as TK_BITOR */
case OP_ShiftLeft:              /* same as TK_LSHIFT */
case OP_ShiftRight: {           /* same as TK_RSHIFT */
  Mem *pNos = &pTos[-1];
  int a, b;

  assert( pNos>=p->aStack );
  if( (pTos->flags | pNos->flags) & MEM_Null ){
    popStack(&pTos, 2);
    pTos++;
    pTos->flags = MEM_Null;
    break;
  }
  a = sqlite3VdbeIntValue(pNos);
  b = sqlite3VdbeIntValue(pTos);
  switch( pOp->opcode ){
    case OP_BitAnd:      a &= b;     break;
    case OP_BitOr:       a |= b;     break;
    case OP_ShiftLeft:   a <<= b;    break;
    case OP_ShiftRight:  a >>= b;    break;
    default:   /* CANT HAPPEN */     break;
  }
  Release(pTos);
  pTos--;
  Release(pTos);
  pTos->i = a;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: AddImm  P1 * *
** 
** Add the value P1 to whatever is on top of the stack.  The result
** is always an integer.
**
** To force the top of the stack to be an integer, just add 0.
*/
case OP_AddImm: {
  assert( pTos>=p->aStack );
  Integerify(pTos);
  pTos->i += pOp->p1;
  break;
}

/* Opcode: ForceInt P1 P2 *
**
** Convert the top of the stack into an integer.  If the current top of
** the stack is not numeric (meaning that is is a NULL or a string that
** does not look like an integer or floating point number) then pop the
** stack and jump to P2.  If the top of the stack is numeric then
** convert it into the least integer that is greater than or equal to its
** current value if P1==0, or to the least integer that is strictly
** greater than its current value if P1==1.
*/
case OP_ForceInt: {
  int v;
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
    Release(pTos);
    pTos--;
    pc = pOp->p2 - 1;
    break;
  }
  if( pTos->flags & MEM_Int ){
    v = pTos->i + (pOp->p1!=0);
  }else{
    Realify(pTos);
    v = (int)pTos->r;
    if( pTos->r>(double)v ) v++;
    if( pOp->p1 && pTos->r==(double)v ) v++;
  }
  Release(pTos);
  pTos->i = v;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: MustBeInt P1 P2 *
** 
** Force the top of the stack to be an integer.  If the top of the
** stack is not an integer and cannot be converted into an integer
** with out data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
**
** If the top of the stack is not an integer and P2 is not zero and
** P1 is 1, then the stack is popped.  In all other cases, the depth
** of the stack is unchanged.
*/
case OP_MustBeInt: {
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
  if( (pTos->flags & MEM_Int)==0 ){
    if( pOp->p2==0 ){
      rc = SQLITE_MISMATCH;
      goto abort_due_to_error;
    }else{
      if( pOp->p1 ) popStack(&pTos, 1);
      pc = pOp->p2 - 1;
    }
  }else{
    Release(pTos);
    pTos->flags = MEM_Int;
  }
  break;
}

/* Opcode: Eq P1 P2 P3
**
** Pop the top two elements from the stack.  If they are equal, then
** jump to instruction P2.  Otherwise, continue to the next instruction.
**
** The least significant byte of P1 may be either 0x00 or 0x01. If either
** operand is NULL (and thus if the result is unknown) then take the jump
** only if the least significant byte of P1 is 0x01.
**
** The second least significant byte of P1 must be an affinity character -
** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
** according to the affinity before the comparison is made. If the byte is
** 0x00, then numeric affinity is used.
**
** Once any conversions have taken place, and neither value is NULL, 
** the values are compared. If both values are blobs, or both are text,
** then memcmp() is used to determine the results of the comparison. If
** both values are numeric, then a numeric comparison is used. If the
** two values are of different types, then they are inequal.
**
** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
** stack if the jump would have been taken, or a 0 if not.  Push a
** NULL if either operand was NULL.
**
** If P3 is not NULL it is a pointer to a collating sequence (a CollSeq
** structure) that defines how to compare text.
*/
/* Opcode: Ne P1 P2 P3
**
** This works just like the Eq opcode except that the jump is taken if
** the operands from the stack are not equal.  See the Eq opcode for
** additional information.
*/
/* Opcode: Lt P1 P2 P3
**
** This works just like the Eq opcode except that the jump is taken if
** the 2nd element down on the stack is less than the top of the stack.
** See the Eq opcode for additional information.
*/
/* Opcode: Le P1 P2 P3
**
** This works just like the Eq opcode except that the jump is taken if
** the 2nd element down on the stack is less than or equal to the
** top of the stack.  See the Eq opcode for additional information.
*/
/* Opcode: Gt P1 P2 P3
**
** This works just like the Eq opcode except that the jump is taken if
** the 2nd element down on the stack is greater than the top of the stack.
** See the Eq opcode for additional information.
*/
/* Opcode: Ge P1 P2 P3
**
** This works just like the Eq opcode except that the jump is taken if
** the 2nd element down on the stack is greater than or equal to the
** top of the stack.  See the Eq opcode for additional information.
*/
case OP_Eq:               /* same as TK_EQ */
case OP_Ne:               /* same as TK_NE */
case OP_Lt:               /* same as TK_LT */
case OP_Le:               /* same as TK_LE */
case OP_Gt:               /* same as TK_GT */
case OP_Ge: {             /* same as TK_GE */
  Mem *pNos;
  int flags;
  int res;
  char affinity;

  pNos = &pTos[-1];
  flags = pTos->flags|pNos->flags;

  /* If either value is a NULL P2 is not zero, take the jump if the least
  ** significant byte of P1 is true. If P2 is zero, then push a NULL onto
  ** the stack.
  */
  if( flags&MEM_Null ){
    popStack(&pTos, 2);
    if( pOp->p2 ){
      if( (pOp->p1&0xFF) ) pc = pOp->p2-1;
    }else{
      pTos++;
      pTos->flags = MEM_Null;
    }
    break;
  }

  affinity = (pOp->p1>>8)&0xFF;
  if( affinity ){
    applyAffinity(pNos, affinity, db->enc);
    applyAffinity(pTos, affinity, db->enc);
  }

  assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
  res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);
  switch( pOp->opcode ){
    case OP_Eq:    res = res==0;     break;
    case OP_Ne:    res = res!=0;     break;
    case OP_Lt:    res = res<0;      break;
    case OP_Le:    res = res<=0;     break;
    case OP_Gt:    res = res>0;      break;
    default:       res = res>=0;     break;
  }

  popStack(&pTos, 2);
  if( pOp->p2 ){
    if( res ){
      pc = pOp->p2-1;
    }
  }else{
    pTos++;
    pTos->flags = MEM_Int;
    pTos->i = res;
  }
  break;
}

/* Opcode: And * * *
**
** Pop two values off the stack.  Take the logical AND of the
** two values and push the resulting boolean value back onto the
** stack. 
*/
/* Opcode: Or * * *
**
** Pop two values off the stack.  Take the logical OR of the
** two values and push the resulting boolean value back onto the
** stack. 
*/
case OP_And:              /* same as TK_AND */
case OP_Or: {             /* same as TK_OR */
  Mem *pNos = &pTos[-1];
  int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */

  assert( pNos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    v1 = 2;
  }else{
    Integerify(pTos);
    v1 = pTos->i==0;
  }
  if( pNos->flags & MEM_Null ){
    v2 = 2;
  }else{
    Integerify(pNos);
    v2 = pNos->i==0;
  }
  if( pOp->opcode==OP_And ){
    static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
    v1 = and_logic[v1*3+v2];
  }else{
    static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
    v1 = or_logic[v1*3+v2];
  }
  popStack(&pTos, 2);
  pTos++;
  if( v1==2 ){
    pTos->flags = MEM_Null;
  }else{
    pTos->i = v1==0;
    pTos->flags = MEM_Int;
  }
  break;
}

/* Opcode: Negative * * *
**
** Treat the top of the stack as a numeric quantity.  Replace it
** with its additive inverse.  If the top of the stack is NULL
** its value is unchanged.
*/
/* Opcode: AbsValue * * *
**
** Treat the top of the stack as a numeric quantity.  Replace it
** with its absolute value. If the top of the stack is NULL
** its value is unchanged.
*/
case OP_Negative:              /* same as TK_UMINUS */
case OP_AbsValue: {
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Real ){
    Release(pTos);
    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
      pTos->r = -pTos->r;
    }
    pTos->flags = MEM_Real;
  }else if( pTos->flags & MEM_Int ){
    Release(pTos);
    if( pOp->opcode==OP_Negative || pTos->i<0 ){
      pTos->i = -pTos->i;
    }
    pTos->flags = MEM_Int;
  }else if( pTos->flags & MEM_Null ){
    /* Do nothing */
  }else{
    Realify(pTos);
    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
      pTos->r = -pTos->r;
    }
    pTos->flags = MEM_Real;
  }
  break;
}

/* Opcode: Not * * *
**
** Interpret the top of the stack as a boolean value.  Replace it
** with its complement.  If the top of the stack is NULL its value
** is unchanged.
*/
case OP_Not: {                /* same as TK_NOT */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  Integerify(pTos);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos->i = !pTos->i;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: BitNot * * *
**
** Interpret the top of the stack as an value.  Replace it
** with its ones-complement.  If the top of the stack is NULL its
** value is unchanged.
*/
case OP_BitNot: {             /* same as TK_BITNOT */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  Integerify(pTos);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos->i = ~pTos->i;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: Noop * * *
**
** Do nothing.  This instruction is often useful as a jump
** destination.
*/
case OP_Noop: {
  break;
}

/* Opcode: If P1 P2 *
**
** Pop a single boolean from the stack.  If the boolean popped is
** true, then jump to p2.  Otherwise continue to the next instruction.
** An integer is false if zero and true otherwise.  A string is
** false if it has zero length and true otherwise.
**
** If the value popped of the stack is NULL, then take the jump if P1
** is true and fall through if P1 is false.
*/
/* Opcode: IfNot P1 P2 *
**
** Pop a single boolean from the stack.  If the boolean popped is
** false, then jump to p2.  Otherwise continue to the next instruction.
** An integer is false if zero and true otherwise.  A string is
** false if it has zero length and true otherwise.
**
** If the value popped of the stack is NULL, then take the jump if P1
** is true and fall through if P1 is false.
*/
case OP_If:
case OP_IfNot: {
  int c;
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    c = pOp->p1;
  }else{
    c = sqlite3VdbeIntValue(pTos);
    if( pOp->opcode==OP_IfNot ) c = !c;
  }
  Release(pTos);
  pTos--;
  if( c ) pc = pOp->p2-1;
  break;
}

/* Opcode: IsNull P1 P2 *
**
** If any of the top abs(P1) values on the stack are NULL, then jump
** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
** unchanged.
*/
case OP_IsNull: {            /* same as TK_ISNULL */
  int i, cnt;
  Mem *pTerm;
  cnt = pOp->p1;
  if( cnt<0 ) cnt = -cnt;
  pTerm = &pTos[1-cnt];
  assert( pTerm>=p->aStack );
  for(i=0; i<cnt; i++, pTerm++){
    if( pTerm->flags & MEM_Null ){
      pc = pOp->p2-1;
      break;
    }
  }
  if( pOp->p1>0 ) popStack(&pTos, cnt);
  break;
}

/* Opcode: NotNull P1 P2 *
**
** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the
** stack if P1 times if P1 is greater than zero.  If P1 is less than
** zero then leave the stack unchanged.
*/
case OP_NotNull: {            /* same as TK_NOTNULL */
  int i, cnt;
  cnt = pOp->p1;
  if( cnt<0 ) cnt = -cnt;
  assert( &pTos[1-cnt] >= p->aStack );
  for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
  if( i>=cnt ) pc = pOp->p2-1;
  if( pOp->p1>0 ) popStack(&pTos, cnt);
  break;
}

/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
** opcode must be called to set the number of fields in the table.
**
** This opcode sets the number of columns for cursor P1 to P2.
**
** If OP_KeyAsData is to be applied to cursor P1, it must be executed
** before this op-code.
*/
case OP_SetNumColumns: {
  Cursor *pC;
  assert( (pOp->p1)<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );
  pC = p->apCsr[pOp->p1];
  pC->nField = pOp->p2;
  if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){
    rc = SQLITE_CORRUPT;
    goto abort_due_to_error;
  }
  break;
}

/* Opcode: Column P1 P2 *
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional
** information about the format of the data.) Push onto the stack the value
** of the P2-th column contained in the data. If there are less that (P2+1) 
** values in the record, push a NULL onto the stack.
**
** If the KeyAsData opcode has previously executed on this cursor, then the
** field might be extracted from the key rather than the data.
**
** If P1 is negative, then the record is stored on the stack rather than in
** a table.  For P1==-1, the top of the stack is used.  For P1==-2, the
** next on the stack is used.  And so forth.  The value pushed is always
** just a pointer into the record which is stored further down on the
** stack.  The column value is not copied. The number of columns in the
** record is stored on the stack just above the record itself.
*/
case OP_Column: {
  u32 payloadSize;   /* Number of bytes in the record */
  int p1 = pOp->p1;  /* P1 value of the opcode */
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC = 0;    /* The VDBE cursor */
  char *zRec;        /* Pointer to complete record-data */
  BtCursor *pCrsr;   /* The BTree cursor */
  u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
  u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  u32 nField;        /* number of fields in the record */
  u32 szHdr;         /* Number of bytes in the record header */
  int len;           /* The length of the serialized data for the column */
  int offset = 0;    /* Offset into the data */
  int idx;           /* Index into the header */
  int i;             /* Loop counter */
  char *zData;       /* Part of the record being decoded */
  Mem sMem;          /* For storing the record being decoded */

  sMem.flags = 0;
  assert( p1<p->nCursor );
  pTos++;
  pTos->flags = MEM_Null;

  /* This block sets the variable payloadSize to be the total number of
  ** bytes in the record.
  **
  ** zRec is set to be the complete text of the record if it is available.
  ** The complete record text is always available for pseudo-tables and
  ** when we are decoded a record from the stack.  If the record is stored
  ** in a cursor, the complete record text might be available in the 
  ** pC->aRow cache.  Or it might not be.  If the data is unavailable,
  ** zRec is set to NULL.
  **
  ** We also compute the number of columns in the record.  For cursors,
  ** the number of columns is stored in the Cursor.nField element.  For
  ** records on the stack, the next entry down on the stack is an integer
  ** which is the number of records.
  */
  assert( p1<0 || p->apCsr[p1]!=0 );
  if( p1<0 ){
    /* Take the record off of the stack */
    Mem *pRec = &pTos[p1];
    Mem *pCnt = &pRec[-1];
    assert( pRec>=p->aStack );
    assert( pRec->flags & MEM_Blob );
    payloadSize = pRec->n;
    zRec = pRec->z;
    assert( pCnt>=p->aStack );
    assert( pCnt->flags & MEM_Int );
    nField = pCnt->i;
    pCrsr = 0;
  }else if( (pC = p->apCsr[p1])->pCursor!=0 ){
    /* The record is stored in a B-Tree */
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    zRec = 0;
    pCrsr = pC->pCursor;
    if( pC->nullRow ){
      payloadSize = 0;
    }else if( pC->cacheValid ){
      payloadSize = pC->payloadSize;
      zRec = pC->aRow;
    }else if( pC->keyAsData ){
      i64 payloadSize64;
      sqlite3BtreeKeySize(pCrsr, &payloadSize64);
      payloadSize = payloadSize64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &payloadSize);
    }
    nField = pC->nField;
#ifndef SQLITE_OMIT_TRIGGER
  }else if( pC->pseudoTable ){
    /* The record is the sole entry of a pseudo-table */
    payloadSize = pC->nData;
    zRec = pC->pData;
    pC->cacheValid = 0;
    assert( payloadSize==0 || zRec!=0 );
    nField = pC->nField;
    pCrsr = 0;
#endif
  }else{
    zRec = 0;
    payloadSize = 0;
    pCrsr = 0;
    nField = 0;
  }

  /* If payloadSize is 0, then just push a NULL onto the stack. */
  if( payloadSize==0 ){
    pTos->flags = MEM_Null;
    break;
  }

  assert( p2<nField );

  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( pC && pC->cacheValid ){
    aType = pC->aType;
    aOffset = pC->aOffset;
  }else{
    int avail;    /* Number of bytes of available data */
    if( pC && pC->aType ){
      aType = pC->aType;
    }else{
      aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
    }
    aOffset = &aType[nField];
    if( aType==0 ){
      goto no_mem;
    }

    /* Figure out how many bytes are in the header */
    if( zRec ){
      zData = zRec;
    }else{
      if( pC->keyAsData ){
        zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
      }else{
        zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
      }
      /* If KeyFetch()/DataFetch() managed to get the entire payload,
      ** save the payload in the pC->aRow cache.  That will save us from
      ** having to make additional calls to fetch the content portion of
      ** the record.
      */
      if( avail>=payloadSize ){
        zRec = pC->aRow = zData;
      }else{
        pC->aRow = 0;
      }
    }
    idx = sqlite3GetVarint32(zData, &szHdr);


    /* The KeyFetch() or DataFetch() above are fast and will get the entire
    ** record header in most cases.  But they will fail to get the complete
    ** record header if the record header does not fit on a single page
    ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to
    ** acquire the complete header text.
    */
    if( !zRec && avail<szHdr ){
      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->keyAsData, &sMem);
      if( rc!=SQLITE_OK ){
        goto op_column_out;
      }
      zData = sMem.z;
    }

    /* Scan the header and use it to fill in the aType[] and aOffset[]
    ** arrays.  aType[i] will contain the type integer for the i-th
    ** column and aOffset[i] will contain the offset from the beginning
    ** of the record to the start of the data for the i-th column
    */
    offset = szHdr;
    assert( offset>0 );
    i = 0;
    while( idx<szHdr && i<nField && offset<=payloadSize ){
      aOffset[i] = offset;
      idx += sqlite3GetVarint32(&zData[idx], &aType[i]);
      offset += sqlite3VdbeSerialTypeLen(aType[i]);
      i++;
    }
    Release(&sMem);
    sMem.flags = MEM_Null;

    /* If i is less that nField, then there are less fields in this
    ** record than SetNumColumns indicated there are columns in the
    ** table. Set the offset for any extra columns not present in
    ** the record to 0. This tells code below to push a NULL onto the
    ** stack instead of deserializing a value from the record.
    */
    while( i<nField ){
      aOffset[i++] = 0;
    }

    /* The header should end at the start of data and the data should
    ** end at last byte of the record. If this is not the case then
    ** we are dealing with a malformed record.
    */
    if( idx!=szHdr || offset!=payloadSize ){
      rc = SQLITE_CORRUPT;
      goto op_column_out;
    }

    /* Remember all aType and aColumn information if we have a cursor
    ** to remember it in. */
    if( pC ){
      pC->payloadSize = payloadSize;
      pC->aType = aType;
      pC->aOffset = aOffset;
      pC->cacheValid = 1;
    }
  }

  /* Get the column information. If aOffset[p2] is non-zero, then 
  ** deserialize the value from the record. If aOffset[p2] is zero,
  ** then there are not enough fields in the record to satisfy the
  ** request. The value is NULL in this case.
  */
  if( aOffset[p2] ){
    assert( rc==SQLITE_OK );
    if( zRec ){
      zData = &zRec[aOffset[p2]];
    }else{
      len = sqlite3VdbeSerialTypeLen(aType[p2]);
      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len,pC->keyAsData,&sMem);
      if( rc!=SQLITE_OK ){
        goto op_column_out;
      }
      zData = sMem.z;
    }
    sqlite3VdbeSerialGet(zData, aType[p2], pTos);
    pTos->enc = db->enc;
  }else{
    pTos->flags = MEM_Null;
  }

  /* If we dynamically allocated space to hold the data (in the
  ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
  ** dynamically allocated space over to the pTos structure rather.
  ** This prevents a memory copy.
  */
  if( (sMem.flags & MEM_Dyn)!=0 ){
    assert( pTos->flags & MEM_Ephem );
    assert( pTos->flags & (MEM_Str|MEM_Blob) );
    assert( pTos->z==sMem.z );
    assert( sMem.flags & MEM_Term );
    pTos->flags &= ~MEM_Ephem;
    pTos->flags |= MEM_Dyn|MEM_Term;
  }

  /* pTos->z might be pointing to sMem.zShort[].  Fix that so that we
  ** can abandon sMem */
  rc = sqlite3VdbeMemMakeWriteable(pTos);

op_column_out:
  /* Release the aType[] memory if we are not dealing with cursor */
  if( !pC || !pC->aType ){
    sqliteFree(aType);
  }
  break;
}

/* Opcode: MakeRecord P1 P2 P3
**
** Convert the top abs(P1) entries of the stack into a single entry
** suitable for use as a data record in a database table or as a key
** in an index.  The details of the format are irrelavant as long as
** the OP_Column opcode can decode the record later and as long as the
** sqlite3VdbeRecordCompare function will correctly compare two encoded
** records.  Refer to source code comments for the details of the record
** format.
**
** The original stack entries are popped from the stack if P1>0 but
** remain on the stack if P1<0.
**
** The P2 argument is divided into two 16-bit words before it is processed.
** If the hi-word is non-zero, then an extra integer is read from the stack
** and appended to the record as a varint.  If the low-word of P2 is not
** zero and one or more of the entries are NULL, then jump to the value of
** the low-word of P2.  This feature can be used to skip a uniqueness test
** on indices.
**
** P3 may be a string that is P1 characters long.  The nth character of the
** string indicates the column affinity that should be used for the nth
** field of the index key (i.e. the first character of P3 corresponds to the
** lowest element on the stack).
**
** The mapping from character to affinity is as follows:
**    'n' = NUMERIC.
**    'i' = INTEGER.
**    't' = TEXT.
**    'o' = NONE.
**
** If P3 is NULL then all index fields have the affinity NONE.
*/
case OP_MakeRecord: {
  /* Assuming the record contains N fields, the record format looks
  ** like this:
  **
  ** ------------------------------------------------------------------------
  ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | 
  ** ------------------------------------------------------------------------
  **
  ** Data(0) is taken from the lowest element of the stack and data(N-1) is
  ** the top of the stack.
  **
  ** Each type field is a varint representing the serial type of the 
  ** corresponding data element (see sqlite3VdbeSerialType()). The
  ** hdr-size field is also a varint which is the offset from the beginning
  ** of the record to data0.
  */
  unsigned char *zNewRecord;
  unsigned char *zCsr;
  Mem *pRec;
  Mem *pRowid = 0;
  int nData = 0;         /* Number of bytes of data space */
  int nHdr = 0;          /* Number of bytes of header space */
  int nByte = 0;         /* Space required for this record */
  u32 serial_type;       /* Type field */
  int containsNull = 0;  /* True if any of the data fields are NULL */
  char zTemp[NBFS];      /* Space to hold small records */
  Mem *pData0;

  int leaveOnStack;      /* If true, leave the entries on the stack */
  int nField;            /* Number of fields in the record */
  int jumpIfNull;        /* Jump here if non-zero and any entries are NULL. */
  int addRowid;          /* True to append a rowid column at the end */
  char *zAffinity;       /* The affinity string for the record */

  leaveOnStack = ((pOp->p1<0)?1:0);
  nField = pOp->p1 * (leaveOnStack?-1:1);
  jumpIfNull = (pOp->p2 & 0x00FFFFFF);
  addRowid = ((pOp->p2>>24) & 0x0000FFFF)?1:0;
  zAffinity = pOp->p3;

  pData0 = &pTos[1-nField];
  assert( pData0>=p->aStack );
  containsNull = 0;

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  for(pRec=pData0; pRec<=pTos; pRec++){
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
    }
    if( pRec->flags&MEM_Null ){
      containsNull = 1;
    }
    serial_type = sqlite3VdbeSerialType(pRec);
    nData += sqlite3VdbeSerialTypeLen(serial_type);
    nHdr += sqlite3VarintLen(serial_type);
  }

  /* If we have to append a varint rowid to this record, set 'rowid'
  ** to the value of the rowid and increase nByte by the amount of space
  ** required to store it and the 0x00 seperator byte.
  */
  if( addRowid ){
    pRowid = &pTos[0-nField];
    assert( pRowid>=p->aStack );
    Integerify(pRowid);
    serial_type = sqlite3VdbeSerialType(pRowid);
    nData += sqlite3VdbeSerialTypeLen(serial_type);
    nHdr += sqlite3VarintLen(serial_type);
  }

  /* Add the initial header varint and total the size */
  nHdr += sqlite3VarintLen(nHdr);
  nByte = nHdr+nData;

  /* Allocate space for the new record. */
  if( nByte>sizeof(zTemp) ){
    zNewRecord = sqliteMallocRaw(nByte);
    if( !zNewRecord ){
      goto no_mem;
    }
  }else{
    zNewRecord = zTemp;
  }

  /* Write the record */
  zCsr = zNewRecord;
  zCsr += sqlite3PutVarint(zCsr, nHdr);
  for(pRec=pData0; pRec<=pTos; pRec++){
    serial_type = sqlite3VdbeSerialType(pRec);
    zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
  }
  if( addRowid ){
    zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid));
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
  }
  if( addRowid ){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
  }
  assert( zCsr==(zNewRecord+nByte) );

  /* Pop entries off the stack if required. Push the new record on. */
  if( !leaveOnStack ){
    popStack(&pTos, nField+addRowid);
  }
  pTos++;
  pTos->n = nByte;
  if( nByte<=sizeof(zTemp) ){
    assert( zNewRecord==(unsigned char *)zTemp );
    pTos->z = pTos->zShort;
    memcpy(pTos->zShort, zTemp, nByte);
    pTos->flags = MEM_Blob | MEM_Short;
  }else{
    assert( zNewRecord!=(unsigned char *)zTemp );
    pTos->z = zNewRecord;
    pTos->flags = MEM_Blob | MEM_Dyn;
    pTos->xDel = 0;
  }

  /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
  if( jumpIfNull && containsNull ){
    pc = jumpIfNull - 1;
  }
  break;
}

/* Opcode: Statement P1 * *
**
** Begin an individual statement transaction which is part of a larger
** BEGIN..COMMIT transaction.  This is needed so that the statement
** can be rolled back after an error without having to roll back the
** entire transaction.  The statement transaction will automatically
** commit when the VDBE halts.
**
** The statement is begun on the database file with index P1.  The main
** database file has an index of 0 and the file used for temporary tables
** has an index of 1.
*/
case OP_Statement: {
  int i = pOp->p1;
  Btree *pBt;
  if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt) && !(db->autoCommit) ){
    assert( sqlite3BtreeIsInTrans(pBt) );
    if( !sqlite3BtreeIsInStmt(pBt) ){
      rc = sqlite3BtreeBeginStmt(pBt);
    }
  }
  break;
}

/* Opcode: AutoCommit P1 P2 *
**
** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
  u8 i = pOp->p1;
  u8 rollback = pOp->p2;

  assert( i==1 || i==0 );
  assert( i==1 || rollback==0 );

  assert( db->activeVdbeCnt>0 );  /* At least this one VM is active */

  if( db->activeVdbeCnt>1 && i && !db->autoCommit ){
    /* If this instruction implements a COMMIT or ROLLBACK, other VMs are
    ** still running, and a transaction is active, return an error indicating
    ** that the other VMs must complete first. 
    */
    sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit", 
        " transaction - SQL statements in progress", 0);
    rc = SQLITE_ERROR;
  }else if( i!=db->autoCommit ){
    db->autoCommit = i;
    if( pOp->p2 ){
      assert( i==1 );
      sqlite3RollbackAll(db);
    }else if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
      p->pTos = pTos;
      p->pc = pc;
      db->autoCommit = 1-i;
      p->rc = SQLITE_BUSY;
      return SQLITE_BUSY;
    }
    return SQLITE_DONE;
  }else{
    sqlite3SetString(&p->zErrMsg,
        (!i)?"cannot start a transaction within a transaction":(
        (rollback)?"cannot rollback - no transaction is active":
                   "cannot commit - no transaction is active"), 0);
         
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: Transaction P1 P2 *
**
** Begin a transaction.  The transaction ends when a Commit or Rollback
** opcode is encountered.  Depending on the ON CONFLICT setting, the
** transaction might also be rolled back if an error is encountered.
**
** P1 is the index of the database file on which the transaction is
** started.  Index 0 is the main database file and index 1 is the
** file used for temporary tables.
**
** If P2 is non-zero, then a write-transaction is started.  A RESERVED lock is
** obtained on the database file when a write-transaction is started.  No
** other process can start another write transaction while this transaction is
** underway.  Starting a write transaction also creates a rollback journal. A
** write transaction must be started before any changes can be made to the
** database.  If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
** on the file.
**
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
  int i = pOp->p1;
  Btree *pBt;

  assert( i>=0 && i<db->nDb );
  pBt = db->aDb[i].pBt;

  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = SQLITE_BUSY;
      p->pTos = pTos;
      return SQLITE_BUSY;
    }
    if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){
      goto abort_due_to_error;
    }
  }
  break;
}

/* Opcode: ReadCookie P1 P2 *
**
** Read cookie number P2 from database P1 and push it onto the stack.
** P2==0 is the schema version.  P2==1 is the database format.
** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
** the main database file and P1==1 is the database file used to store
** temporary tables.
**
** There must be a read-lock on the database (either a transaction
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: {
  int iMeta;
  assert( pOp->p2<SQLITE_N_BTREE_META );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( db->aDb[pOp->p1].pBt!=0 );
  /* The indexing of meta values at the schema layer is off by one from
  ** the indexing in the btree layer.  The btree considers meta[0] to
  ** be the number of free pages in the database (a read-only value)
  ** and meta[1] to be the schema cookie.  The schema layer considers
  ** meta[1] to be the schema cookie.  So we have to shift the index
  ** by one in the following statement.
  */
  rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, 1 + pOp->p2, (u32 *)&iMeta);
  pTos++;
  pTos->i = iMeta;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: SetCookie P1 P2 *
**
** Write the top of the stack into cookie number P2 of database P1.
** P2==0 is the schema version.  P2==1 is the database format.
** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
** the main database file and P1==1 is the database file used to store
** temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: {
  Db *pDb;
  assert( pOp->p2<SQLITE_N_BTREE_META );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pDb = &db->aDb[pOp->p1];
  assert( pDb->pBt!=0 );
  assert( pTos>=p->aStack );
  Integerify(pTos);
  /* See note about index shifting on OP_ReadCookie */
  rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->i);
  if( pOp->p2==0 ){
    /* When the schema cookie changes, record the new cookie internally */
    pDb->schema_cookie = pTos->i;
    db->flags |= SQLITE_InternChanges;
  }
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  break;
}

/* Opcode: VerifyCookie P1 P2 *
**
** Check the value of global database parameter number 0 (the
** schema version) and make sure it is equal to P2.  
** P1 is the database number which is 0 for the main database file
** and 1 for the file holding temporary tables and some higher number
** for auxiliary databases.
**
** The cookie changes its value whenever the database schema changes.
** This operation is used to detect when that the cookie has changed
** and that the current process needs to reread the schema.
**
** Either a transaction needs to have been started or an OP_Open needs
** to be executed (to establish a read lock) before this opcode is
** invoked.
*/
case OP_VerifyCookie: {
  int iMeta;
  Btree *pBt;
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pBt = db->aDb[pOp->p1].pBt;
  if( pBt ){
    rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta);
  }else{
    rc = SQLITE_OK;
    iMeta = 0;
  }
  if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
    sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0);
    rc = SQLITE_SCHEMA;
  }
  break;
}

/* Opcode: OpenRead P1 P2 P3
**
** Open a read-only cursor for the database table whose root page is
** P2 in a database file.  The database file is determined by an 
** integer from the top of the stack.  0 means the main database and
** 1 means the database used for temporary tables.  Give the new 
** cursor an identifier of P1.  The P1 values need not be contiguous
** but all P1 values should be small integers.  It is an error for
** P1 to be negative.
**
** If P2==0 then take the root page number from the next of the stack.
**
** There will be a read lock on the database whenever there is an
** open cursor.  If the database was unlocked prior to this instruction
** then a read lock is acquired as part of this instruction.  A read
** lock allows other processes to read the database but prohibits
** any other process from modifying the database.  The read lock is
** released when all cursors are closed.  If this instruction attempts
** to get a read lock but fails, the script terminates with an
** SQLITE_BUSY error code.
**
** The P3 value is a pointer to a KeyInfo structure that defines the
** content and collating sequence of indices.  P3 is NULL for cursors
** that are not pointing to indices.
**
** See also OpenWrite.
*/
/* Opcode: OpenWrite P1 P2 P3
**
** Open a read/write cursor named P1 on the table or index whose root
** page is P2.  If P2==0 then take the root page number from the stack.
**
** The P3 value is a pointer to a KeyInfo structure that defines the
** content and collating sequence of indices.  P3 is NULL for cursors
** that are not pointing to indices.
**
** This instruction works just like OpenRead except that it opens the cursor
** in read/write mode.  For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
**
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {
  int i = pOp->p1;
  int p2 = pOp->p2;
  int wrFlag;
  Btree *pX;
  int iDb;
  Cursor *pCur;
  
  assert( pTos>=p->aStack );
  Integerify(pTos);
  iDb = pTos->i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  assert( iDb>=0 && iDb<db->nDb );
  pX = db->aDb[iDb].pBt;
  assert( pX!=0 );
  wrFlag = pOp->opcode==OP_OpenWrite;
  if( p2<=0 ){
    assert( pTos>=p->aStack );
    Integerify(pTos);
    p2 = pTos->i;
    assert( (pTos->flags & MEM_Dyn)==0 );
    pTos--;
    if( p2<2 ){
      sqlite3SetString(&p->zErrMsg, "root page number less than 2", (char*)0);
      rc = SQLITE_INTERNAL;
      break;
    }
  }
  assert( i>=0 );
  pCur = allocateCursor(p, i);
  if( pCur==0 ) goto no_mem;
  pCur->nullRow = 1;
  if( pX==0 ) break;
  /* We always provide a key comparison function.  If the table being
  ** opened is of type INTKEY, the comparision function will be ignored. */
  rc = sqlite3BtreeCursor(pX, p2, wrFlag,
           sqlite3VdbeRecordCompare, pOp->p3,
           &pCur->pCursor);
  pCur->pKeyInfo = (KeyInfo*)pOp->p3;
  if( pCur->pKeyInfo ){
    pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
    pCur->pKeyInfo->enc = p->db->enc;
  }else{
    pCur->pIncrKey = &pCur->bogusIncrKey;
  }
  switch( rc ){
    case SQLITE_BUSY: {
      p->pc = pc;
      p->rc = SQLITE_BUSY;
      p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
      return SQLITE_BUSY;
    }
    case SQLITE_OK: {
      int flags = sqlite3BtreeFlags(pCur->pCursor);
      pCur->intKey = (flags & BTREE_INTKEY)!=0;
      pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
      break;
    }
    case SQLITE_EMPTY: {
      rc = SQLITE_OK;
      break;
    }
    default: {
      goto abort_due_to_error;
    }
  }
  break;
}

/* Opcode: OpenTemp P1 * P3
**
** Open a new cursor to a transient table.
** The transient cursor is always opened read/write even if 
** the main database is read-only.  The transient table is deleted
** automatically when the cursor is closed.
**
** The cursor points to a BTree table if P3==0 and to a BTree index
** if P3 is not 0.  If P3 is not NULL, it points to a KeyInfo structure
** that defines the format of keys in the index.
**
** This opcode is used for tables that exist for the duration of a single
** SQL statement only.  Tables created using CREATE TEMPORARY TABLE
** are opened using OP_OpenRead or OP_OpenWrite.  "Temporary" in the
** context of this opcode means for the duration of a single SQL statement
** whereas "Temporary" in the context of CREATE TABLE means for the duration
** of the connection to the database.  Same word; different meanings.
*/
case OP_OpenTemp: {
  int i = pOp->p1;
  Cursor *pCx;
  assert( i>=0 );
  pCx = allocateCursor(p, i);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
  if( rc==SQLITE_OK ){
    rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
  }
  if( rc==SQLITE_OK ){
    /* If a transient index is required, create it by calling
    ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
    ** opening it. If a transient table is required, just use the
    ** automatically created table with root-page 1 (an INTKEY table).
    */
    if( pOp->p3 ){
      int pgno;
      assert( pOp->p3type==P3_KEYINFO );
      rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); 
      if( rc==SQLITE_OK ){
        assert( pgno==MASTER_ROOT+1 );
        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
            pOp->p3, &pCx->pCursor);
        pCx->pKeyInfo = (KeyInfo*)pOp->p3;
        pCx->pKeyInfo->enc = p->db->enc;
        pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
      }
    }else{
      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
      pCx->intKey = 1;
      pCx->pIncrKey = &pCx->bogusIncrKey;
    }
  }
  break;
}

#ifndef SQLITE_OMIT_TRIGGER
/* Opcode: OpenPseudo P1 * *
**
** Open a new cursor that points to a fake table that contains a single
** row of data.  Any attempt to write a second row of data causes the
** first row to be deleted.  All data is deleted when the cursor is
** closed.
**
** A pseudo-table created by this opcode is useful for holding the
** NEW or OLD tables in a trigger.
*/
case OP_OpenPseudo: {
  int i = pOp->p1;
  Cursor *pCx;
  assert( i>=0 );
  pCx = allocateCursor(p, i);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->pseudoTable = 1;
  pCx->pIncrKey = &pCx->bogusIncrKey;
  break;
}
#endif

/* Opcode: Close P1 * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
*/
case OP_Close: {
  int i = pOp->p1;
  if( i>=0 && i<p->nCursor ){
    sqlite3VdbeFreeCursor(p->apCsr[i]);
    p->apCsr[i] = 0;
  }
  break;
}

/* Opcode: MoveGe P1 P2 *
**
** Pop the top of the stack and use its value as a key.  Reposition
** cursor P1 so that it points to the smallest entry that is greater
** than or equal to the key that was popped ffrom the stack.
** If there are no records greater than or equal to the key and P2 
** is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, MoveLt, MoveGt, MoveLe
*/
/* Opcode: MoveGt P1 P2 *
**
** Pop the top of the stack and use its value as a key.  Reposition
** cursor P1 so that it points to the smallest entry that is greater
** than the key from the stack.
** If there are no records greater than the key and P2 is not zero,
** then jump to P2.
**
** See also: Found, NotFound, Distinct, MoveLt, MoveGe, MoveLe
*/
/* Opcode: MoveLt P1 P2 *
**
** Pop the top of the stack and use its value as a key.  Reposition
** cursor P1 so that it points to the largest entry that is less
** than the key from the stack.
** If there are no records less than the key and P2 is not zero,
** then jump to P2.
**
** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLe
*/
/* Opcode: MoveLe P1 P2 *
**
** Pop the top of the stack and use its value as a key.  Reposition
** cursor P1 so that it points to the largest entry that is less than
** or equal to the key that was popped from the stack.
** If there are no records less than or eqal to the key and P2 is not zero,
** then jump to P2.
**
** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt
*/
case OP_MoveLt:
case OP_MoveLe:
case OP_MoveGe:
case OP_MoveGt: {
  int i = pOp->p1;
  Cursor *pC;

  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( pC->pCursor!=0 ){
    int res, oc;
    oc = pOp->opcode;
    pC->nullRow = 0;
    *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
    if( pC->intKey ){
      i64 iKey;
      Integerify(pTos);
      iKey = intToKey(pTos->i);
      if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){
        pC->movetoTarget = iKey;
        pC->deferredMoveto = 1;
        assert( (pTos->flags & MEM_Dyn)==0 );
        pTos--;
        break;
      }
      rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pC->lastRecno = pTos->i;
      pC->recnoIsValid = res==0;
    }else{
      Stringify(pTos, db->enc);
      rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pC->recnoIsValid = 0;
    }
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
    *pC->pIncrKey = 0;
    sqlite3_search_count++;
    if( oc==OP_MoveGe || oc==OP_MoveGt ){
      if( res<0 ){
        rc = sqlite3BtreeNext(pC->pCursor, &res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        pC->recnoIsValid = 0;
      }else{
        res = 0;
      }
    }else{
      assert( oc==OP_MoveLt || oc==OP_MoveLe );
      if( res>=0 ){
        rc = sqlite3BtreePrevious(pC->pCursor, &res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        pC->recnoIsValid = 0;
      }else{
        /* res might be negative because the table is empty.  Check to
        ** see if this is the case.
        */
        res = sqlite3BtreeEof(pC->pCursor);
      }
    }
    if( res ){
      if( pOp->p2>0 ){
        pc = pOp->p2 - 1;
      }else{
        pC->nullRow = 1;
      }
    }
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: Distinct P1 P2 *
**
** Use the top of the stack as a string key.  If a record with that key does
** not exist in the table of cursor P1, then jump to P2.  If the record
** does already exist, then fall thru.  The cursor is left pointing
** at the record if it exists. The key is not popped from the stack.
**
** This operation is similar to NotFound except that this operation
** does not pop the key from the stack.
**
** See also: Found, NotFound, MoveTo, IsUnique, NotExists
*/
/* Opcode: Found P1 P2 *
**
** Use the top of the stack as a string key.  If a record with that key
** does exist in table of P1, then jump to P2.  If the record
** does not exist, then fall thru.  The cursor is left pointing
** to the record if it exists.  The key is popped from the stack.
**
** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
*/
/* Opcode: NotFound P1 P2 *
**
** Use the top of the stack as a string key.  If a record with that key
** does not exist in table of P1, then jump to P2.  If the record
** does exist, then fall thru.  The cursor is left pointing to the
** record if it exists.  The key is popped from the stack.
**
** The difference between this operation and Distinct is that
** Distinct does not pop the key from the stack.
**
** See also: Distinct, Found, MoveTo, NotExists, IsUnique
*/
case OP_Distinct:
case OP_NotFound:
case OP_Found: {
  int i = pOp->p1;
  int alreadyExists = 0;
  Cursor *pC;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
    int res, rx;
    assert( pC->intKey==0 );
    Stringify(pTos, db->enc);
    rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
    alreadyExists = rx==SQLITE_OK && res==0;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
  }
  if( pOp->opcode==OP_Found ){
    if( alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !alreadyExists ) pc = pOp->p2 - 1;
  }
  if( pOp->opcode!=OP_Distinct ){
    Release(pTos);
    pTos--;
  }
  break;
}

/* Opcode: IsUnique P1 P2 *
**
** The top of the stack is an integer record number.  Call this
** record number R.  The next on the stack is an index key created
** using MakeIdxKey.  Call it K.  This instruction pops R from the
** stack but it leaves K unchanged.
**
** P1 is an index.  So it has no data and its key consists of a
** record generated by OP_MakeIdxKey.  This key contains one or more
** fields followed by a ROWID field.
** 
** This instruction asks if there is an entry in P1 where the
** fields matches K but the rowid is different from R.
** If there is no such entry, then there is an immediate
** jump to P2.  If any entry does exist where the index string
** matches K but the record number is not R, then the record
** number for that entry is pushed onto the stack and control
** falls through to the next instruction.
**
** See also: Distinct, NotFound, NotExists, Found
*/
case OP_IsUnique: {
  int i = pOp->p1;
  Mem *pNos = &pTos[-1];
  Cursor *pCx;
  BtCursor *pCrsr;
  i64 R;

  /* Pop the value R off the top of the stack
  */
  assert( pNos>=p->aStack );
  Integerify(pTos);
  R = pTos->i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  assert( i>=0 && i<=p->nCursor );
  pCx = p->apCsr[i];
  assert( pCx!=0 );
  pCrsr = pCx->pCursor;
  if( pCrsr!=0 ){
    int res, rc;
    i64 v;         /* The record number on the P1 entry that matches K */
    char *zKey;    /* The value of K */
    int nKey;      /* Number of bytes in K */
    int len;       /* Number of bytes in K without the rowid at the end */
    int szRowid;   /* Size of the rowid column at the end of zKey */

    /* Make sure K is a string and make zKey point to K
    */
    Stringify(pNos, db->enc);
    zKey = pNos->z;
    nKey = pNos->n;

    szRowid = sqlite3VdbeIdxRowidLen(nKey, zKey);
    len = nKey-szRowid;

    /* Search for an entry in P1 where all but the last four bytes match K.
    ** If there is no such entry, jump immediately to P2.
    */
    assert( pCx->deferredMoveto==0 );
    pCx->cacheValid = 0;
    rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
    if( rc!=SQLITE_OK ) goto abort_due_to_error;
    if( res<0 ){
      rc = sqlite3BtreeNext(pCrsr, &res);
      if( res ){
        pc = pOp->p2 - 1;
        break;
      }
    }
    rc = sqlite3VdbeIdxKeyCompare(pCx, len, zKey, &res); 
    if( rc!=SQLITE_OK ) goto abort_due_to_error;
    if( res>0 ){
      pc = pOp->p2 - 1;
      break;
    }

    /* At this point, pCrsr is pointing to an entry in P1 where all but
    ** the final entry (the rowid) matches K.  Check to see if the
    ** final rowid column is different from R.  If it equals R then jump
    ** immediately to P2.
    */
    rc = sqlite3VdbeIdxRowid(pCrsr, &v);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    if( v==R ){
      pc = pOp->p2 - 1;
      break;
    }

    /* The final varint of the key is different from R.  Push it onto
    ** the stack.  (The record number of an entry that violates a UNIQUE
    ** constraint.)
    */
    pTos++;
    pTos->i = v;
    pTos->flags = MEM_Int;
  }
  break;
}

/* Opcode: NotExists P1 P2 *
**
** Use the top of the stack as a integer key.  If a record with that key
** does not exist in table of P1, then jump to P2.  If the record
** does exist, then fall thru.  The cursor is left pointing to the
** record if it exists.  The integer key is popped from the stack.
**
** The difference between this operation and NotFound is that this
** operation assumes the key is an integer and NotFound assumes it
** is a string.
**
** See also: Distinct, Found, MoveTo, NotFound, IsUnique
*/
case OP_NotExists: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int res;
    u64 iKey;
    assert( pTos->flags & MEM_Int );
    assert( p->apCsr[i]->intKey );
    iKey = intToKey(pTos->i);
    rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
    pC->lastRecno = pTos->i;
    pC->recnoIsValid = res==0;
    pC->nullRow = 0;
    pC->cacheValid = 0;
    if( res!=0 ){
      pc = pOp->p2 - 1;
      pC->recnoIsValid = 0;
    }
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: NewRecno P1 P2 *
**
** Get a new integer record number used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to.  The new record number is pushed 
** onto the stack.
**
** If P2>0 then P2 is a memory cell that holds the largest previously
** generated record number.  No new record numbers are allowed to be less
** than this value.  When this value reaches its maximum, a SQLITE_FULL
** error is generated.  The P2 memory cell is updated with the generated
** record number.  This P2 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
case OP_NewRecno: {
  int i = pOp->p1;
  i64 v = 0;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor==0 ){
    /* The zero initialization above is all that is needed */
  }else{
    /* The next rowid or record number (different terms for the same
    ** thing) is obtained in a two-step algorithm.
    **
    ** First we attempt to find the largest existing rowid and add one
    ** to that.  But if the largest existing rowid is already the maximum
    ** positive integer, we have to fall through to the second
    ** probabilistic algorithm
    **
    ** The second algorithm is to select a rowid at random and see if
    ** it already exists in the table.  If it does not exist, we have
    ** succeeded.  If the random rowid does exist, we select a new one
    ** and try again, up to 1000 times.
    **
    ** For a table with less than 2 billion entries, the probability
    ** of not finding a unused rowid is about 1.0e-300.  This is a 
    ** non-zero probability, but it is still vanishingly small and should
    ** never cause a problem.  You are much, much more likely to have a
    ** hardware failure than for this algorithm to fail.
    **
    ** The analysis in the previous paragraph assumes that you have a good
    ** source of random numbers.  Is a library function like lrand48()
    ** good enough?  Maybe. Maybe not. It's hard to know whether there
    ** might be subtle bugs is some implementations of lrand48() that
    ** could cause problems. To avoid uncertainty, SQLite uses its own 
    ** random number generator based on the RC4 algorithm.
    **
    ** To promote locality of reference for repetitive inserts, the
    ** first few attempts at chosing a random rowid pick values just a little
    ** larger than the previous rowid.  This has been shown experimentally
    ** to double the speed of the COPY operation.
    */
    int res, rx=SQLITE_OK, cnt;
    i64 x;
    cnt = 0;
    if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
          BTREE_INTKEY ){
      rc = SQLITE_CORRUPT;
      goto abort_due_to_error;
    }
    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 );
    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );

#ifdef SQLITE_32BIT_ROWID
#   define MAX_ROWID 0x7fffffff
#else
    /* Some compilers complain about constants of the form 0x7fffffffffffffff.
    ** Others complain about 0x7ffffffffffffffffLL.  The following macro seems
    ** to provide the constant while making all compilers happy.
    */
#   define MAX_ROWID  ( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
#endif

    if( !pC->useRandomRowid ){
      if( pC->nextRowidValid ){
        v = pC->nextRowid;
      }else{
        rx = sqlite3BtreeLast(pC->pCursor, &res);
        if( res ){
          v = 1;
        }else{
          sqlite3BtreeKeySize(pC->pCursor, &v);
          v = keyToInt(v);
          if( v==MAX_ROWID ){
            pC->useRandomRowid = 1;
          }else{
            v++;
          }
        }
      }

#ifndef SQLITE_OMIT_AUTOINCREMENT
      if( pOp->p2 ){
        Mem *pMem;
        assert( pOp->p2>0 && pOp->p2<p->nMem );  /* P2 is a valid memory cell */
        pMem = &p->aMem[pOp->p2];
        Integerify(pMem);
        assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P2) holds an integer */
        if( pMem->i==MAX_ROWID || pC->useRandomRowid ){
          rc = SQLITE_FULL;
          goto abort_due_to_error;
        }
        if( v<pMem->i+1 ){
          v = pMem->i + 1;
        }
        pMem->i = v;
      }
#endif

      if( v<MAX_ROWID ){
        pC->nextRowidValid = 1;
        pC->nextRowid = v+1;
      }else{
        pC->nextRowidValid = 0;
      }
    }
    if( pC->useRandomRowid ){
      assert( pOp->p2==0 );  /* SQLITE_FULL must have occurred prior to this */
      v = db->priorNewRowid;
      cnt = 0;
      do{
        if( v==0 || cnt>2 ){
          sqlite3Randomness(sizeof(v), &v);
          if( cnt<5 ) v &= 0xffffff;
        }else{
          unsigned char r;
          sqlite3Randomness(1, &r);
          v += r + 1;
        }
        if( v==0 ) continue;
        x = intToKey(v);
        rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, &res);
        cnt++;
      }while( cnt<1000 && rx==SQLITE_OK && res==0 );
      db->priorNewRowid = v;
      if( rx==SQLITE_OK && res==0 ){
        rc = SQLITE_FULL;
        goto abort_due_to_error;
      }
    }
    pC->recnoIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
  }
  pTos++;
  pTos->i = v;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: PutIntKey P1 P2 *
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value on the top of the
** stack.  The key is the next value down on the stack.  The key must
** be an integer.  The stack is popped twice by this instruction.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P2 is set,
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it's unmodified).
*/
/* Opcode: PutStrKey P1 * *
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value on the top of the
** stack.  The key is the next value down on the stack.  The key must
** be a string.  The stack is popped twice by this instruction.
**
** P1 may not be a pseudo-table opened using the OpenPseudo opcode.
*/
case OP_PutIntKey:
case OP_PutStrKey: {
  Mem *pNos = &pTos[-1];
  int i = pOp->p1;
  Cursor *pC;
  assert( pNos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
    char *zKey;
    i64 nKey; 
    i64 iKey;
    if( pOp->opcode==OP_PutStrKey ){
      Stringify(pNos, db->enc);
      nKey = pNos->n;
      zKey = pNos->z;
    }else{
      assert( pNos->flags & MEM_Int );

      /* If the table is an INTKEY table, set nKey to the value of
      ** the integer key, and zKey to NULL. Otherwise, set nKey to
      ** sizeof(i64) and point zKey at iKey. iKey contains the integer
      ** key in the on-disk byte order.
      */
      iKey = intToKey(pNos->i);
      if( pC->intKey ){
        nKey = intToKey(pNos->i);
        zKey = 0;
      }else{
        nKey = sizeof(i64);
        zKey = (char*)&iKey;
      }

      if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
      if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
      if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
        pC->nextRowidValid = 0;
      }
    }
    if( pTos->flags & MEM_Null ){
      pTos->z = 0;
      pTos->n = 0;
    }else{
      assert( pTos->flags & (MEM_Blob|MEM_Str) );
    }
#ifndef SQLITE_OMIT_TRIGGER
    if( pC->pseudoTable ){
      /* PutStrKey does not work for pseudo-tables.
      ** The following assert makes sure we are not trying to use
      ** PutStrKey on a pseudo-table
      */
      assert( pOp->opcode==OP_PutIntKey );
      sqliteFree(pC->pData);
      pC->iKey = iKey;
      pC->nData = pTos->n;
      if( pTos->flags & MEM_Dyn ){
        pC->pData = pTos->z;
        pTos->flags = MEM_Null;
      }else{
        pC->pData = sqliteMallocRaw( pC->nData+2 );
        if( !pC->pData ) goto no_mem;
        memcpy(pC->pData, pTos->z, pC->nData);
        pC->pData[pC->nData] = 0;
        pC->pData[pC->nData+1] = 0;
      }
      pC->nullRow = 0;
    }else{
#endif
      rc = sqlite3BtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
#ifndef SQLITE_OMIT_TRIGGER
    }
#endif
    
    pC->recnoIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
  }
  popStack(&pTos, 2);
  break;
}

/* Opcode: Delete P1 P2 *
**
** Delete the record at which the P1 cursor is currently pointing.
**
** The cursor will be left pointing at either the next or the previous
** record in the table. If it is left pointing at the next record, then
** the next Next instruction will be a no-op.  Hence it is OK to delete
** a record from within an Next loop.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).
**
** If P1 is a pseudo-table, then this instruction is a no-op.
*/
case OP_Delete: {
  int i = pOp->p1;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( pC->pCursor!=0 ){
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    rc = sqlite3BtreeDelete(pC->pCursor);
    pC->nextRowidValid = 0;
    pC->cacheValid = 0;
  }
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}

/* Opcode: ResetCount P1 * *
**
** This opcode resets the VMs internal change counter to 0. If P1 is true,
** then the value of the change counter is copied to the database handle
** change counter (returned by subsequent calls to sqlite3_changes())
** before it is reset. This is used by trigger programs.
*/
case OP_ResetCount: {
  if( pOp->p1 ){
    sqlite3VdbeSetChanges(db, p->nChange);
  }
  p->nChange = 0;
  break;
}

/* Opcode: KeyAsData P1 P2 *
**
** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
** off (if P2==0).  In key-as-data mode, the OP_Column opcode pulls
** data off of the key rather than the data.  This is used for
** processing compound selects.
*/
case OP_KeyAsData: {
  int i = pOp->p1;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  pC->keyAsData = pOp->p2;
  break;
}

/* Opcode: RowData P1 * *
**
** Push onto the stack the complete row data for cursor P1.
** There is no interpretation of the data.  It is just copied
** onto the stack exactly as it is found in the database file.
**
** If the cursor is not pointing to a valid row, a NULL is pushed
** onto the stack.
*/
/* Opcode: RowKey P1 * *
**
** Push onto the stack the complete row key for cursor P1.
** There is no interpretation of the key.  It is just copied
** onto the stack exactly as it is found in the database file.
**
** If the cursor is not pointing to a valid row, a NULL is pushed
** onto the stack.
*/
case OP_RowKey:
case OP_RowData: {
  int i = pOp->p1;
  Cursor *pC;
  u32 n;

  pTos++;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( pC->nullRow ){
    pTos->flags = MEM_Null;
  }else if( pC->pCursor!=0 ){
    BtCursor *pCrsr = pC->pCursor;
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->nullRow ){
      pTos->flags = MEM_Null;
      break;
    }else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
      i64 n64;
      assert( !pC->intKey );
      sqlite3BtreeKeySize(pCrsr, &n64);
      n = n64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &n);
    }
    pTos->n = n;
    if( n<=NBFS ){
      pTos->flags = MEM_Blob | MEM_Short;
      pTos->z = pTos->zShort;
    }else{
      char *z = sqliteMallocRaw( n );
      if( z==0 ) goto no_mem;
      pTos->flags = MEM_Blob | MEM_Dyn;
      pTos->xDel = 0;
      pTos->z = z;
    }
    if( pC->keyAsData || pOp->opcode==OP_RowKey ){
      sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
    }else{
      sqlite3BtreeData(pCrsr, 0, n, pTos->z);
    }
#ifndef SQLITE_OMIT_TRIGGER
  }else if( pC->pseudoTable ){
    pTos->n = pC->nData;
    pTos->z = pC->pData;
    pTos->flags = MEM_Blob|MEM_Ephem;
#endif
  }else{
    pTos->flags = MEM_Null;
  }
  break;
}

/* Opcode: Recno P1 * *
**
** Push onto the stack an integer which is the first 4 bytes of the
** the key to the current entry in a sequential scan of the database
** file P1.  The sequential scan should have been started using the 
** Next opcode.
*/
case OP_Recno: {
  int i = pOp->p1;
  Cursor *pC;
  i64 v;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  pTos++;
  if( pC->recnoIsValid ){
    v = pC->lastRecno;
  }else if( pC->pseudoTable ){
    v = keyToInt(pC->iKey);
  }else if( pC->nullRow || pC->pCursor==0 ){
    pTos->flags = MEM_Null;
    break;
  }else{
    assert( pC->pCursor!=0 );
    sqlite3BtreeKeySize(pC->pCursor, &v);
    v = keyToInt(v);
  }
  pTos->i = v;
  pTos->flags = MEM_Int;
  break;
}

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/* Opcode: FullKey P1 * *
**
** Extract the complete key from the record that cursor P1 is currently
** pointing to and push the key onto the stack as a string.
**
** Compare this opcode to Recno.  The Recno opcode extracts the first
** 4 bytes of the key and pushes those bytes onto the stack as an
** integer.  This instruction pushes the entire key as a string.
**
** This opcode may not be used on a pseudo-table.
*/
case OP_FullKey: {
  int i = pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( p->apCsr[i]->keyAsData );
  assert( !p->apCsr[i]->pseudoTable );
  pTos++;
  pTos->flags = MEM_Null;
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    i64 amt;
    char *z;

    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    assert( pC->intKey==0 );
    sqlite3BtreeKeySize(pCrsr, &amt);
    if( amt<=0 ){
      rc = SQLITE_CORRUPT;
      goto abort_due_to_error;
    }
    if( amt>NBFS ){
      z = sqliteMallocRaw( amt );
      if( z==0 ) goto no_mem;
      pTos->flags = MEM_Blob | MEM_Dyn;
      pTos->xDel = 0;
    }else{
      z = pTos->zShort;
      pTos->flags = MEM_Blob | MEM_Short;
    }
    sqlite3BtreeKey(pCrsr, 0, amt, z);
    pTos->z = z;
    pTos->n = amt;
  }
  break;
}
#endif

/* Opcode: NullRow P1 * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always push 
** a NULL onto the stack.
*/
case OP_NullRow: {
  int i = pOp->p1;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  pC->nullRow = 1;
  pC->recnoIsValid = 0;
  break;
}

/* Opcode: Last P1 P2 *
**
** The next use of the Recno or Column or Next instruction for P1 
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    int res;
    rc = sqlite3BtreeLast(pCrsr, &res);
    pC->nullRow = res;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
    if( res && pOp->p2>0 ){
      pc = pOp->p2 - 1;
    }
  }else{
    pC->nullRow = 0;
  }
  break;
}

/* Opcode: Rewind P1 P2 *
**
** The next use of the Recno or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  int res;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    rc = sqlite3BtreeFirst(pCrsr, &res);
    pC->atFirst = res==0;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
  }else{
    res = 1;
  }
  pC->nullRow = res;
  if( res && pOp->p2>0 ){
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Next P1 P2 *
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index.  If there are no more key/value pairs then fall through
** to the following instruction.  But if the cursor advance was successful,
** jump immediately to P2.
**
** See also: Prev
*/
/* Opcode: Prev P1 P2 *
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index.  If there is no previous key/value pairs then fall through
** to the following instruction.  But if the cursor backup was successful,
** jump immediately to P2.
*/
case OP_Prev:
case OP_Next: {
  Cursor *pC;
  BtCursor *pCrsr;

  CHECK_FOR_INTERRUPT;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    int res;
    if( pC->nullRow ){
      res = 1;
    }else{
      assert( pC->deferredMoveto==0 );
      rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
                                  sqlite3BtreePrevious(pCrsr, &res);
      pC->nullRow = res;
      pC->cacheValid = 0;
    }
    if( res==0 ){
      pc = pOp->p2 - 1;
      sqlite3_search_count++;
    }
  }else{
    pC->nullRow = 1;
  }
  pC->recnoIsValid = 0;
  break;
}

/* Opcode: IdxPut P1 P2 P3
**
** The top of the stack holds a SQL index key made using the
** MakeIdxKey instruction.  This opcode writes that key into the
** index P1.  Data for the entry is nil.
**
** If P2==1, then the key must be unique.  If the key is not unique,
** the program aborts with a SQLITE_CONSTRAINT error and the database
** is rolled back.  If P3 is not null, then it becomes part of the
** error message returned with the SQLITE_CONSTRAINT.
*/
case OP_IdxPut: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos->flags & MEM_Blob );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int nKey = pTos->n;
    const char *zKey = pTos->z;
    if( pOp->p2 ){
      int res;
      int len;
   
      /* 'len' is the length of the key minus the rowid at the end */
      len = nKey - sqlite3VdbeIdxRowidLen(nKey, zKey);

      rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      while( res!=0 && !sqlite3BtreeEof(pCrsr) ){
        int c;
        if( sqlite3VdbeIdxKeyCompare(pC, len, zKey, &c)==SQLITE_OK && c==0 ){
          rc = SQLITE_CONSTRAINT;
          if( pOp->p3 && pOp->p3[0] ){
            sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
          }
          goto abort_due_to_error;
        }
        if( res<0 ){
          sqlite3BtreeNext(pCrsr, &res);
          res = +1;
        }else{
          break;
        }
      }
    }
    assert( pC->intKey==0 );
    rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
    assert( pC->deferredMoveto==0 );
    pC->cacheValid = 0;
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxDelete P1 * *
**
** The top of the stack is an index key built using the MakeIdxKey opcode.
** This opcode removes that entry from the index.
*/
case OP_IdxDelete: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Blob );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int rx, res;
    rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
    if( rx==SQLITE_OK && res==0 ){
      rc = sqlite3BtreeDelete(pCrsr);
    }
    assert( pC->deferredMoveto==0 );
    pC->cacheValid = 0;
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxRecno P1 * *
**
** Push onto the stack an integer which is the varint located at the
** end of the index key pointed to by cursor P1.  This integer should be
** the record number of the table entry to which this index entry points.
**
** See also: Recno, MakeIdxKey.
*/
case OP_IdxRecno: {
  int i = pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  pTos++;
  pTos->flags = MEM_Null;
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    i64 rowid;

    assert( pC->deferredMoveto==0 );
    assert( pC->intKey==0 );
    if( pC->nullRow ){
      pTos->flags = MEM_Null;
    }else{
      rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pTos->flags = MEM_Int;
      pTos->i = rowid;
    }
  }
  break;
}

/* Opcode: IdxGT P1 P2 *
**
** The top of the stack is an index entry that omits the ROWID.  Compare
** the top of stack against the index that P1 is currently pointing to.
** Ignore the ROWID on the P1 index.
**
** The top of the stack might have fewer columns that P1.
**
** If the P1 index entry is greater than the top of the stack
** then jump to P2.  Otherwise fall through to the next instruction.
** In either case, the stack is popped once.
*/
/* Opcode: IdxGE P1 P2 P3
**
** The top of the stack is an index entry that omits the ROWID.  Compare
** the top of stack against the index that P1 is currently pointing to.
** Ignore the ROWID on the P1 index.
**
** If the P1 index entry is greater than or equal to the top of the stack
** then jump to P2.  Otherwise fall through to the next instruction.
** In either case, the stack is popped once.
**
** If P3 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.  This make the opcode work
** like IdxGT except that if the key from the stack is a prefix of
** the key in the cursor, the result is false whereas it would be
** true with IdxGT.
*/
/* Opcode: IdxLT P1 P2 P3
**
** The top of the stack is an index entry that omits the ROWID.  Compare
** the top of stack against the index that P1 is currently pointing to.
** Ignore the ROWID on the P1 index.
**
** If the P1 index entry is less than  the top of the stack
** then jump to P2.  Otherwise fall through to the next instruction.
** In either case, the stack is popped once.
**
** If P3 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.  This makes the opcode work
** like IdxLE.
*/
case OP_IdxLT:
case OP_IdxGT:
case OP_IdxGE: {
  int i= pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos>=p->aStack );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int res, rc;
 
    assert( pTos->flags & MEM_Blob );  /* Created using OP_Make*Key */
    Stringify(pTos, db->enc);
    assert( pC->deferredMoveto==0 );
    *pC->pIncrKey = pOp->p3!=0;
    assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT );
    rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, pTos->z, &res);
    *pC->pIncrKey = 0;
    if( rc!=SQLITE_OK ){
      break;
    }
    if( pOp->opcode==OP_IdxLT ){
      res = -res;
    }else if( pOp->opcode==OP_IdxGE ){
      res++;
    }
    if( res>0 ){
      pc = pOp->p2 - 1 ;
    }
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxIsNull P1 P2 *
**
** The top of the stack contains an index entry such as might be generated
** by the MakeIdxKey opcode.  This routine looks at the first P1 fields of
** that key.  If any of the first P1 fields are NULL, then a jump is made
** to address P2.  Otherwise we fall straight through.
**
** The index entry is always popped from the stack.
*/
case OP_IdxIsNull: {
  int i = pOp->p1;
  int k, n;
  const char *z;
  u32 serial_type;

  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Blob );
  z = pTos->z;
  n = pTos->n;
  k = sqlite3GetVarint32(z, &serial_type);
  for(; k<n && i>0; i--){
    k += sqlite3GetVarint32(&z[k], &serial_type);
    if( serial_type==0 ){   /* Serial type 0 is a NULL */
      pc = pOp->p2-1;
      break;
    }
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: Destroy P1 P2 *
**
** Delete an entire database table or index whose root page in the database
** file is given by P1.
**
** The table being destroyed is in the main database file if P2==0.  If
** P2==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
** If AUTOVACUUM is enabled then it is possible that another root page
** might be moved into the newly deleted root page in order to keep all
** root pages contiguous at the beginning of the database.  The former
** value of the root page that moved - its value before the move occurred -
** is pushed onto the stack.  If no page movement was required (because
** the table being dropped was already the last one in the database) then
** a zero is pushed onto the stack.  If AUTOVACUUM is disabled
** then a zero is pushed onto the stack.
**
** See also: Clear
*/
case OP_Destroy: {
  int iMoved;
  if( db->activeVdbeCnt>1 ){
    rc = SQLITE_LOCKED;
  }else{
    assert( db->activeVdbeCnt==1 );
    rc = sqlite3BtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1, &iMoved);
    pTos++;
    pTos->flags = MEM_Int;
    pTos->i = iMoved;
  #ifndef SQLITE_OMIT_AUTOVACUUM
    if( rc==SQLITE_OK && iMoved!=0 ){
      sqlite3RootPageMoved(&db->aDb[pOp->p2], iMoved, pOp->p1);
    }
  #endif
  }
  break;
}

/* Opcode: Clear P1 P2 *
**
** Delete all contents of the database table or index whose root page
** in the database file is given by P1.  But, unlike Destroy, do not
** remove the table or index from the database file.
**
** The table being clear is in the main database file if P2==0.  If
** P2==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
** See also: Destroy
*/
case OP_Clear: {
  rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
  break;
}

/* Opcode: CreateTable P1 * *
**
** Allocate a new table in the main database file if P2==0 or in the
** auxiliary database file if P2==1.  Push the page number
** for the root page of the new table onto the stack.
**
** The difference between a table and an index is this:  A table must
** have a 4-byte integer key and can have arbitrary data.  An index
** has an arbitrary key but no data.
**
** See also: CreateIndex
*/
/* Opcode: CreateIndex P1 * *
**
** Allocate a new index in the main database file if P2==0 or in the
** auxiliary database file if P2==1.  Push the page number of the
** root page of the new index onto the stack.
**
** See documentation on OP_CreateTable for additional information.
*/
case OP_CreateIndex:
case OP_CreateTable: {
  int pgno;
  int flags;
  Db *pDb;
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pDb = &db->aDb[pOp->p1];
  assert( pDb->pBt!=0 );
  if( pOp->opcode==OP_CreateTable ){
    /* flags = BTREE_INTKEY; */
    flags = BTREE_LEAFDATA|BTREE_INTKEY;
  }else{
    flags = BTREE_ZERODATA;
  }
  rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
  pTos++;
  if( rc==SQLITE_OK ){
    pTos->i = pgno;
    pTos->flags = MEM_Int;
  }else{
    pTos->flags = MEM_Null;
  }
  break;
}

/* Opcode: ParseSchema P1 * P3
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
** that match the WHERE clause P3.
**
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine.  It is thus a reentrant opcode.
*/
case OP_ParseSchema: {
  char *zSql;
  int iDb = pOp->p1;
  const char *zMaster;
  InitData initData;

  assert( iDb>=0 && iDb<db->nDb );
  if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break;
  zMaster = iDb==1 ? TEMP_MASTER_NAME : MASTER_NAME;
  initData.db = db;
  initData.pzErrMsg = &p->zErrMsg;
  zSql = sqlite3MPrintf(
     "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
     pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
  if( zSql==0 ) goto no_mem;
  sqlite3SafetyOff(db);
  assert( db->init.busy==0 );
  db->init.busy = 1;
  rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
  db->init.busy = 0;
  sqlite3SafetyOn(db);
  sqliteFree(zSql);
  break;  
}

/* Opcode: DropTable P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the table named P3 in database P1.  This is called after a table
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTable: {
  sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p3);
  break;
}

/* Opcode: DropIndex P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the index named P3 in database P1.  This is called after an index
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropIndex: {
  sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p3);
  break;
}

/* Opcode: DropTrigger P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the trigger named P3 in database P1.  This is called after a trigger
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTrigger: {
  sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p3);
  break;
}


#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/* Opcode: IntegrityCk * P2 *
**
** Do an analysis of the currently open database.  Push onto the
** stack the text of an error message describing any problems.
** If there are no errors, push a "ok" onto the stack.
**
** The root page numbers of all tables in the database are integer
** values on the stack.  This opcode pulls as many integers as it
** can off of the stack and uses those numbers as the root pages.
**
** If P2 is not zero, the check is done on the auxiliary database
** file, not the main database file.
**
** This opcode is used for testing purposes only.
*/
case OP_IntegrityCk: {
  int nRoot;
  int *aRoot;
  int j;
  char *z;

  for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){
    if( (pTos[-nRoot].flags & MEM_Int)==0 ) break;
  }
  assert( nRoot>0 );
  aRoot = sqliteMallocRaw( sizeof(int*)*(nRoot+1) );
  if( aRoot==0 ) goto no_mem;
  for(j=0; j<nRoot; j++){
    Mem *pMem = &pTos[-j];
    aRoot[j] = pMem->i;
  }
  aRoot[j] = 0;
  popStack(&pTos, nRoot);
  pTos++;
  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
  if( z==0 || z[0]==0 ){
    if( z ) sqliteFree(z);
    pTos->z = "ok";
    pTos->n = 2;
    pTos->flags = MEM_Str | MEM_Static | MEM_Term;
  }else{
    pTos->z = z;
    pTos->n = strlen(z);
    pTos->flags = MEM_Str | MEM_Dyn | MEM_Term;
    pTos->xDel = 0;
  }
  pTos->enc = SQLITE_UTF8;
  sqlite3VdbeChangeEncoding(pTos, db->enc);
  sqliteFree(aRoot);
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/* Opcode: ListWrite * * *
**
** Write the integer on the top of the stack
** into the temporary storage list.
*/
case OP_ListWrite: {
  Keylist *pKeylist;
  assert( pTos>=p->aStack );
  pKeylist = p->pList;
  if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
    pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
    if( pKeylist==0 ) goto no_mem;
    pKeylist->nKey = 1000;
    pKeylist->nRead = 0;
    pKeylist->nUsed = 0;
    pKeylist->pNext = p->pList;
    p->pList = pKeylist;
  }
  Integerify(pTos);
  pKeylist->aKey[pKeylist->nUsed++] = pTos->i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  break;
}

/* Opcode: ListRewind * * *
**
** Rewind the temporary buffer back to the beginning.
*/
case OP_ListRewind: {
  /* What this opcode codes, really, is reverse the order of the
  ** linked list of Keylist structures so that they are read out
  ** in the same order that they were read in. */
  Keylist *pRev, *pTop;
  pRev = 0;
  while( p->pList ){
    pTop = p->pList;
    p->pList = pTop->pNext;
    pTop->pNext = pRev;
    pRev = pTop;
  }
  p->pList = pRev;
  break;
}

/* Opcode: ListRead * P2 *
**
** Attempt to read an integer from the temporary storage buffer
** and push it onto the stack.  If the storage buffer is empty, 
** push nothing but instead jump to P2.
*/
case OP_ListRead: {
  Keylist *pKeylist;
  CHECK_FOR_INTERRUPT;
  pKeylist = p->pList;
  if( pKeylist!=0 ){
    assert( pKeylist->nRead>=0 );
    assert( pKeylist->nRead<pKeylist->nUsed );
    assert( pKeylist->nRead<pKeylist->nKey );
    pTos++;
    pTos->i = pKeylist->aKey[pKeylist->nRead++];
    pTos->flags = MEM_Int;
    if( pKeylist->nRead>=pKeylist->nUsed ){
      p->pList = pKeylist->pNext;
      sqliteFree(pKeylist);
    }
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: ListReset * * *
**
** Reset the temporary storage buffer so that it holds nothing.
*/
case OP_ListReset: {
  if( p->pList ){
    sqlite3VdbeKeylistFree(p->pList);
    p->pList = 0;
  }
  break;
}

#ifndef SQLITE_OMIT_SUBQUERY
/* Opcode: AggContextPush * * * 
**
** Save the state of the current aggregator. It is restored an 
** AggContextPop opcode.
** 
*/
case OP_AggContextPush: {
  p->pAgg++;
  assert( p->pAgg<&p->apAgg[p->nAgg] );
  break;
}

/* Opcode: AggContextPop * * *
**
** Restore the aggregator to the state it was in when AggContextPush
** was last called. Any data in the current aggregator is deleted.
*/
case OP_AggContextPop: {
  p->pAgg--;
  assert( p->pAgg>=p->apAgg );
  break;
}
#endif

#ifndef SQLITE_OMIT_TRIGGER
/* Opcode: ContextPush * * * 
**
** Save the current Vdbe context such that it can be restored by a ContextPop
** opcode. The context stores the last insert row id, the last statement change
** count, and the current statement change count.
*/
case OP_ContextPush: {
  int i = p->contextStackTop++;
  Context *pContext;

  assert( i>=0 );
  /* FIX ME: This should be allocated as part of the vdbe at compile-time */
  if( i>=p->contextStackDepth ){
    p->contextStackDepth = i+1;
    p->contextStack = sqliteRealloc(p->contextStack, sizeof(Context)*(i+1));
    if( p->contextStack==0 ) goto no_mem;
  }
  pContext = &p->contextStack[i];
  pContext->lastRowid = db->lastRowid;
  pContext->nChange = p->nChange;
  pContext->pList = p->pList;
  p->pList = 0;
  break;
}

/* Opcode: ContextPop * * * 
**
** Restore the Vdbe context to the state it was in when contextPush was last
** executed. The context stores the last insert row id, the last statement
** change count, and the current statement change count.
*/
case OP_ContextPop: {
  Context *pContext = &p->contextStack[--p->contextStackTop];
  assert( p->contextStackTop>=0 );
  db->lastRowid = pContext->lastRowid;
  p->nChange = pContext->nChange;
  sqlite3VdbeKeylistFree(p->pList);
  p->pList = pContext->pList;
  break;
}
#endif /* #ifndef SQLITE_OMIT_TRIGGER */

/* Opcode: SortPut * * *
**
** The TOS is the key and the NOS is the data.  Pop both from the stack
** and put them on the sorter.  The key and data should have been
** made using the MakeRecord opcode.
*/
case OP_SortPut: {
  Mem *pNos = &pTos[-1];
  Sorter *pSorter;
  assert( pNos>=p->aStack );
  if( Dynamicify(pTos, db->enc) ) goto no_mem;
  pSorter = sqliteMallocRaw( sizeof(Sorter) );
  if( pSorter==0 ) goto no_mem;
  pSorter->pNext = p->pSort;
  p->pSort = pSorter;
  assert( pTos->flags & MEM_Dyn );
  pSorter->nKey = pTos->n;
  pSorter->zKey = pTos->z;
  pSorter->data.flags = MEM_Null;
  rc = sqlite3VdbeMemMove(&pSorter->data, pNos);
  pTos -= 2;
  break;
}

/* Opcode: Sort * * P3
**
** Sort all elements on the sorter.  The algorithm is a
** mergesort.  The P3 argument is a pointer to a KeyInfo structure
** that describes the keys to be sorted.
*/
case OP_Sort: {
  int i;
  KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
  Sorter *pElem;
  Sorter *apSorter[NSORT];
  sqlite3_sort_count++;
  pKeyInfo->enc = p->db->enc;
  for(i=0; i<NSORT; i++){
    apSorter[i] = 0;
  }
  while( p->pSort ){
    pElem = p->pSort;
    p->pSort = pElem->pNext;
    pElem->pNext = 0;
    for(i=0; i<NSORT-1; i++){
      if( apSorter[i]==0 ){
        apSorter[i] = pElem;
        break;
      }else{
        pElem = Merge(apSorter[i], pElem, pKeyInfo);
        apSorter[i] = 0;
      }
    }
    if( i>=NSORT-1 ){
      apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem, pKeyInfo);
    }
  }
  pElem = 0;
  for(i=0; i<NSORT; i++){
    pElem = Merge(apSorter[i], pElem, pKeyInfo);
  }
  p->pSort = pElem;
  break;
}

/* Opcode: SortNext * P2 *
**
** Push the data for the topmost element in the sorter onto the
** stack, then remove the element from the sorter.  If the sorter
** is empty, push nothing on the stack and instead jump immediately 
** to instruction P2.
*/
case OP_SortNext: {
  Sorter *pSorter = p->pSort;
  CHECK_FOR_INTERRUPT;
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    pTos++;
    pTos->flags = MEM_Null;
    rc = sqlite3VdbeMemMove(pTos, &pSorter->data);
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: SortReset * * *
**
** Remove any elements that remain on the sorter.
*/
case OP_SortReset: {
  sqlite3VdbeSorterReset(p);
  break;
}

/* Opcode: MemStore P1 P2 *
**
** Write the top of the stack into memory location P1.
** P1 should be a small integer since space is allocated
** for all memory locations between 0 and P1 inclusive.
**
** After the data is stored in the memory location, the
** stack is popped once if P2 is 1.  If P2 is zero, then
** the original data remains on the stack.
*/
case OP_MemStore: {
  assert( pTos>=p->aStack );
  assert( pOp->p1>=0 && pOp->p1<p->nMem );
  rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos);
  pTos--;

  /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will
  ** restore the top of the stack to its original value.
  */
  if( pOp->p2 ){
    break;
  }
}
/* Opcode: MemLoad P1 * *
**
** Push a copy of the value in memory location P1 onto the stack.
**
** If the value is a string, then the value pushed is a pointer to
** the string that is stored in the memory location.  If the memory
** location is subsequently changed (using OP_MemStore) then the
** value pushed onto the stack will change too.
*/
case OP_MemLoad: {
  int i = pOp->p1;
  assert( i>=0 && i<p->nMem );
  pTos++;
  sqlite3VdbeMemShallowCopy(pTos, &p->aMem[i], MEM_Ephem);
  break;
}

#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Opcode: MemMax P1 * *
**
** Set the value of memory cell P1 to the maximum of its current value
** and the value on the top of the stack.  The stack is unchanged.
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemMax: {
  int i = pOp->p1;
  Mem *pMem;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  Integerify(pMem);
  Integerify(pTos);
  if( pMem->i<pTos->i){
    pMem->i = pTos->i;
  }
  break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */

/* Opcode: MemIncr P1 P2 *
**
** Increment the integer valued memory cell P1 by 1.  If P2 is not zero
** and the result after the increment is exactly 1, then jump
** to P2.
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemIncr: {
  int i = pOp->p1;
  Mem *pMem;
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  pMem->i++;
  if( pOp->p2>0 && pMem->i==1 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfMemPos P1 P2 *
**
** If the value of memory cell P1 is 1 or greater, jump to P2. This
** opcode assumes that memory cell P1 holds an integer value.
*/
case OP_IfMemPos: {
  int i = pOp->p1;
  Mem *pMem;
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->i>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: AggReset P1 P2 P3
**
** Reset the current aggregator context so that it no longer contains any 
** data. Future aggregator elements will contain P2 values each and be sorted
** using the KeyInfo structure pointed to by P3.
**
** If P1 is non-zero, then only a single aggregator row is available (i.e.
** there is no GROUP BY expression). In this case it is illegal to invoke
** OP_AggFocus.
*/
case OP_AggReset: {
  assert( !pOp->p3 || pOp->p3type==P3_KEYINFO );
  if( pOp->p1 ){
    rc = sqlite3VdbeAggReset(0, p->pAgg, (KeyInfo *)pOp->p3);
    p->pAgg->nMem = pOp->p2;    /* Agg.nMem is used by AggInsert() */
    rc = AggInsert(p->pAgg, 0, 0);
  }else{
    rc = sqlite3VdbeAggReset(db, p->pAgg, (KeyInfo *)pOp->p3);
    p->pAgg->nMem = pOp->p2;
  }
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  p->pAgg->apFunc = sqliteMalloc( p->pAgg->nMem*sizeof(p->pAgg->apFunc[0]) );
  if( p->pAgg->apFunc==0 ) goto no_mem;
  break;
}

/* Opcode: AggInit * P2 P3
**
** Initialize the function parameters for an aggregate function.
** The aggregate will operate out of aggregate column P2.
** P3 is a pointer to the FuncDef structure for the function.
*/
case OP_AggInit: {
  int i = pOp->p2;
  assert( i>=0 && i<p->pAgg->nMem );
  p->pAgg->apFunc[i] = (FuncDef*)pOp->p3;
  break;
}

/* Opcode: AggFunc * P2 P3
**
** Execute the step function for an aggregate.  The
** function has P2 arguments.  P3 is a pointer to the FuncDef
** structure that specifies the function.
**
** The top of the stack must be an integer which is the index of
** the aggregate column that corresponds to this aggregate function.
** Ideally, this index would be another parameter, but there are
** no free parameters left.  The integer is popped from the stack.
*/
case OP_AggFunc: {
  int n = pOp->p2;
  int i;
  Mem *pMem, *pRec;
  sqlite3_context ctx;
  sqlite3_value **apVal;

  assert( n>=0 );
  assert( pTos->flags==MEM_Int );
  pRec = &pTos[-n];
  assert( pRec>=p->aStack );

  apVal = p->apArg;
  assert( apVal || n==0 );

  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    storeTypeInfo(pRec, db->enc);
  }
  i = pTos->i;
  assert( i>=0 && i<p->pAgg->nMem );
  ctx.pFunc = (FuncDef*)pOp->p3;
  pMem = &p->pAgg->pCurrent->aMem[i];
  ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
  ctx.pAgg = pMem->z;
  ctx.cnt = ++pMem->i;
  ctx.isError = 0;
  ctx.pColl = 0;
  if( ctx.pFunc->needCollSeq ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  (ctx.pFunc->xStep)(&ctx, n, apVal);
  pMem->z = ctx.pAgg;
  pMem->flags = MEM_AggCtx;
  popStack(&pTos, n+1);
  if( ctx.isError ){
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: AggFocus * P2 *
**
** Pop the top of the stack and use that as an aggregator key.  If
** an aggregator with that same key already exists, then make the
** aggregator the current aggregator and jump to P2.  If no aggregator
** with the given key exists, create one and make it current but
** do not jump.
**
** The order of aggregator opcodes is important.  The order is:
** AggReset AggFocus AggNext.  In other words, you must execute
** AggReset first, then zero or more AggFocus operations, then
** zero or more AggNext operations.  You must not execute an AggFocus
** in between an AggNext and an AggReset.
*/
case OP_AggFocus: {
  char *zKey;
  int nKey;
  int res;
  assert( pTos>=p->aStack );
  Stringify(pTos, db->enc);
  zKey = pTos->z;
  nKey = pTos->n;
  assert( p->pAgg->pBtree );
  assert( p->pAgg->pCsr );
  rc = sqlite3BtreeMoveto(p->pAgg->pCsr, zKey, nKey, &res);
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  if( res==0 ){
    rc = sqlite3BtreeData(p->pAgg->pCsr, 0, sizeof(AggElem*),
        (char *)&p->pAgg->pCurrent);
    pc = pOp->p2 - 1;
  }else{
    rc = AggInsert(p->pAgg, zKey, nKey);
  }
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  Release(pTos);
  pTos--;
  break; 
}

/* Opcode: AggSet * P2 *
**
** Move the top of the stack into the P2-th field of the current
** aggregate.  String values are duplicated into new memory.
*/
case OP_AggSet: {
  AggElem *pFocus;
  int i = pOp->p2;
  pFocus = p->pAgg->pCurrent;
  assert( pTos>=p->aStack );
  if( pFocus==0 ) goto no_mem;
  assert( i>=0 && i<p->pAgg->nMem );
  rc = sqlite3VdbeMemMove(&pFocus->aMem[i], pTos);
  pTos--;
  break;
}

/* Opcode: AggGet P1 P2 *
**
** Push a new entry onto the stack which is a copy of the P2-th field
** of the current aggregate.  Strings are not duplicated so
** string values will be ephemeral.
**
** If P1 is zero, then the value is pulled out of the current aggregate
** in the current aggregate context. If P1 is greater than zero, then
** the value is taken from the P1th outer aggregate context. (i.e. if
** P1==1 then read from the aggregate context that will be restored
** by the next OP_AggContextPop opcode).
*/
case OP_AggGet: {
  AggElem *pFocus;
  int i = pOp->p2;
  Agg *pAgg = &p->pAgg[-pOp->p1];
  assert( pAgg>=p->apAgg );
  pFocus = pAgg->pCurrent;
  if( pFocus==0 ){
    int res;
    if( sqlite3_malloc_failed ) goto no_mem;
    rc = sqlite3BtreeFirst(pAgg->pCsr, &res);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    if( res!=0 ){
      rc = AggInsert(pAgg, "", 1);
      pFocus = pAgg->pCurrent;
    }else{
      rc = sqlite3BtreeData(pAgg->pCsr, 0, 4, (char *)&pFocus);
    }
  }
  assert( i>=0 && i<pAgg->nMem );
  pTos++;
  sqlite3VdbeMemShallowCopy(pTos, &pFocus->aMem[i], MEM_Ephem);
  if( pTos->flags&MEM_Str ){
    sqlite3VdbeChangeEncoding(pTos, db->enc);
  }
  break;
}

/* Opcode: AggNext * P2 *
**
** Make the next aggregate value the current aggregate.  The prior
** aggregate is deleted.  If all aggregate values have been consumed,
** jump to P2.
**
** The order of aggregator opcodes is important.  The order is:
** AggReset AggFocus AggNext.  In other words, you must execute
** AggReset first, then zero or more AggFocus operations, then
** zero or more AggNext operations.  You must not execute an AggFocus
** in between an AggNext and an AggReset.
*/
case OP_AggNext: {
  int res;
  assert( rc==SQLITE_OK );
  CHECK_FOR_INTERRUPT;
  if( p->pAgg->searching==0 ){
    p->pAgg->searching = 1;
    if( p->pAgg->pCsr ){
      rc = sqlite3BtreeFirst(p->pAgg->pCsr, &res);
    }else{
      res = 0;
    }
  }else{
    if( p->pAgg->pCsr ){
      rc = sqlite3BtreeNext(p->pAgg->pCsr, &res);
    }else{
      res = 1;
    }
  }
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
  if( res!=0 ){
    pc = pOp->p2 - 1;
  }else{
    int i;
    sqlite3_context ctx;
    Mem *aMem;

    if( p->pAgg->pCsr ){
      rc = sqlite3BtreeData(p->pAgg->pCsr, 0, sizeof(AggElem*),
          (char *)&p->pAgg->pCurrent);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
    }
    aMem = p->pAgg->pCurrent->aMem;
    for(i=0; i<p->pAgg->nMem; i++){
      FuncDef *pFunc = p->pAgg->apFunc[i];
      Mem *pMem = &aMem[i];
      if( pFunc==0 || pFunc->xFinalize==0 ) continue;
      ctx.s.flags = MEM_Null;
      ctx.s.z = pMem->zShort;
      ctx.pAgg = (void*)pMem->z;
      ctx.cnt = pMem->i;
      ctx.pFunc = pFunc;
      pFunc->xFinalize(&ctx);
      pMem->z = ctx.pAgg;
      if( pMem->z && pMem->z!=pMem->zShort ){
        sqliteFree( pMem->z );
      }
      *pMem = ctx.s;
      if( pMem->flags & MEM_Short ){
        pMem->z = pMem->zShort;
      }
    }
  }
  break;
}

/* Opcode: Vacuum * * *
**
** Vacuum the entire database.  This opcode will cause other virtual
** machines to be created and run.  It may not be called from within
** a transaction.
*/
case OP_Vacuum: {
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; 
  rc = sqlite3RunVacuum(&p->zErrMsg, db);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  break;
}

/* Opcode: Expire P1 * *
**
** Cause precompiled statements to become expired. An expired statement
** fails with an error code of SQLITE_SCHEMA if it is ever executed 
** (via sqlite3_step()).
** 
** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
** then only the currently executing statement is affected. 
*/
case OP_Expire: {
  if( !pOp->p1 ){
    sqlite3ExpirePreparedStatements(db);
  }else{
    p->expired = 1;
  }
  break;
}


/* An other opcode is illegal...
*/
default: {
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);
  sqlite3SetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
  rc = SQLITE_INTERNAL;
  break;
}

/*****************************************************************************
** The cases of the switch statement above this line should all be indented
** by 6 spaces.  But the left-most 6 spaces have been removed to improve the
** readability.  From this point on down, the normal indentation rules are
** restored.
*****************************************************************************/
    }

#ifdef VDBE_PROFILE
    {
      long long elapse = hwtime() - start;
      pOp->cycles += elapse;
      pOp->cnt++;
#if 0
        fprintf(stdout, "%10lld ", elapse);
        sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
#endif
    }
#endif

    /* The following code adds nothing to the actual functionality
    ** of the program.  It is only here for testing and debugging.
    ** On the other hand, it does burn CPU cycles every time through
    ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
    */
#ifndef NDEBUG
    /* Sanity checking on the top element of the stack */
    if( pTos>=p->aStack ){
      sqlite3VdbeMemSanity(pTos, db->enc);
    }
    if( pc<-1 || pc>=p->nOp ){
      sqlite3SetString(&p->zErrMsg, "jump destination out of range", (char*)0);
      rc = SQLITE_INTERNAL;
    }
#ifdef SQLITE_DEBUG
    /* Code for tracing the vdbe stack. */
    if( p->trace && pTos>=p->aStack ){
      int i;
      fprintf(p->trace, "Stack:");
      for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
        if( pTos[i].flags & MEM_Null ){
          fprintf(p->trace, " NULL");
        }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
          fprintf(p->trace, " si:%lld", pTos[i].i);
        }else if( pTos[i].flags & MEM_Int ){
          fprintf(p->trace, " i:%lld", pTos[i].i);
        }else if( pTos[i].flags & MEM_Real ){
          fprintf(p->trace, " r:%g", pTos[i].r);
        }else{
          char zBuf[100];
          sqlite3VdbeMemPrettyPrint(&pTos[i], zBuf, 100);
          fprintf(p->trace, " ");
          fprintf(p->trace, "%s", zBuf);
        }
      }
      if( rc!=0 ) fprintf(p->trace," rc=%d",rc);
      fprintf(p->trace,"\n");
    }
#endif  /* SQLITE_DEBUG */
#endif  /* NDEBUG */
  }  /* The end of the for(;;) loop the loops through opcodes */

  /* If we reach this point, it means that execution is finished.
  */
vdbe_halt:
  if( rc ){
    p->rc = rc;
    rc = SQLITE_ERROR;
  }else{
    rc = SQLITE_DONE;
  }
  sqlite3VdbeHalt(p);
  p->pTos = pTos;
  return rc;

  /* Jump to here if a malloc() fails.  It's hard to get a malloc()
  ** to fail on a modern VM computer, so this code is untested.
  */
no_mem:
  sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
  rc = SQLITE_NOMEM;
  goto vdbe_halt;

  /* Jump to here for an SQLITE_MISUSE error.
  */
abort_due_to_misuse:
  rc = SQLITE_MISUSE;
  /* Fall thru into abort_due_to_error */

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  if( p->zErrMsg==0 ){
    if( sqlite3_malloc_failed ) rc = SQLITE_NOMEM;
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  }
  goto vdbe_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */
abort_due_to_interrupt:
  assert( db->flags & SQLITE_Interrupt );
  db->flags &= ~SQLITE_Interrupt;
  if( db->magic!=SQLITE_MAGIC_BUSY ){
    rc = SQLITE_MISUSE;
  }else{
    rc = SQLITE_INTERRUPT;
  }
  p->rc = rc;
  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  goto vdbe_halt;
}
Added SQLite.Interop/src/vdbe.h.






































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.1 2005/03/01 16:04:38 rmsimpson Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
** in the source file sqliteVdbe.c are allowed to see the insides
** of this structure.
*/
typedef struct Vdbe Vdbe;

/*
** A single instruction of the virtual machine has an opcode
** and as many as three operands.  The instruction is recorded
** as an instance of the following structure:
*/
struct VdbeOp {
  u8 opcode;          /* What operation to perform */
  int p1;             /* First operand */
  int p2;             /* Second parameter (often the jump destination) */
  char *p3;           /* Third parameter */
  int p3type;         /* P3_STATIC, P3_DYNAMIC or P3_POINTER */
#ifdef VDBE_PROFILE
  int cnt;            /* Number of times this instruction was executed */
  long long cycles;   /* Total time spend executing this instruction */
#endif
};
typedef struct VdbeOp VdbeOp;

/*
** A smaller version of VdbeOp used for the VdbeAddOpList() function because
** it takes up less space.
*/
struct VdbeOpList {
  u8 opcode;          /* What operation to perform */
  signed char p1;     /* First operand */
  short int p2;       /* Second parameter (often the jump destination) */
  char *p3;           /* Third parameter */
};
typedef struct VdbeOpList VdbeOpList;

/*
** Allowed values of VdbeOp.p3type
*/
#define P3_NOTUSED    0   /* The P3 parameter is not used */
#define P3_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
#define P3_STATIC   (-2)  /* Pointer to a static string */
#define P3_POINTER  (-3)  /* P3 is a pointer to some structure or object */
#define P3_COLLSEQ  (-4)  /* P3 is a pointer to a CollSeq structure */
#define P3_FUNCDEF  (-5)  /* P3 is a pointer to a FuncDef structure */
#define P3_KEYINFO  (-6)  /* P3 is a pointer to a KeyInfo structure */
#define P3_VDBEFUNC (-7)  /* P3 is a pointer to a VdbeFunc structure */

/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.
*/
#define P3_KEYINFO_HANDOFF (-7)

/*
** The following macro converts a relative address in the p2 field
** of a VdbeOp structure into a negative number so that 
** sqlite3VdbeAddOpList() knows that the address is relative.  Calling
** the macro again restores the address.
*/
#define ADDR(X)  (-1-(X))

/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
** header file that defines a number for each opcode used by the VDBE.
*/
#include "opcodes.h"

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqlite3VdbeCreate(sqlite3*);
void sqlite3VdbeCreateCallback(Vdbe*, int*);
int sqlite3VdbeAddOp(Vdbe*,int,int,int);
int sqlite3VdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
void sqlite3VdbeDequoteP3(Vdbe*, int addr);
int sqlite3VdbeFindOp(Vdbe*, int, int, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
void sqlite3VdbeTrace(Vdbe*,FILE*);
int sqlite3VdbeReset(Vdbe*);
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
void sqlite3VdbeSetNumCols(Vdbe*,int);
int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
void sqlite3VdbeCountChanges(Vdbe*);

#ifndef NDEBUG
  void sqlite3VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X)  sqlite3VdbeComment X
#else
# define VdbeComment(X)
#endif

#endif
Added SQLite.Interop/src/vdbeInt.h.
























































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2003 September 6
**
** 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 is the header file for information that is private to the
** VDBE.  This information used to all be at the top of the single
** source code file "vdbe.c".  When that file became too big (over
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
*/

/*
** intToKey() and keyToInt() used to transform the rowid.  But with
** the latest versions of the design they are no-ops.
*/
#define keyToInt(X)   (X)
#define intToKey(X)   (X)

/*
** The makefile scans the vdbe.c source file and creates the following
** array of string constants which are the names of all VDBE opcodes.  This
** array is defined in a separate source code file named opcode.c which is
** automatically generated by the makefile.
*/
extern char *sqlite3OpcodeNames[];

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
** of the following structure.
*/
typedef struct VdbeOp Op;

/*
** Boolean values
*/
typedef unsigned char Bool;

/*
** A cursor is a pointer into a single BTree within a database file.
** The cursor can seek to a BTree entry with a particular key, or
** loop over all entries of the Btree.  You can also insert new BTree
** entries or retrieve the key or data from the entry that the cursor
** is currently pointing to.
** 
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
**
** If the Cursor.isTriggerRow flag is set it means that this cursor is
** really a single row that represents the NEW or OLD pseudo-table of
** a row trigger.  The data for the row is stored in Cursor.pData and
** the rowid is in Cursor.iKey.
*/
struct Cursor {
  BtCursor *pCursor;    /* The cursor structure of the backend */
  i64 lastRecno;        /* Last recno from a Next or NextIdx operation */
  i64 nextRowid;        /* Next rowid returned by OP_NewRowid */
  Bool zeroed;          /* True if zeroed out and ready for reuse */
  Bool recnoIsValid;    /* True if lastRecno is valid */
  Bool keyAsData;       /* The OP_Column command works on key instead of data */
  Bool atFirst;         /* True if pointing to first entry */
  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
  Bool nullRow;         /* True if pointing to a row with no data */
  Bool nextRowidValid;  /* True if the nextRowid field is valid */
  Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
  Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
  Bool intKey;          /* True if the table requires integer keys */
  Bool zeroData;        /* True if table contains keys only - no data */
  u8 bogusIncrKey;      /* Something for pIncrKey to point to if pKeyInfo==0 */
  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
  Btree *pBt;           /* Separate file holding temporary table */
  int nData;            /* Number of bytes in pData */
  char *pData;          /* Data for a NEW or OLD pseudo-table */
  i64 iKey;             /* Key for the NEW or OLD pseudo-table row */
  u8 *pIncrKey;         /* Pointer to pKeyInfo->incrKey */
  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
  int nField;           /* Number of fields in the header */

  /* Cached information about the header for the data record that the
  ** cursor is currently pointing to.  Only valid if cacheValid is true.
  ** zRow might point to (ephemeral) data for the current row, or it might
  ** be NULL. */
  Bool cacheValid;      /* True if the cache is valid */
  int payloadSize;      /* Total number of bytes in the record */
  u32 *aType;           /* Type values for all entries in the record */
  u32 *aOffset;         /* Cached offsets to the start of each columns data */
  u8 *aRow;             /* Data for the current row, if all on one page */
};
typedef struct Cursor Cursor;

/*
** Number of bytes of string storage space available to each stack
** layer without having to malloc.  NBFS is short for Number of Bytes
** For Strings.
*/
#define NBFS 32

/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.  A value (and therefore Mem structure)
** has the following properties:
**
** Each value has a manifest type. The manifest type of the value stored
** in a Mem struct is returned by the MemType(Mem*) macro. The type is
** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or
** SQLITE_BLOB.
*/
struct Mem {
  i64 i;              /* Integer value */
  int n;              /* Number of characters in string value, including '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of MEM_Null, MEM_Str, etc. */
  u8  enc;            /* TEXT_Utf8, TEXT_Utf16le, or TEXT_Utf16be */
  double r;           /* Real value */
  char *z;            /* String or BLOB value */
  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
  char zShort[NBFS];  /* Space for short strings */
};
typedef struct Mem Mem;

/*
** A sorter builds a list of elements to be sorted.  Each element of
** the list is an instance of the following structure.
*/
typedef struct Sorter Sorter;
struct Sorter {
  int nKey;           /* Number of bytes in the key */
  char *zKey;         /* The key by which we will sort */
  Mem data;
  Sorter *pNext;      /* Next in the list */
};

/* 
** Number of buckets used for merge-sort.  
*/
#define NSORT 30

/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** No other flags may be set in this case.
**
** If the MEM_Str flag is set then Mem.z points at a string representation.
** Usually this is encoded in the same unicode encoding as the main
** database (see below for exceptions). If the MEM_Term flag is also
** set, then the string is nul terminated. The MEM_Int and MEM_Real 
** flags may coexist with the MEM_Str flag.
**
** Multiple of these values can appear in Mem.flags.  But only one
** at a time can appear in Mem.type.
*/
#define MEM_Null      0x0001   /* Value is NULL */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */

/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0020   /* String rep is nul terminated */
#define MEM_Dyn       0x0040   /* Need to call sqliteFree() on Mem.z */
#define MEM_Static    0x0080   /* Mem.z points to a static string */
#define MEM_Ephem     0x0100   /* Mem.z points to an ephemeral string */
#define MEM_Short     0x0200   /* Mem.z points to Mem.zShort */

/* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
** It indicates that the corresponding AggElem.aMem.z points to a
** aggregate function context that needs to be finalized.
*/
#define MEM_AggCtx    0x0400  /* Mem.z points to an agg function context */


/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
** additional information about auxiliary information bound to arguments
** of the function.  This is used to implement the sqlite3_get_auxdata()
** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
** that can be associated with a constant argument to a function.  This
** allows functions such as "regexp" to compile their constant regular
** expression argument once and reused the compiled code for multiple
** invocations.
*/
struct VdbeFunc {
  FuncDef *pFunc;               /* The definition of the function */
  int nAux;                     /* Number of entries allocated for apAux[] */
  struct AuxData {
    void *pAux;                   /* Aux data for the i-th argument */
    void (*xDelete)(void *);      /* Destructor for the aux data */
  } apAux[1];                   /* One slot for each function argument */
};
typedef struct VdbeFunc VdbeFunc;

/*
** The "context" argument for a installable function.  A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbe.c because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  FuncDef *pFunc;   /* Pointer to function information.  MUST BE FIRST */
  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
  Mem s;            /* The return value is stored here */
  void *pAgg;       /* Aggregate context */
  u8 isError;       /* Set to true for an error */
  int cnt;          /* Number of times that the step function has been called */
  CollSeq *pColl;
};

/*
** An Agg structure describes an Aggregator.  Each Agg consists of
** zero or more Aggregator elements (AggElem).  Each AggElem contains
** a key and one or more values.  The values are used in processing
** aggregate functions in a SELECT.  The key is used to implement
** the GROUP BY clause of a select.
*/
typedef struct Agg Agg;
typedef struct AggElem AggElem;
struct Agg {
  int nMem;            /* Number of values stored in each AggElem */
  AggElem *pCurrent;   /* The AggElem currently in focus */
  FuncDef **apFunc;    /* Information about aggregate functions */
  Btree *pBtree;       /* The tmp. btree used to group elements, if required. */
  BtCursor *pCsr;      /* Read/write cursor to the table in pBtree */
  int nTab;            /* Root page of the table in pBtree */
  u8 searching;        /* True between the first AggNext and AggReset */
};
struct AggElem {
  char *zKey;          /* The key to this AggElem */
  int nKey;            /* Number of bytes in the key, including '\0' at end */
  Mem aMem[1];         /* The values for this AggElem */
};

/*
** A Set structure is used for quick testing to see if a value
** is part of a small set.  Sets are used to implement code like
** this:
**            x.y IN ('hi','hoo','hum')
*/
typedef struct Set Set;
struct Set {
  Hash hash;             /* A set is just a hash table */
  HashElem *prev;        /* Previously accessed hash elemen */
};

/*
** A Keylist is a bunch of keys into a table.  The keylist can
** grow without bound.  The keylist stores the ROWIDs of database
** records that need to be deleted or updated.
*/
typedef struct Keylist Keylist;
struct Keylist {
  int nKey;         /* Number of slots in aKey[] */
  int nUsed;        /* Next unwritten slot in aKey[] */
  int nRead;        /* Next unread slot in aKey[] */
  Keylist *pNext;   /* Next block of keys */
  i64 aKey[1];      /* One or more keys.  Extra space allocated as needed */
};

/*
** A Context stores the last insert rowid, the last statement change count,
** and the current statement change count (i.e. changes since last statement).
** The current keylist is also stored in the context.
** Elements of Context structure type make up the ContextStack, which is
** updated by the ContextPush and ContextPop opcodes (used by triggers).
** The context is pushed before executing a trigger a popped when the
** trigger finishes.
*/
typedef struct Context Context;
struct Context {
  int lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
  int nChange;      /* Statement changes (Vdbe.nChanges)     */
  Keylist *pList;   /* Records that will participate in a DELETE or UPDATE */
};

/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
** is really a pointer to an instance of this structure.
*/
struct Vdbe {
  sqlite3 *db;        /* The whole database */
  Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
  FILE *trace;        /* Write an execution trace here, if not NULL */
  int nOp;            /* Number of instructions in the program */
  int nOpAlloc;       /* Number of slots allocated for aOp[] */
  Op *aOp;            /* Space to hold the virtual machine's program */
  int nLabel;         /* Number of labels used */
  int nLabelAlloc;    /* Number of slots allocated in aLabel[] */
  int *aLabel;        /* Space to hold the labels */
  Mem *aStack;        /* The operand stack, except string values */
  Mem *pTos;          /* Top entry in the operand stack */
  Mem **apArg;        /* Arguments to currently executing user function */
  Mem *aColName;      /* Column names to return */
  int nCursor;        /* Number of slots in apCsr[] */
  Cursor **apCsr;     /* One element of this array for each open cursor */
  Sorter *pSort;      /* A linked list of objects to be sorted */
  int nVar;           /* Number of entries in aVar[] */
  Mem *aVar;          /* Values for the OP_Variable opcode. */
  char **azVar;       /* Name of variables */
  int okVar;          /* True if azVar[] has been initialized */
  int magic;              /* Magic number for sanity checking */
  int nMem;               /* Number of memory locations currently allocated */
  Mem *aMem;              /* The memory locations */
  int nAgg;               /* Number of elements in apAgg */
  Agg *apAgg;             /* Array of aggregate contexts */
  Agg *pAgg;              /* Current aggregate context */
  int nCallback;          /* Number of callbacks invoked so far */
  Keylist *pList;         /* A list of ROWIDs */
  int contextStackTop;    /* Index of top element in the context stack */
  int contextStackDepth;  /* The size of the "context" stack */
  Context *contextStack;  /* Stack used by opcodes ContextPush & ContextPop*/
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
  unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
  int errorAction;        /* Recovery action to do in case of an error */
  int inTempTrans;        /* True if temp database is transactioned */
  int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
  int returnDepth;        /* Next unused element in returnStack[] */
  int nResColumn;         /* Number of columns in one row of the result set */
  char **azResColumn;     /* Values for one row of result */ 
  int popStack;           /* Pop the stack this much on entry to VdbeExec() */
  char *zErrMsg;          /* Error message written here */
  u8 resOnStack;          /* True if there are result values on the stack */
  u8 explain;             /* True if EXPLAIN present on SQL command */
  u8 changeCntOn;         /* True to update the change-counter */
  u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
  u8 expired;             /* True if the VM needs to be recompiled */
  int nChange;            /* Number of db changes made since last reset */
};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */

/*
** Function prototypes
*/
void sqlite3VdbeFreeCursor(Cursor*);
void sqlite3VdbeSorterReset(Vdbe*);
int sqlite3VdbeAggReset(sqlite3*, Agg *, KeyInfo *);
void sqlite3VdbeKeylistFree(Keylist*);
void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(Cursor*);
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
#ifdef SQLITE_DEBUG
void sqlite3VdbePrintSql(Vdbe*);
#endif
int sqlite3VdbeSerialTypeLen(u32);
u32 sqlite3VdbeSerialType(Mem*);
int sqlite3VdbeSerialPut(unsigned char*, Mem*);
int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*);
int sqlite3VdbeIdxRowidLen(int,const u8*);
int sqlite3VdbeExec(Vdbe*);
int sqlite3VdbeList(Vdbe*);
int sqlite3VdbeHalt(Vdbe*);
int sqlite3VdbeChangeEncoding(Mem *, int);
int sqlite3VdbeMemCopy(Mem*, const Mem*);
void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
int sqlite3VdbeMemMove(Mem*, Mem*);
int sqlite3VdbeMemNulTerminate(Mem*);
int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
void sqlite3VdbeMemSetInt64(Mem*, i64);
void sqlite3VdbeMemSetDouble(Mem*, double);
void sqlite3VdbeMemSetNull(Mem*);
int sqlite3VdbeMemMakeWriteable(Mem*);
int sqlite3VdbeMemDynamicify(Mem*);
int sqlite3VdbeMemStringify(Mem*, int);
i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
#ifndef NDEBUG
void sqlite3VdbeMemSanity(Mem*, u8);
#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
int sqlite3VdbeMemHandleBom(Mem *pMem);
Added SQLite.Interop/src/vdbeapi.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
/*
** 2004 May 26
**
** 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 file contains code use to implement APIs that are part of the
** VDBE.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled.  A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.
**
***** EXPERIMENTAL ******
*/
int sqlite3_expired(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  return p==0 || p->expired;
}

/**************************** sqlite3_value_  *******************************
** The following routines extract information from a Mem or sqlite3_value
** structure.
*/
const void *sqlite3_value_blob(sqlite3_value *pVal){
  Mem *p = (Mem*)pVal;
  if( p->flags & (MEM_Blob|MEM_Str) ){
    return p->z;
  }else{
    return sqlite3_value_text(pVal);
  }
}
int sqlite3_value_bytes(sqlite3_value *pVal){
  return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
int sqlite3_value_bytes16(sqlite3_value *pVal){
  return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
double sqlite3_value_double(sqlite3_value *pVal){
  return sqlite3VdbeRealValue((Mem*)pVal);
}
int sqlite3_value_int(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}
sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
  return (const char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_value_text16(sqlite3_value* pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
const void *sqlite3_value_text16be(sqlite3_value *pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16BE);
}
const void *sqlite3_value_text16le(sqlite3_value *pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16LE);
}
#endif /* SQLITE_OMIT_UTF16 */
int sqlite3_value_type(sqlite3_value* pVal){
  return pVal->type;
}

/**************************** sqlite3_result_  *******************************
** The following routines are used by user-defined functions to specify
** the function result.
*/
void sqlite3_result_blob(
  sqlite3_context *pCtx, 
  const void *z, 
  int n, 
  void (*xDel)(void *)
){
  assert( n>0 );
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
}
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
  sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
}
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
  pCtx->isError = 1;
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
  pCtx->isError = 1;
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
  sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
}
void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
  sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
}
void sqlite3_result_null(sqlite3_context *pCtx){
  sqlite3VdbeMemSetNull(&pCtx->s);
}
void sqlite3_result_text(
  sqlite3_context *pCtx, 
  const char *z, 
  int n,
  void (*xDel)(void *)
){
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel);
}
#ifndef SQLITE_OMIT_UTF16
void sqlite3_result_text16(
  sqlite3_context *pCtx, 
  const void *z, 
  int n, 
  void (*xDel)(void *)
){
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);
}
void sqlite3_result_text16be(
  sqlite3_context *pCtx, 
  const void *z, 
  int n, 
  void (*xDel)(void *)
){
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel);
}
void sqlite3_result_text16le(
  sqlite3_context *pCtx, 
  const void *z, 
  int n, 
  void (*xDel)(void *)
){
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
  sqlite3VdbeMemCopy(&pCtx->s, pValue);
}


/*
** Execute the statement pStmt, either until a row of data is ready, the
** statement is completely executed or an error occurs.
*/
int sqlite3_step(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  sqlite3 *db;
  int rc;

  if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }
  if( p->aborted ){
    return SQLITE_ABORT;
  }
  if( p->pc<=0 && p->expired ){
    if( p->rc==SQLITE_OK ){
      p->rc = SQLITE_SCHEMA;
    }
    return SQLITE_ERROR;
  }
  db = p->db;
  if( sqlite3SafetyOn(db) ){
    p->rc = SQLITE_MISUSE;
    return SQLITE_MISUSE;
  }
  if( p->pc<0 ){
    /* Invoke the trace callback if there is one
    */
    if( (db = p->db)->xTrace && !db->init.busy ){
      assert( p->nOp>0 );
      assert( p->aOp[p->nOp-1].opcode==OP_Noop );
      assert( p->aOp[p->nOp-1].p3!=0 );
      assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC );
      sqlite3SafetyOff(db);
      db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3);
      if( sqlite3SafetyOn(db) ){
        p->rc = SQLITE_MISUSE;
        return SQLITE_MISUSE;
      }
    }

    /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned
    ** on in debugging mode.
    */
#ifdef SQLITE_DEBUG
    if( (db->flags & SQLITE_SqlTrace)!=0 ){
      sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3);
    }
#endif /* SQLITE_DEBUG */

    db->activeVdbeCnt++;
    p->pc = 0;
  }
#ifndef SQLITE_OMIT_EXPLAIN
  if( p->explain ){
    rc = sqlite3VdbeList(p);
  }else
#endif /* SQLITE_OMIT_EXPLAIN */
  {
    rc = sqlite3VdbeExec(p);
  }

  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
  }

  sqlite3Error(p->db, rc, p->zErrMsg);
  return rc;
}

/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
*/
void *sqlite3_user_data(sqlite3_context *p){
  assert( p && p->pFunc );
  return p->pFunc->pUserData;
}

/*
** Allocate or return the aggregate context for a user function.  A new
** context is allocated on the first call.  Subsequent calls return the
** same context that was returned on prior calls.
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite3_context structure which is only defined in
** this source file.
*/
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
  assert( p && p->pFunc && p->pFunc->xStep );
  if( p->pAgg==0 ){
    if( nByte<=NBFS ){
      p->pAgg = (void*)p->s.z;
      memset(p->pAgg, 0, nByte);
    }else{
      p->pAgg = sqliteMalloc( nByte );
    }
  }
  return p->pAgg;
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
  VdbeFunc *pVdbeFunc = pCtx->pVdbeFunc;
  if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
    return 0;
  }
  return pVdbeFunc->apAux[iArg].pAux;
}

/*
** Set the auxilary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
*/
void sqlite3_set_auxdata(
  sqlite3_context *pCtx, 
  int iArg, 
  void *pAux, 
  void (*xDelete)(void*)
){
  struct AuxData *pAuxData;
  VdbeFunc *pVdbeFunc;
  if( iArg<0 ) return;

  pVdbeFunc = pCtx->pVdbeFunc;
  if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
    int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
    pCtx->pVdbeFunc = pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc);
    if( !pVdbeFunc ) return;
    memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0, 
             sizeof(struct AuxData)*(iArg+1-pVdbeFunc->nAux));
    pVdbeFunc->nAux = iArg+1;
    pVdbeFunc->pFunc = pCtx->pFunc;
  }

  pAuxData = &pVdbeFunc->apAux[iArg];
  if( pAuxData->pAux && pAuxData->xDelete ){
    pAuxData->xDelete(pAuxData->pAux);
  }
  pAuxData->pAux = pAux;
  pAuxData->xDelete = xDelete;
}

/*
** Return the number of times the Step function of a aggregate has been 
** called.
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite3_context structure which is only defined in
** this source file.
*/
int sqlite3_aggregate_count(sqlite3_context *p){
  assert( p && p->pFunc && p->pFunc->xStep );
  return p->cnt;
}

/*
** Return the number of columns in the result set for the statement pStmt.
*/
int sqlite3_column_count(sqlite3_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;
  return pVm ? pVm->nResColumn : 0;
}

/*
** Return the number of values available from the current row of the
** currently executing statement pStmt.
*/
int sqlite3_data_count(sqlite3_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;
  if( pVm==0 || !pVm->resOnStack ) return 0;
  return pVm->nResColumn;
}


/*
** Check to see if column iCol of the given statement is valid.  If
** it is, return a pointer to the Mem for the value of that column.
** If iCol is not valid, return a pointer to a Mem which has a value
** of NULL.
*/
static Mem *columnMem(sqlite3_stmt *pStmt, int i){
  Vdbe *pVm = (Vdbe *)pStmt;
  int vals = sqlite3_data_count(pStmt);
  if( i>=vals || i<0 ){
    static Mem nullMem;
    if( nullMem.flags==0 ){ nullMem.flags = MEM_Null; }
    sqlite3Error(pVm->db, SQLITE_RANGE, 0);
    return &nullMem;
  }
  return &pVm->pTos[(1-vals)+i];
}

/**************************** sqlite3_column_  *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_blob( columnMem(pStmt,i) );
}
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_bytes( columnMem(pStmt,i) );
}
int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_bytes16( columnMem(pStmt,i) );
}
double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_double( columnMem(pStmt,i) );
}
int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_int( columnMem(pStmt,i) );
}
sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_int64( columnMem(pStmt,i) );
}
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_text( columnMem(pStmt,i) );
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_text16( columnMem(pStmt,i) );
}
#endif /* SQLITE_OMIT_UTF16 */
int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_type( columnMem(pStmt,i) );
}

/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string.  If N is out of range, return 0.
** If useType is 1, then use the second set of N elements (the datatype
** names) instead of the first set.
*/
static const void *columnName(
  sqlite3_stmt *pStmt,
  int N,
  const void *(*xFunc)(Mem*),
  int useType
){
  Vdbe *p = (Vdbe *)pStmt;
  int n = sqlite3_column_count(pStmt);

  if( p==0 || N>=n || N<0 ){
    return 0;
  }
  if( useType ){
    N += n;
  }
  return xFunc(&p->aColName[N]);
}


/*
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 0);
}

/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-8.
*/
const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 1);
}

#ifndef SQLITE_OMIT_UTF16
/*
** Return the name of the 'i'th column of the result set of SQL statement
** pStmt, encoded as UTF-16.
*/
const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0);
}

/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-16.
*/
const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1);
}
#endif /* SQLITE_OMIT_UTF16 */

/******************************* sqlite3_bind_  ***************************
** 
** Routines used to attach values to wildcards in a compiled SQL statement.
*/
/*
** Unbind the value bound to variable i in virtual machine p. This is the 
** the same as binding a NULL value to the column. If the "i" parameter is
** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
*/
static int vdbeUnbind(Vdbe *p, int i){
  Mem *pVar;
  if( p==0 || p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
    sqlite3Error(p->db, SQLITE_MISUSE, 0);
    return SQLITE_MISUSE;
  }
  if( i<1 || i>p->nVar ){
    sqlite3Error(p->db, SQLITE_RANGE, 0);
    return SQLITE_RANGE;
  }
  i--;
  pVar = &p->aVar[i];
  sqlite3VdbeMemRelease(pVar);
  pVar->flags = MEM_Null;
  sqlite3Error(p->db, SQLITE_OK, 0);
  return SQLITE_OK;
}

/*
** Bind a text or BLOB value.
*/
static int bindText(
  sqlite3_stmt *pStmt, 
  int i, 
  const void *zData, 
  int nData, 
  void (*xDel)(void*),
  int encoding
){
  Vdbe *p = (Vdbe *)pStmt;
  Mem *pVar;
  int rc;

  rc = vdbeUnbind(p, i);
  if( rc || zData==0 ){
    return rc;
  }
  pVar = &p->aVar[i-1];
  rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
  if( rc ){
    return rc;
  }
  if( rc==SQLITE_OK && encoding!=0 ){
    rc = sqlite3VdbeChangeEncoding(pVar, p->db->enc);
  }
  return rc;
}


/*
** Bind a blob value to an SQL statement variable.
*/
int sqlite3_bind_blob(
  sqlite3_stmt *pStmt, 
  int i, 
  const void *zData, 
  int nData, 
  void (*xDel)(void*)
){
  return bindText(pStmt, i, zData, nData, xDel, 0);
}
int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
  int rc;
  Vdbe *p = (Vdbe *)pStmt;
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE_OK ){
    sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
  }
  return rc;
}
int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
  return sqlite3_bind_int64(p, i, (i64)iValue);
}
int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
  int rc;
  Vdbe *p = (Vdbe *)pStmt;
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE_OK ){
    sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
  }
  return rc;
}
int sqlite3_bind_null(sqlite3_stmt* p, int i){
  return vdbeUnbind((Vdbe *)p, i);
}
int sqlite3_bind_text( 
  sqlite3_stmt *pStmt, 
  int i, 
  const char *zData, 
  int nData, 
  void (*xDel)(void*)
){
  return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
int sqlite3_bind_text16(
  sqlite3_stmt *pStmt, 
  int i, 
  const void *zData, 
  int nData, 
  void (*xDel)(void*)
){
  return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the number of wildcards that can be potentially bound to.
** This routine is added to support DBD::SQLite.  
*/
int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  return p ? p->nVar : 0;
}

/*
** Create a mapping from variable numbers to variable names
** in the Vdbe.azVar[] array, if such a mapping does not already
** exist.
*/
static void createVarMap(Vdbe *p){
  if( !p->okVar ){
    int j;
    Op *pOp;
    for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
      if( pOp->opcode==OP_Variable ){
        assert( pOp->p1>0 && pOp->p1<=p->nVar );
        p->azVar[pOp->p1-1] = pOp->p3;
      }
    }
    p->okVar = 1;
  }
}

/*
** Return the name of a wildcard parameter.  Return NULL if the index
** is out of range or if the wildcard is unnamed.
**
** The result is always UTF-8.
*/
const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
  Vdbe *p = (Vdbe*)pStmt;
  if( p==0 || i<1 || i>p->nVar ){
    return 0;
  }
  createVarMap(p);
  return p->azVar[i-1];
}

/*
** Given a wildcard parameter name, return the index of the variable
** with that name.  If there is no variable with the given name,
** return 0.
*/
int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
  Vdbe *p = (Vdbe*)pStmt;
  int i;
  if( p==0 ){
    return 0;
  }
  createVarMap(p); 
  if( zName ){
    for(i=0; i<p->nVar; i++){
      const char *z = p->azVar[i];
      if( z && strcmp(z,zName)==0 ){
        return i+1;
      }
    }
  }
  return 0;
}
Added SQLite.Interop/src/vdbeaux.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
/*
** 2003 September 6
**
** 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 file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"


/*
** When debugging the code generator in a symbolic debugger, one can
** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed
** as they are added to the instruction stream.
*/
#ifndef NDEBUG
int sqlite3_vdbe_addop_trace = 0;
#endif


/*
** Create a new virtual database engine.
*/
Vdbe *sqlite3VdbeCreate(sqlite3 *db){
  Vdbe *p;
  p = sqliteMalloc( sizeof(Vdbe) );
  if( p==0 ) return 0;
  p->db = db;
  if( db->pVdbe ){
    db->pVdbe->pPrev = p;
  }
  p->pNext = db->pVdbe;
  p->pPrev = 0;
  db->pVdbe = p;
  p->magic = VDBE_MAGIC_INIT;
  return p;
}

/*
** Turn tracing on or off
*/
void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
  p->trace = trace;
}

/*
** Resize the Vdbe.aOp array so that it contains at least N
** elements.
*/
static void resizeOpArray(Vdbe *p, int N){
  if( p->nOpAlloc<N ){
    int oldSize = p->nOpAlloc;
    p->nOpAlloc = N+100;
    p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
    if( p->aOp ){
      memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
    }
  }
}

/*
** Add a new instruction to the list of instructions current in the
** VDBE.  Return the address of the new instruction.
**
** Parameters:
**
**    p               Pointer to the VDBE
**
**    op              The opcode for this instruction
**
**    p1, p2          First two of the three possible operands.
**
** Use the sqlite3VdbeResolveLabel() function to fix an address and
** the sqlite3VdbeChangeP3() function to change the value of the P3
** operand.
*/
int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  p->nOp++;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, i+1);
  if( p->aOp==0 ){
    return 0;
  }
  pOp = &p->aOp[i];
  pOp->opcode = op;
  pOp->p1 = p1;
  pOp->p2 = p2;
  pOp->p3 = 0;
  pOp->p3type = P3_NOTUSED;
#ifdef SQLITE_DEBUG
  if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
#endif
  return i;
}

/*
** Add an opcode that includes the p3 value.
*/
int sqlite3VdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3,int p3type){
  int addr = sqlite3VdbeAddOp(p, op, p1, p2);
  sqlite3VdbeChangeP3(p, addr, zP3, p3type);
  return addr;
}

/*
** Create a new symbolic label for an instruction that has yet to be
** coded.  The symbolic label is really just a negative number.  The
** label can be used as the P2 value of an operation.  Later, when
** the label is resolved to a specific address, the VDBE will scan
** through its operation list and change all values of P2 which match
** the label into the resolved address.
**
** The VDBE knows that a P2 value is a label because labels are
** always negative and P2 values are suppose to be non-negative.
** Hence, a negative P2 value is a label that has yet to be resolved.
**
** Zero is returned if a malloc() fails.
*/
int sqlite3VdbeMakeLabel(Vdbe *p){
  int i;
  i = p->nLabel++;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( i>=p->nLabelAlloc ){
    p->nLabelAlloc = p->nLabelAlloc*2 + 10;
    p->aLabel = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
  }
  if( p->aLabel ){
    p->aLabel[i] = -1;
  }
  return -1-i;
}

/*
** Resolve label "x" to be the address of the next instruction to
** be inserted.  The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
void sqlite3VdbeResolveLabel(Vdbe *p, int x){
  int j = -1-x;
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( j>=0 && j<p->nLabel );
  if( p->aLabel ){
    p->aLabel[j] = p->nOp;
  }
}

/*
** Loop through the program looking for P2 values that are negative.
** Each such value is a label.  Resolve the label by setting the P2
** value to its correct non-zero value.
**
** This routine is called once after all opcodes have been inserted.
*/
static void resolveP2Values(Vdbe *p){
  int i;
  Op *pOp;
  int *aLabel = p->aLabel;
  if( aLabel==0 ) return;
  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
    if( pOp->p2>=0 ) continue;
    assert( -1-pOp->p2<p->nLabel );
    pOp->p2 = aLabel[-1-pOp->p2];
  }
  sqliteFree(p->aLabel);
  p->aLabel = 0;
}

/*
** Return the address of the next instruction to be inserted.
*/
int sqlite3VdbeCurrentAddr(Vdbe *p){
  assert( p->magic==VDBE_MAGIC_INIT );
  return p->nOp;
}

/*
** Add a whole list of operations to the operation stack.  Return the
** address of the first operation added.
*/
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
  int addr;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, p->nOp + nOp);
  if( p->aOp==0 ){
    return 0;
  }
  addr = p->nOp;
  if( nOp>0 ){
    int i;
    VdbeOpList const *pIn = aOp;
    for(i=0; i<nOp; i++, pIn++){
      int p2 = pIn->p2;
      VdbeOp *pOut = &p->aOp[i+addr];
      pOut->opcode = pIn->opcode;
      pOut->p1 = pIn->p1;
      pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
      pOut->p3 = pIn->p3;
      pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
#ifdef SQLITE_DEBUG
      if( sqlite3_vdbe_addop_trace ){
        sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
      }
#endif
    }
    p->nOp += nOp;
  }
  return addr;
}

/*
** Change the value of the P1 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.
*/
void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p1 = val;
  }
}

/*
** Change the value of the P2 operand for a specific instruction.
** This routine is useful for setting a jump destination.
*/
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
  assert( val>=0 );
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p2 = val;
  }
}

/*
** Change the value of the P3 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.
**
** If n>=0 then the P3 operand is dynamic, meaning that a copy of
** the string is made into memory obtained from sqliteMalloc().
** A value of n==0 means copy bytes of zP3 up to and including the
** first null byte.  If n>0 then copy n+1 bytes of zP3.
**
** If n==P3_STATIC  it means that zP3 is a pointer to a constant static
** string and we can just copy the pointer.  n==P3_POINTER means zP3 is
** a pointer to some object other than a string.  n==P3_COLLSEQ and
** n==P3_KEYINFO mean that zP3 is a pointer to a CollSeq or KeyInfo
** structure.  A copy is made of KeyInfo structures into memory obtained
** from sqliteMalloc.
**
** If addr<0 then change P3 on the most recently inserted instruction.
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
  Op *pOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p==0 || p->aOp==0 ) return;
  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
    if( addr<0 ) return;
  }
  pOp = &p->aOp[addr];
  if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
    sqliteFree(pOp->p3);
    pOp->p3 = 0;
  }
  if( zP3==0 ){
    pOp->p3 = 0;
    pOp->p3type = P3_NOTUSED;
  }else if( n==P3_KEYINFO ){
    KeyInfo *pKeyInfo;
    int nField, nByte;
    nField = ((KeyInfo*)zP3)->nField;
    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]);
    pKeyInfo = sqliteMallocRaw( nByte );
    pOp->p3 = (char*)pKeyInfo;
    if( pKeyInfo ){
      memcpy(pKeyInfo, zP3, nByte);
      pOp->p3type = P3_KEYINFO;
    }else{
      pOp->p3type = P3_NOTUSED;
    }
  }else if( n==P3_KEYINFO_HANDOFF ){
    pOp->p3 = (char*)zP3;
    pOp->p3type = P3_KEYINFO;
  }else if( n<0 ){
    pOp->p3 = (char*)zP3;
    pOp->p3type = n;
  }else{
    if( n==0 ) n = strlen(zP3);
    pOp->p3 = sqliteStrNDup(zP3, n);
    pOp->p3type = P3_DYNAMIC;
  }
}

#ifndef NDEBUG
/*
** Replace the P3 field of the most recently coded instruction with
** comment text.
*/
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  assert( p->nOp>0 );
  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 );
  va_start(ap, zFormat);
  sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
  va_end(ap);
}
#endif

/*
** If the P3 operand to the specified instruction appears
** to be a quoted string token, then this procedure removes 
** the quotes.
**
** The quoting operator can be either a grave ascent (ASCII 0x27)
** or a double quote character (ASCII 0x22).  Two quotes in a row
** resolve to be a single actual quote character within the string.
*/
void sqlite3VdbeDequoteP3(Vdbe *p, int addr){
  Op *pOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p->aOp==0 ) return;
  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
    if( addr<0 ) return;
  }
  pOp = &p->aOp[addr];
  if( pOp->p3==0 || pOp->p3[0]==0 ) return;
  if( pOp->p3type==P3_STATIC ){
    pOp->p3 = sqliteStrDup(pOp->p3);
    pOp->p3type = P3_DYNAMIC;
  }
  assert( pOp->p3type==P3_DYNAMIC );
  sqlite3Dequote(pOp->p3);
}

/*
** Search the current program starting at instruction addr for the given
** opcode and P2 value.  Return the address plus 1 if found and 0 if not
** found.
*/
int sqlite3VdbeFindOp(Vdbe *p, int addr, int op, int p2){
  int i;
  assert( p->magic==VDBE_MAGIC_INIT );
  for(i=addr; i<p->nOp; i++){
    if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return i+1;
  }
  return 0;
}

/*
** Return the opcode for a given address.
*/
VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( addr>=0 && addr<p->nOp );
  return &p->aOp[addr];
}

#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Compute a string that describes the P3 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP3(Op *pOp, char *zTemp, int nTemp){
  char *zP3;
  assert( nTemp>=20 );
  switch( pOp->p3type ){
    case P3_POINTER: {
      sprintf(zTemp, "ptr(%#x)", (int)pOp->p3);
      zP3 = zTemp;
      break;
    }
    case P3_KEYINFO: {
      int i, j;
      KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
      sprintf(zTemp, "keyinfo(%d", pKeyInfo->nField);
      i = strlen(zTemp);
      for(j=0; j<pKeyInfo->nField; j++){
        CollSeq *pColl = pKeyInfo->aColl[j];
        if( pColl ){
          int n = strlen(pColl->zName);
          if( i+n>nTemp-6 ){
            strcpy(&zTemp[i],",...");
            break;
          }
          zTemp[i++] = ',';
          if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
            zTemp[i++] = '-';
          }
          strcpy(&zTemp[i], pColl->zName);
          i += n;
        }else if( i+4<nTemp-6 ){
          strcpy(&zTemp[i],",nil");
          i += 4;
        }
      }
      zTemp[i++] = ')';
      zTemp[i] = 0;
      assert( i<nTemp );
      zP3 = zTemp;
      break;
    }
    case P3_COLLSEQ: {
      CollSeq *pColl = (CollSeq*)pOp->p3;
      sprintf(zTemp, "collseq(%.20s)", pColl->zName);
      zP3 = zTemp;
      break;
    }
    case P3_FUNCDEF: {
      FuncDef *pDef = (FuncDef*)pOp->p3;
      char zNum[30];
      sprintf(zTemp, "%.*s", nTemp, pDef->zName);
      sprintf(zNum,"(%d)", pDef->nArg);
      if( strlen(zTemp)+strlen(zNum)+1<=nTemp ){
        strcat(zTemp, zNum);
      }
      zP3 = zTemp;
      break;
    }
    default: {
      zP3 = pOp->p3;
      if( zP3==0 || pOp->opcode==OP_Noop ){
        zP3 = "";
      }
    }
  }
  return zP3;
}
#endif


#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Print a single opcode.  This routine is used for debugging only.
*/
void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
  char *zP3;
  char zPtr[50];
  static const char *zFormat1 = "%4d %-13s %4d %4d %s\n";
  if( pOut==0 ) pOut = stdout;
  zP3 = displayP3(pOp, zPtr, sizeof(zPtr));
  fprintf(pOut, zFormat1,
      pc, sqlite3OpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3);
  fflush(pOut);
}
#endif

/*
** Release an array of N Mem elements
*/
static void releaseMemArray(Mem *p, int N){
  if( p ){
    while( N-->0 ){
      sqlite3VdbeMemRelease(p++);
    }
  }
}

#ifndef SQLITE_OMIT_EXPLAIN
/*
** Give a listing of the program in the virtual machine.
**
** The interface is the same as sqlite3VdbeExec().  But instead of
** running the code, it invokes the callback once for each instruction.
** This feature is used to implement "EXPLAIN".
*/
int sqlite3VdbeList(
  Vdbe *p                   /* The VDBE */
){
  sqlite3 *db = p->db;
  int i;
  int rc = SQLITE_OK;

  assert( p->explain );
  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
  assert( db->magic==SQLITE_MAGIC_BUSY );
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );

  /* Even though this opcode does not put dynamic strings onto the
  ** the stack, they may become dynamic if the user calls
  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
  */
  if( p->pTos==&p->aStack[4] ){
    releaseMemArray(p->aStack, 5);
  }
  p->resOnStack = 0;


  i = p->pc++;
  if( i>=p->nOp ){
    p->rc = SQLITE_OK;
    rc = SQLITE_DONE;
  }else if( db->flags & SQLITE_Interrupt ){
    db->flags &= ~SQLITE_Interrupt;
    p->rc = SQLITE_INTERRUPT;
    rc = SQLITE_ERROR;
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0);
  }else{
    Op *pOp = &p->aOp[i];
    Mem *pMem = p->aStack;
    pMem->flags = MEM_Int;
    pMem->type = SQLITE_INTEGER;
    pMem->i = i;                                /* Program counter */
    pMem++;

    pMem->flags = MEM_Static|MEM_Str|MEM_Term;
    pMem->z = sqlite3OpcodeNames[pOp->opcode];  /* Opcode */
    pMem->n = strlen(pMem->z);
    pMem->type = SQLITE_TEXT;
    pMem->enc = SQLITE_UTF8;
    pMem++;

    pMem->flags = MEM_Int;
    pMem->i = pOp->p1;                          /* P1 */
    pMem->type = SQLITE_INTEGER;
    pMem++;

    pMem->flags = MEM_Int;
    pMem->i = pOp->p2;                          /* P2 */
    pMem->type = SQLITE_INTEGER;
    pMem++;

    pMem->flags = MEM_Short|MEM_Str|MEM_Term;   /* P3 */
    pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
    pMem->type = SQLITE_TEXT;
    pMem->enc = SQLITE_UTF8;

    p->nResColumn = 5;
    p->pTos = pMem;
    p->rc = SQLITE_OK;
    p->resOnStack = 1;
    rc = SQLITE_ROW;
  }
  return rc;
}
#endif /* SQLITE_OMIT_EXPLAIN */

/*
** Print the SQL that was used to generate a VDBE program.
*/
void sqlite3VdbePrintSql(Vdbe *p){
#ifdef SQLITE_DEBUG
  int nOp = p->nOp;
  VdbeOp *pOp;
  if( nOp<1 ) return;
  pOp = &p->aOp[nOp-1];
  if( pOp->opcode==OP_Noop && pOp->p3!=0 ){
    const char *z = pOp->p3;
    while( isspace(*(u8*)z) ) z++;
    printf("SQL: [%s]\n", z);
  }
#endif
}

/*
** Prepare a virtual machine for execution.  This involves things such
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqlite3VdbeExec().  
**
** This is the only way to move a VDBE from VDBE_MAGIC_INIT to
** VDBE_MAGIC_RUN.
*/
void sqlite3VdbeMakeReady(
  Vdbe *p,                       /* The VDBE */
  int nVar,                      /* Number of '?' see in the SQL statement */
  int nMem,                      /* Number of memory cells to allocate */
  int nCursor,                   /* Number of cursors to allocate */
  int nAgg,                      /* Number of aggregate contexts required */
  int isExplain                  /* True if the EXPLAIN keywords is present */
){
  int n;

  assert( p!=0 );
  assert( p->magic==VDBE_MAGIC_INIT );

  /* There should be at least one opcode.
  */
  assert( p->nOp>0 );

  /* No instruction ever pushes more than a single element onto the
  ** stack.  And the stack never grows on successive executions of the
  ** same loop.  So the total number of instructions is an upper bound
  ** on the maximum stack depth required.
  **
  ** Allocation all the stack space we will ever need.
  */
  if( p->aStack==0 ){
    resolveP2Values(p);
    assert( nVar>=0 );
    n = isExplain ? 10 : p->nOp;
    p->aStack = sqliteMalloc(
        n*sizeof(p->aStack[0])         /* aStack */
      + n*sizeof(Mem*)                 /* apArg */
      + nVar*sizeof(Mem)               /* aVar */
      + nVar*sizeof(char*)             /* azVar */
      + nMem*sizeof(Mem)               /* aMem */
      + nCursor*sizeof(Cursor*)        /* apCsr */
      + nAgg*sizeof(Agg)               /* Aggregate contexts */
    );
    if( !sqlite3_malloc_failed ){
      p->aMem = &p->aStack[n];
      p->nMem = nMem;
      p->aVar = &p->aMem[nMem];
      p->nVar = nVar;
      p->okVar = 0;
      p->apArg = (Mem**)&p->aVar[nVar];
      p->azVar = (char**)&p->apArg[n];
      p->apCsr = (Cursor**)&p->azVar[nVar];
      if( nAgg>0 ){
        p->nAgg = nAgg;
        p->apAgg = (Agg*)&p->apCsr[nCursor];
      }
      p->nCursor = nCursor;
      for(n=0; n<nVar; n++){
        p->aVar[n].flags = MEM_Null;
      }
    }
  }
  p->pAgg = p->apAgg;
  for(n=0; n<p->nMem; n++){
    p->aMem[n].flags = MEM_Null;
  }

#ifdef SQLITE_DEBUG
  if( (p->db->flags & SQLITE_VdbeListing)!=0
    || sqlite3OsFileExists("vdbe_explain")
  ){
    int i;
    printf("VDBE Program Listing:\n");
    sqlite3VdbePrintSql(p);
    for(i=0; i<p->nOp; i++){
      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
    }
  }
  if( sqlite3OsFileExists("vdbe_trace") ){
    p->trace = stdout;
  }
#endif
  p->pTos = &p->aStack[-1];
  p->pc = -1;
  p->rc = SQLITE_OK;
  p->uniqueCnt = 0;
  p->returnDepth = 0;
  p->errorAction = OE_Abort;
  p->popStack =  0;
  p->explain |= isExplain;
  p->magic = VDBE_MAGIC_RUN;
  p->nChange = 0;
#ifdef VDBE_PROFILE
  {
    int i;
    for(i=0; i<p->nOp; i++){
      p->aOp[i].cnt = 0;
      p->aOp[i].cycles = 0;
    }
  }
#endif
}


/*
** Remove any elements that remain on the sorter for the VDBE given.
*/
void sqlite3VdbeSorterReset(Vdbe *p){
  while( p->pSort ){
    Sorter *pSorter = p->pSort;
    p->pSort = pSorter->pNext;
    sqliteFree(pSorter->zKey);
    sqlite3VdbeMemRelease(&pSorter->data);
    sqliteFree(pSorter);
  }
}

/*
** Free all resources allociated with AggElem pElem, an element of
** aggregate pAgg.
*/
static void freeAggElem(AggElem *pElem, Agg *pAgg){
  int i;
  for(i=0; i<pAgg->nMem; i++){
    Mem *pMem = &pElem->aMem[i];
    if( pAgg->apFunc && pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){
      sqlite3_context ctx;
      ctx.pFunc = pAgg->apFunc[i];
      ctx.s.flags = MEM_Null;
      ctx.pAgg = pMem->z;
      ctx.cnt = pMem->i;
      ctx.isError = 0;
      (*ctx.pFunc->xFinalize)(&ctx);
      pMem->z = ctx.pAgg;
      if( pMem->z!=0 && pMem->z!=pMem->zShort ){
        sqliteFree(pMem->z);
      }
      sqlite3VdbeMemRelease(&ctx.s);
    }else{
      sqlite3VdbeMemRelease(pMem);
    }
  }
  sqliteFree(pElem);
}

/*
** Reset an Agg structure.  Delete all its contents.
**
** For installable aggregate functions, if the step function has been
** called, make sure the finalizer function has also been called.  The
** finalizer might need to free memory that was allocated as part of its
** private context.  If the finalizer has not been called yet, call it
** now.
**
** If db is NULL, then this is being called from sqliteVdbeReset(). In
** this case clean up all references to the temp-table used for
** aggregates (if it was ever opened).
**
** If db is not NULL, then this is being called from with an OP_AggReset
** opcode. Open the temp-table, if it has not already been opened and
** delete the contents of the table used for aggregate information, ready
** for the next round of aggregate processing.
*/
int sqlite3VdbeAggReset(sqlite3 *db, Agg *pAgg, KeyInfo *pKeyInfo){
  int rc = 0;
  BtCursor *pCsr;

  if( !pAgg ) return SQLITE_OK;
  pCsr = pAgg->pCsr;
  assert( (pCsr && pAgg->nTab>0) || (!pCsr && pAgg->nTab==0)
         || sqlite3_malloc_failed );

  /* If pCsr is not NULL, then the table used for aggregate information
  ** is open. Loop through it and free the AggElem* structure pointed at
  ** by each entry. If the finalizer has not been called for an AggElem,
  ** do that too. Finally, clear the btree table itself.
  */
  if( pCsr ){
    int res;
    assert( pAgg->pBtree );
    assert( pAgg->nTab>0 );

    rc=sqlite3BtreeFirst(pCsr, &res);
    while( res==0 && rc==SQLITE_OK ){
      AggElem *pElem;
      rc = sqlite3BtreeData(pCsr, 0, sizeof(AggElem*), (char *)&pElem);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      assert( pAgg->apFunc!=0 );
      freeAggElem(pElem, pAgg);
      rc=sqlite3BtreeNext(pCsr, &res);
    }
    if( rc!=SQLITE_OK ){
      return rc;
    }

    sqlite3BtreeCloseCursor(pCsr);
    sqlite3BtreeClearTable(pAgg->pBtree, pAgg->nTab);
  }else{ 
    /* The cursor may not be open because the aggregator was never used,
    ** or it could be that it was used but there was no GROUP BY clause.
    */
    if( pAgg->pCurrent ){
      freeAggElem(pAgg->pCurrent, pAgg);
    }
  }

  /* If db is not NULL and we have not yet and we have not yet opened
  ** the temporary btree then do so and create the table to store aggregate
  ** information.
  **
  ** If db is NULL, then close the temporary btree if it is open.
  */
  if( db ){
    if( !pAgg->pBtree ){
      assert( pAgg->nTab==0 );
#ifndef SQLITE_OMIT_MEMORYDB
      rc = sqlite3BtreeFactory(db, ":memory:", 0, TEMP_PAGES, &pAgg->pBtree);
#else
      rc = sqlite3BtreeFactory(db, 0, 0, TEMP_PAGES, &pAgg->pBtree);
#endif
      if( rc!=SQLITE_OK ) return rc;
      sqlite3BtreeBeginTrans(pAgg->pBtree, 1);
      rc = sqlite3BtreeCreateTable(pAgg->pBtree, &pAgg->nTab, 0);
      if( rc!=SQLITE_OK ) return rc;
    }
    assert( pAgg->nTab!=0 );

    rc = sqlite3BtreeCursor(pAgg->pBtree, pAgg->nTab, 1,
        sqlite3VdbeRecordCompare, pKeyInfo, &pAgg->pCsr);
    if( rc!=SQLITE_OK ) return rc;
  }else{
    if( pAgg->pBtree ){
      sqlite3BtreeClose(pAgg->pBtree);
      pAgg->pBtree = 0;
      pAgg->nTab = 0;
    }
    pAgg->pCsr = 0;
  }

  if( pAgg->apFunc ){ 
    sqliteFree(pAgg->apFunc);
    pAgg->apFunc = 0;
  }
  pAgg->pCurrent = 0;
  pAgg->nMem = 0;
  pAgg->searching = 0;
  return SQLITE_OK;
}


/*
** Delete a keylist
*/
void sqlite3VdbeKeylistFree(Keylist *p){
  while( p ){
    Keylist *pNext = p->pNext;
    sqliteFree(p);
    p = pNext;
  }
}

/*
** Close a cursor and release all the resources that cursor happens
** to hold.
*/
void sqlite3VdbeFreeCursor(Cursor *pCx){
  if( pCx==0 ){
    return;
  }
  if( pCx->pCursor ){
    sqlite3BtreeCloseCursor(pCx->pCursor);
  }
  if( pCx->pBt ){
    sqlite3BtreeClose(pCx->pBt);
  }
  sqliteFree(pCx->pData);
  sqliteFree(pCx->aType);
  sqliteFree(pCx);
}

/*
** Close all cursors
*/
static void closeAllCursors(Vdbe *p){
  int i;
  if( p->apCsr==0 ) return;
  for(i=0; i<p->nCursor; i++){
    sqlite3VdbeFreeCursor(p->apCsr[i]);
    p->apCsr[i] = 0;
  }
}

/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of
** variables in the aVar[] array.
*/
static void Cleanup(Vdbe *p){
  int i;
  if( p->aStack ){
    releaseMemArray(p->aStack, 1 + (p->pTos - p->aStack));
    p->pTos = &p->aStack[-1];
  }
  closeAllCursors(p);
  releaseMemArray(p->aMem, p->nMem);
  if( p->pList ){
    sqlite3VdbeKeylistFree(p->pList);
    p->pList = 0;
  }
  if( p->contextStack ){
    for(i=0; i<p->contextStackTop; i++){
      sqlite3VdbeKeylistFree(p->contextStack[i].pList);
    }
    sqliteFree(p->contextStack);
  }
  sqlite3VdbeSorterReset(p);
  for(i=0; i<p->nAgg; i++){
    sqlite3VdbeAggReset(0, &p->apAgg[i], 0);
  }
  p->contextStack = 0;
  p->contextStackDepth = 0;
  p->contextStackTop = 0;
  sqliteFree(p->zErrMsg);
  p->zErrMsg = 0;
}

/*
** Set the number of result columns that will be returned by this SQL
** statement. This is now set at compile time, rather than during
** execution of the vdbe program so that sqlite3_column_count() can
** be called on an SQL statement before sqlite3_step().
*/
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
  Mem *pColName;
  int n;
  assert( 0==p->nResColumn );
  p->nResColumn = nResColumn;
  n = nResColumn*2;
  p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  while( n-- > 0 ){
    (pColName++)->flags = MEM_Null;
  }
}

/*
** Set the name of the idx'th column to be returned by the SQL statement.
** zName must be a pointer to a nul terminated string.
**
** This call must be made after a call to sqlite3VdbeSetNumCols().
**
** If N==P3_STATIC  it means that zName is a pointer to a constant static
** string and we can just copy the pointer. If it is P3_DYNAMIC, then 
** the string is freed using sqliteFree() when the vdbe is finished with
** it. Otherwise, N bytes of zName are copied.
*/
int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
  int rc;
  Mem *pColName;
  assert( idx<(2*p->nResColumn) );
  if( sqlite3_malloc_failed ) return SQLITE_NOMEM;
  assert( p->aColName!=0 );
  pColName = &(p->aColName[idx]);
  if( N==P3_DYNAMIC || N==P3_STATIC ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
  }else{
    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
  }
  if( rc==SQLITE_OK && N==P3_DYNAMIC ){
    pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
    pColName->xDel = 0;
  }
  return rc;
}

/*
** A read or write transaction may or may not be active on database handle
** db. If a transaction is active, commit it. If there is a
** write-transaction spanning more than one database file, this routine
** takes care of the master journal trickery.
*/
static int vdbeCommit(sqlite3 *db){
  int i;
  int nTrans = 0;  /* Number of databases with an active write-transaction */
  int rc = SQLITE_OK;
  int needXcommit = 0;

  for(i=0; i<db->nDb; i++){ 
    Btree *pBt = db->aDb[i].pBt;
    if( pBt && sqlite3BtreeIsInTrans(pBt) ){
      needXcommit = 1;
      if( i!=1 ) nTrans++;
    }
  }

  /* If there are any write-transactions at all, invoke the commit hook */
  if( needXcommit && db->xCommitCallback ){
    int rc;
    sqlite3SafetyOff(db);
    rc = db->xCommitCallback(db->pCommitArg);
    sqlite3SafetyOn(db);
    if( rc ){
      return SQLITE_CONSTRAINT;
    }
  }

  /* The simple case - no more than one database file (not counting the
  ** TEMP database) has a transaction active.   There is no need for the
  ** master-journal.
  **
  ** If the return value of sqlite3BtreeGetFilename() is a zero length
  ** string, it means the main database is :memory:.  In that case we do
  ** not support atomic multi-file commits, so use the simple case then
  ** too.
  */
  if( 0==strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){
    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        rc = sqlite3BtreeSync(pBt, 0);
      }
    }

    /* Do the commit only if all databases successfully synced */
    if( rc==SQLITE_OK ){
      for(i=0; i<db->nDb; i++){
        Btree *pBt = db->aDb[i].pBt;
        if( pBt ){
          sqlite3BtreeCommit(pBt);
        }
      }
    }
  }

  /* The complex case - There is a multi-file write-transaction active.
  ** This requires a master journal file to ensure the transaction is
  ** committed atomicly.
  */
  else{
    char *zMaster = 0;   /* File-name for the master journal */
    char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
    OsFile master;

    /* Select a master journal file name */
    do {
      u32 random;
      sqliteFree(zMaster);
      sqlite3Randomness(sizeof(random), &random);
      zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random&0x7fffffff);
      if( !zMaster ){
        return SQLITE_NOMEM;
      }
    }while( sqlite3OsFileExists(zMaster) );

    /* Open the master journal. */
    memset(&master, 0, sizeof(master));
    rc = sqlite3OsOpenExclusive(zMaster, &master, 0);
    if( rc!=SQLITE_OK ){
      sqliteFree(zMaster);
      return rc;
    }
 
    /* Write the name of each database file in the transaction into the new
    ** master journal file. If an error occurs at this point close
    ** and delete the master journal file. All the individual journal files
    ** still have 'null' as the master journal pointer, so they will roll
    ** back independently if a failure occurs.
    */
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( i==1 ) continue;   /* Ignore the TEMP database */
      if( pBt && sqlite3BtreeIsInTrans(pBt) ){
        char const *zFile = sqlite3BtreeGetJournalname(pBt);
        if( zFile[0]==0 ) continue;  /* Ignore :memory: databases */
        rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1);
        if( rc!=SQLITE_OK ){
          sqlite3OsClose(&master);
          sqlite3OsDelete(zMaster);
          sqliteFree(zMaster);
          return rc;
        }
      }
    }


    /* Sync the master journal file. Before doing this, open the directory
    ** the master journal file is store in so that it gets synced too.
    */
    zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
    rc = sqlite3OsOpenDirectory(zMainFile, &master);
    if( rc!=SQLITE_OK || (rc = sqlite3OsSync(&master))!=SQLITE_OK ){
      sqlite3OsClose(&master);
      sqlite3OsDelete(zMaster);
      sqliteFree(zMaster);
      return rc;
    }

    /* Sync all the db files involved in the transaction. The same call
    ** sets the master journal pointer in each individual journal. If
    ** an error occurs here, do not delete the master journal file.
    **
    ** If the error occurs during the first call to sqlite3BtreeSync(),
    ** then there is a chance that the master journal file will be
    ** orphaned. But we cannot delete it, in case the master journal
    ** file name was written into the journal file before the failure
    ** occured.
    */
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( pBt && sqlite3BtreeIsInTrans(pBt) ){
        rc = sqlite3BtreeSync(pBt, zMaster);
        if( rc!=SQLITE_OK ){
          sqlite3OsClose(&master);
          sqliteFree(zMaster);
          return rc;
        }
      }
    }
    sqlite3OsClose(&master);

    /* Delete the master journal file. This commits the transaction. After
    ** doing this the directory is synced again before any individual
    ** transaction files are deleted.
    */
    rc = sqlite3OsDelete(zMaster);
    assert( rc==SQLITE_OK );
    sqliteFree(zMaster);
    zMaster = 0;
    rc = sqlite3OsSyncDirectory(zMainFile);
    if( rc!=SQLITE_OK ){
      /* This is not good. The master journal file has been deleted, but
      ** the directory sync failed. There is no completely safe course of
      ** action from here. The individual journals contain the name of the
      ** master journal file, but there is no way of knowing if that
      ** master journal exists now or if it will exist after the operating
      ** system crash that may follow the fsync() failure.
      */
      return rc;
    }

    /* All files and directories have already been synced, so the following
    ** calls to sqlite3BtreeCommit() are only closing files and deleting
    ** journals. If something goes wrong while this is happening we don't
    ** really care. The integrity of the transaction is already guaranteed,
    ** but some stray 'cold' journals may be lying around. Returning an
    ** error code won't help matters.
    */
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        sqlite3BtreeCommit(pBt);
      }
    }
  }

  return rc;
}

/*
** Find every active VM other than pVdbe and change its status to
** aborted.  This happens when one VM causes a rollback due to an
** ON CONFLICT ROLLBACK clause (for example).  The other VMs must be
** aborted so that they do not have data rolled out from underneath
** them leading to a segfault.
*/
static void abortOtherActiveVdbes(Vdbe *pVdbe){
  Vdbe *pOther;
  for(pOther=pVdbe->db->pVdbe; pOther; pOther=pOther->pNext){
    if( pOther==pVdbe ) continue;
    if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue;
    closeAllCursors(pOther);
    pOther->aborted = 1;
  }
}

/* 
** This routine checks that the sqlite3.activeVdbeCnt count variable
** matches the number of vdbe's in the list sqlite3.pVdbe that are
** currently active. An assertion fails if the two counts do not match.
** This is an internal self-check only - it is not an essential processing
** step.
**
** This is a no-op if NDEBUG is defined.
*/
#ifndef NDEBUG
static void checkActiveVdbeCnt(sqlite3 *db){
  Vdbe *p;
  int cnt = 0;
  p = db->pVdbe;
  while( p ){
    if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
      cnt++;
    }
    p = p->pNext;
  }
  assert( cnt==db->activeVdbeCnt );
}
#else
#define checkActiveVdbeCnt(x)
#endif

/*
** This routine is called the when a VDBE tries to halt.  If the VDBE
** has made changes and is in autocommit mode, then commit those
** changes.  If a rollback is needed, then do the rollback.
**
** This routine is the only way to move the state of a VM from
** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT.
**
** Return an error code.  If the commit could not complete because of
** lock contention, return SQLITE_BUSY.  If SQLITE_BUSY is returned, it
** means the close did not happen and needs to be repeated.
*/
int sqlite3VdbeHalt(Vdbe *p){
  sqlite3 *db = p->db;
  int i;
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */

  if( p->magic!=VDBE_MAGIC_RUN ){
    /* Already halted.  Nothing to do. */
    assert( p->magic==VDBE_MAGIC_HALT );
    return SQLITE_OK;
  }
  closeAllCursors(p);
  checkActiveVdbeCnt(db);
  if( p->pc<0 ){
    /* No commit or rollback needed if the program never started */
  }else if( db->autoCommit && db->activeVdbeCnt==1 ){
    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
      /* The auto-commit flag is true, there are no other active queries
      ** using this handle and the vdbe program was successful or hit an
      ** 'OR FAIL' constraint. This means a commit is required.
      */
      int rc = vdbeCommit(db);
      if( rc==SQLITE_BUSY ){
        return SQLITE_BUSY;
      }else if( rc!=SQLITE_OK ){
        p->rc = rc;
        xFunc = sqlite3BtreeRollback;
      }
    }else{
      xFunc = sqlite3BtreeRollback;
    }
  }else{
    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
      xFunc = sqlite3BtreeCommitStmt;
    }else if( p->errorAction==OE_Abort ){
      xFunc = sqlite3BtreeRollbackStmt;
    }else{
      xFunc = sqlite3BtreeRollback;
      db->autoCommit = 1;
      abortOtherActiveVdbes(p);
    }
  }

  /* If xFunc is not NULL, then it is one of sqlite3BtreeRollback,
  ** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
  ** each backend. If an error occurs and the return code is still
  ** SQLITE_OK, set the return code to the new error value.
  */
  for(i=0; xFunc && i<db->nDb; i++){ 
    int rc;
    Btree *pBt = db->aDb[i].pBt;
    if( pBt ){
      rc = xFunc(pBt);
      if( p->rc==SQLITE_OK ) p->rc = rc;
    }
  }

  /* If this was an INSERT, UPDATE or DELETE, set the change counter. */
  if( p->changeCntOn && p->pc>=0 ){
    if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
      sqlite3VdbeSetChanges(db, p->nChange);
    }else{
      sqlite3VdbeSetChanges(db, 0);
    }
    p->nChange = 0;
  }

  /* Rollback or commit any schema changes that occurred. */
  if( p->rc!=SQLITE_OK ){
    sqlite3RollbackInternalChanges(db);
  }else if( db->flags & SQLITE_InternChanges ){
    sqlite3CommitInternalChanges(db);
  }

  /* We have successfully halted and closed the VM.  Record this fact. */
  if( p->pc>=0 ){
    db->activeVdbeCnt--;
  }
  p->magic = VDBE_MAGIC_HALT;
  checkActiveVdbeCnt(db);

  return SQLITE_OK;
}

/*
** Clean up a VDBE after execution but do not delete the VDBE just yet.
** Write any error messages into *pzErrMsg.  Return the result code.
**
** After this routine is run, the VDBE should be ready to be executed
** again.
**
** To look at it another way, this routine resets the state of the
** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
** VDBE_MAGIC_INIT.
*/
int sqlite3VdbeReset(Vdbe *p){
  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
    sqlite3Error(p->db, SQLITE_MISUSE, 0);
    return SQLITE_MISUSE;
  }

  /* If the VM did not run to completion or if it encountered an
  ** error, then it might not have been halted properly.  So halt
  ** it now.
  */
  sqlite3VdbeHalt(p);

  /* If the VDBE has be run even partially, then transfer the error code
  ** and error message from the VDBE into the main database structure.  But
  ** if the VDBE has just been set to run but has not actually executed any
  ** instructions yet, leave the main database error information unchanged.
  */
  if( p->pc>=0 ){
    if( p->zErrMsg ){
      sqlite3Error(p->db, p->rc, "%s", p->zErrMsg);
      sqliteFree(p->zErrMsg);
      p->zErrMsg = 0;
    }else if( p->rc ){
      sqlite3Error(p->db, p->rc, 0);
    }else{
      sqlite3Error(p->db, SQLITE_OK, 0);
    }
  }else if( p->rc && p->expired ){
    /* The expired flag was set on the VDBE before the first call
    ** to sqlite3_step(). For consistency (since sqlite3_step() was
    ** called), set the database error in this case as well.
    */
    sqlite3Error(p->db, p->rc, 0);
  }

  /* Reclaim all memory used by the VDBE
  */
  Cleanup(p);

  /* Save profiling information from this VDBE run.
  */
  assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || sqlite3_malloc_failed==1 );
#ifdef VDBE_PROFILE
  {
    FILE *out = fopen("vdbe_profile.out", "a");
    if( out ){
      int i;
      fprintf(out, "---- ");
      for(i=0; i<p->nOp; i++){
        fprintf(out, "%02x", p->aOp[i].opcode);
      }
      fprintf(out, "\n");
      for(i=0; i<p->nOp; i++){
        fprintf(out, "%6d %10lld %8lld ",
           p->aOp[i].cnt,
           p->aOp[i].cycles,
           p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
        );
        sqlite3VdbePrintOp(out, i, &p->aOp[i]);
      }
      fclose(out);
    }
  }
#endif
  p->magic = VDBE_MAGIC_INIT;
  p->aborted = 0;
  if( p->rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(p->db, 0);
  }
  return p->rc;
}
 
/*
** Clean up and delete a VDBE after execution.  Return an integer which is
** the result code.  Write any error message text into *pzErrMsg.
*/
int sqlite3VdbeFinalize(Vdbe *p){
  int rc = SQLITE_OK;

  if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
    rc = sqlite3VdbeReset(p);
  }else if( p->magic!=VDBE_MAGIC_INIT ){
    return SQLITE_MISUSE;
  }
  sqlite3VdbeDelete(p);
  return rc;
}

/*
** Call the destructor for each auxdata entry in pVdbeFunc for which
** the corresponding bit in mask is clear.  Auxdata entries beyond 31
** are always destroyed.  To destroy all auxdata entries, call this
** routine with mask==0.
*/
void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
  int i;
  for(i=0; i<pVdbeFunc->nAux; i++){
    struct AuxData *pAux = &pVdbeFunc->apAux[i];
    if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){
      if( pAux->xDelete ){
        pAux->xDelete(pAux->pAux);
      }
      pAux->pAux = 0;
    }
  }
}

/*
** Delete an entire VDBE.
*/
void sqlite3VdbeDelete(Vdbe *p){
  int i;
  if( p==0 ) return;
  Cleanup(p);
  if( p->pPrev ){
    p->pPrev->pNext = p->pNext;
  }else{
    assert( p->db->pVdbe==p );
    p->db->pVdbe = p->pNext;
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  if( p->aOp ){
    for(i=0; i<p->nOp; i++){
      Op *pOp = &p->aOp[i];
      if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
        sqliteFree(pOp->p3);
      }
      if( pOp->p3type==P3_VDBEFUNC ){
        VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
        sqliteFree(pVdbeFunc);
      }
    }
    sqliteFree(p->aOp);
  }
  releaseMemArray(p->aVar, p->nVar);
  sqliteFree(p->aLabel);
  sqliteFree(p->aStack);
  releaseMemArray(p->aColName, p->nResColumn*2);
  sqliteFree(p->aColName);
  p->magic = VDBE_MAGIC_DEAD;
  sqliteFree(p);
}

/*
** If a MoveTo operation is pending on the given cursor, then do that
** MoveTo now.  Return an error code.  If no MoveTo is pending, this
** routine does nothing and returns SQLITE_OK.
*/
int sqlite3VdbeCursorMoveto(Cursor *p){
  if( p->deferredMoveto ){
    int res, rc;
    extern int sqlite3_search_count;
    assert( p->intKey );
    if( p->intKey ){
      rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
    }else{
      rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
                              sizeof(i64),&res);
    }
    if( rc ) return rc;
    *p->pIncrKey = 0;
    p->lastRecno = keyToInt(p->movetoTarget);
    p->recnoIsValid = res==0;
    if( res<0 ){
      rc = sqlite3BtreeNext(p->pCursor, &res);
      if( rc ) return rc;
    }
    sqlite3_search_count++;
    p->deferredMoveto = 0;
    p->cacheValid = 0;
  }
  return SQLITE_OK;
}

/*
** The following functions:
**
** sqlite3VdbeSerialType()
** sqlite3VdbeSerialTypeLen()
** sqlite3VdbeSerialRead()
** sqlite3VdbeSerialLen()
** sqlite3VdbeSerialWrite()
**
** encapsulate the code that serializes values for storage in SQLite
** data and index records. Each serialized value consists of a
** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
** integer, stored as a varint.
**
** In an SQLite index record, the serial type is stored directly before
** the blob of data that it corresponds to. In a table record, all serial
** types are stored at the start of the record, and the blobs of data at
** the end. Hence these functions allow the caller to handle the
** serial-type and data blob seperately.
**
** The following table describes the various storage classes for data:
**
**   serial type        bytes of data      type
**   --------------     ---------------    ---------------
**      0                     0            NULL
**      1                     1            signed integer
**      2                     2            signed integer
**      3                     3            signed integer
**      4                     4            signed integer
**      5                     6            signed integer
**      6                     8            signed integer
**      7                     8            IEEE float
**     8-11                                reserved for expansion
**    N>=12 and even       (N-12)/2        BLOB
**    N>=13 and odd        (N-13)/2        text
**
*/

/*
** Return the serial-type for the value stored in pMem.
*/
u32 sqlite3VdbeSerialType(Mem *pMem){
  int flags = pMem->flags;

  if( flags&MEM_Null ){
    return 0;
  }
  if( flags&MEM_Int ){
    /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
#   define MAX_6BYTE ((((i64)0x00010000)<<32)-1)
    i64 i = pMem->i;
    u64 u = i<0 ? -i : i;
    if( u<=127 ) return 1;
    if( u<=32767 ) return 2;
    if( u<=8388607 ) return 3;
    if( u<=2147483647 ) return 4;
    if( u<=MAX_6BYTE ) return 5;
    return 6;
  }
  if( flags&MEM_Real ){
    return 7;
  }
  if( flags&MEM_Str ){
    int n = pMem->n;
    assert( n>=0 );
    return ((n*2) + 13);
  }
  if( flags&MEM_Blob ){
    return (pMem->n*2 + 12);
  }
  return 0;
}

/*
** Return the length of the data corresponding to the supplied serial-type.
*/
int sqlite3VdbeSerialTypeLen(u32 serial_type){
  if( serial_type>=12 ){
    return (serial_type-12)/2;
  }else{
    static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
    return aSize[serial_type];
  }
}

/*
** Write the serialized data blob for the value stored in pMem into 
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
*/ 
int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
  u32 serial_type = sqlite3VdbeSerialType(pMem);
  int len;

  /* NULL */
  if( serial_type==0 ){
    return 0;
  }
 
  /* Integer and Real */
  if( serial_type<=7 ){
    u64 v;
    int i;
    if( serial_type==7 ){
      v = *(u64*)&pMem->r;
    }else{
      v = *(u64*)&pMem->i;
    }
    len = i = sqlite3VdbeSerialTypeLen(serial_type);
    while( i-- ){
      buf[i] = (v&0xFF);
      v >>= 8;
    }
    return len;
  }
  
  /* String or blob */
  assert( serial_type>=12 );
  len = sqlite3VdbeSerialTypeLen(serial_type);
  memcpy(buf, pMem->z, len);
  return len;
}

/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem.  Return the number of bytes read.
*/ 
int sqlite3VdbeSerialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){
  int len;

  if( serial_type==0 ){
    /* NULL */
    pMem->flags = MEM_Null;
    return 0;
  }
  len = sqlite3VdbeSerialTypeLen(serial_type);
  if( serial_type<=7 ){
    /* Integer and Real */
    if( serial_type<=4 ){
      /* 32-bit integer type.  This is handled by a special case for
      ** performance reasons. */
      int v = buf[0];
      int n;
      if( v&0x80 ){
        v |= -256;
      }
      for(n=1; n<len; n++){
        v = (v<<8) | buf[n];
      }
      pMem->flags = MEM_Int;
      pMem->i = v;
      return n;
    }else{
      u64 v = 0;
      int n;

      if( buf[0]&0x80 ){
        v = -1;
      }
      for(n=0; n<len; n++){
        v = (v<<8) | buf[n];
      }
      if( serial_type==7 ){
        pMem->flags = MEM_Real;
        pMem->r = *(double*)&v;
      }else{
        pMem->flags = MEM_Int;
        pMem->i = *(i64*)&v;
      }
    }
  }else{
    /* String or blob */
    assert( serial_type>=12 );
    pMem->z = (char *)buf;
    pMem->n = len;
    pMem->xDel = 0;
    if( serial_type&0x01 ){
      pMem->flags = MEM_Str | MEM_Ephem;
    }else{
      pMem->flags = MEM_Blob | MEM_Ephem;
    }
  }
  return len;
}

/*
** This function compares the two table rows or index records specified by 
** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
** or positive integer if {nKey1, pKey1} is less than, equal to or 
** greater than {nKey2, pKey2}.  Both Key1 and Key2 must be byte strings
** composed by the OP_MakeRecord opcode of the VDBE.
*/
int sqlite3VdbeRecordCompare(
  void *userData,
  int nKey1, const void *pKey1, 
  int nKey2, const void *pKey2
){
  KeyInfo *pKeyInfo = (KeyInfo*)userData;
  u32 d1, d2;          /* Offset into aKey[] of next data element */
  u32 idx1, idx2;      /* Offset into aKey[] of next header element */
  u32 szHdr1, szHdr2;  /* Number of bytes in header */
  int i = 0;
  int nField;
  int rc = 0;
  const unsigned char *aKey1 = (const unsigned char *)pKey1;
  const unsigned char *aKey2 = (const unsigned char *)pKey2;

  Mem mem1;
  Mem mem2;
  mem1.enc = pKeyInfo->enc;
  mem2.enc = pKeyInfo->enc;
  
  idx1 = sqlite3GetVarint32(pKey1, &szHdr1);
  d1 = szHdr1;
  idx2 = sqlite3GetVarint32(pKey2, &szHdr2);
  d2 = szHdr2;
  nField = pKeyInfo->nField;
  while( idx1<szHdr1 && idx2<szHdr2 ){
    u32 serial_type1;
    u32 serial_type2;

    /* Read the serial types for the next element in each key. */
    idx1 += sqlite3GetVarint32(&aKey1[idx1], &serial_type1);
    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
    idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2);
    if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;

    /* Assert that there is enough space left in each key for the blob of
    ** data to go with the serial type just read. This assert may fail if
    ** the file is corrupted.  Then read the value from each key into mem1
    ** and mem2 respectively.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
    d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);

    rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
    sqlite3VdbeMemRelease(&mem1);
    sqlite3VdbeMemRelease(&mem2);
    if( rc!=0 ){
      break;
    }
    i++;
  }

  /* One of the keys ran out of fields, but all the fields up to that point
  ** were equal. If the incrKey flag is true, then the second key is
  ** treated as larger.
  */
  if( rc==0 ){
    if( pKeyInfo->incrKey ){
      rc = -1;
    }else if( d1<nKey1 ){
      rc = 1;
    }else if( d2<nKey2 ){
      rc = -1;
    }
  }

  if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){
    rc = -rc;
  }

  return rc;
}

/*
** The argument is an index entry composed using the OP_MakeRecord opcode.
** The last entry in this record should be an integer (specifically
** an integer rowid).  This routine returns the number of bytes in
** that integer.
*/
int sqlite3VdbeIdxRowidLen(int nKey, const u8 *aKey){
  u32 szHdr;        /* Size of the header */
  u32 typeRowid;    /* Serial type of the rowid */

  sqlite3GetVarint32(aKey, &szHdr);
  sqlite3GetVarint32(&aKey[szHdr-1], &typeRowid);
  return sqlite3VdbeSerialTypeLen(typeRowid);
}
  

/*
** pCur points at an index entry created using the OP_MakeRecord opcode.
** Read the rowid (the last field in the record) and store it in *rowid.
** Return SQLITE_OK if everything works, or an error code otherwise.
*/
int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
  i64 nCellKey;
  int rc;
  u32 szHdr;        /* Size of the header */
  u32 typeRowid;    /* Serial type of the rowid */
  u32 lenRowid;     /* Size of the rowid */
  Mem m, v;

  sqlite3BtreeKeySize(pCur, &nCellKey);
  if( nCellKey<=0 ){
    return SQLITE_CORRUPT;
  }
  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  sqlite3GetVarint32(m.z, &szHdr);
  sqlite3GetVarint32(&m.z[szHdr-1], &typeRowid);
  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
  sqlite3VdbeSerialGet(&m.z[m.n-lenRowid], typeRowid, &v);
  *rowid = v.i;
  sqlite3VdbeMemRelease(&m);
  return SQLITE_OK;
}

/*
** Compare the key of the index entry that cursor pC is point to against
** the key string in pKey (of length nKey).  Write into *pRes a number
** that is negative, zero, or positive if pC is less than, equal to,
** or greater than pKey.  Return SQLITE_OK on success.
**
** pKey is either created without a rowid or is truncated so that it
** omits the rowid at the end.  The rowid at the end of the index entry
** is ignored as well.
*/
int sqlite3VdbeIdxKeyCompare(
  Cursor *pC,                 /* The cursor to compare against */
  int nKey, const u8 *pKey,   /* The key to compare */
  int *res                    /* Write the comparison result here */
){
  i64 nCellKey;
  int rc;
  BtCursor *pCur = pC->pCursor;
  int lenRowid;
  Mem m;

  sqlite3BtreeKeySize(pCur, &nCellKey);
  if( nCellKey<=0 ){
    *res = 0;
    return SQLITE_OK;
  }
  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z);
  *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
  sqlite3VdbeMemRelease(&m);
  return SQLITE_OK;
}

/*
** This routine sets the value to be returned by subsequent calls to
** sqlite3_changes() on the database handle 'db'. 
*/
void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
  db->nChange = nChange;
  db->nTotalChange += nChange;
}

/*
** Set a flag in the vdbe to update the change counter when it is finalised
** or reset.
*/
void sqlite3VdbeCountChanges(Vdbe *v){
  v->changeCntOn = 1;
}

/*
** Mark every prepared statement associated with a database connection
** as expired.
**
** An expired statement means that recompilation of the statement is
** recommend.  Statements expire when things happen that make their
** programs obsolete.  Removing user-defined functions or collating
** sequences, or changing an authorization function are the types of
** things that make prepared statements obsolete.
*/
void sqlite3ExpirePreparedStatements(sqlite3 *db){
  Vdbe *p;
  for(p = db->pVdbe; p; p=p->pNext){
    p->expired = 1;
  }
}
Added SQLite.Interop/src/vdbemem.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
/*
** 2004 May 26
**
** 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 file contains code use to manipulate "Mem" structure.  A "Mem"
** stores a single value in the VDBE.  Mem is an opaque structure visible
** only within the VDBE.  Interface routines refer to a Mem using the
** name sqlite_value
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** If pMem is an object with a valid string representation, this routine
** ensures the internal encoding for the string representation is
** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE.
**
** If pMem is not a string object, or the encoding of the string
** representation is already stored using the requested encoding, then this
** routine is a no-op.
**
** SQLITE_OK is returned if the conversion is successful (or not required).
** SQLITE_NOMEM may be returned if a malloc() fails during conversion
** between formats.
*/
int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
  int rc;
  if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
    return SQLITE_OK;
  }
#ifdef SQLITE_OMIT_UTF16
  return SQLITE_ERROR;
#else
  rc = sqlite3VdbeMemTranslate(pMem, desiredEnc);
  if( rc==SQLITE_NOMEM ){
    sqlite3VdbeMemRelease(pMem);
    pMem->flags = MEM_Null;
    pMem->z = 0;
  }
  return rc;
#endif
}

/*
** Make the given Mem object MEM_Dyn.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemDynamicify(Mem *pMem){
  int n = pMem->n;
  u8 *z;
  if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){
    return SQLITE_OK;
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  assert( pMem->flags & (MEM_Str|MEM_Blob) );
  z = sqliteMallocRaw( n+2 );
  if( z==0 ){
    return SQLITE_NOMEM;
  }
  pMem->flags |= MEM_Dyn|MEM_Term;
  pMem->xDel = 0;
  memcpy(z, pMem->z, n );
  z[n] = 0;
  z[n+1] = 0;
  pMem->z = z;
  pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short);
  return SQLITE_OK;
}

/*
** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes
** of the Mem.z[] array can be modified.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
  int n;
  u8 *z;
  if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
    return SQLITE_OK;
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  assert( pMem->flags & (MEM_Str|MEM_Blob) );
  if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
    z = pMem->zShort;
    pMem->flags |= MEM_Short|MEM_Term;
  }else{
    z = sqliteMallocRaw( n+2 );
    if( z==0 ){
      return SQLITE_NOMEM;
    }
    pMem->flags |= MEM_Dyn|MEM_Term;
    pMem->xDel = 0;
  }
  memcpy(z, pMem->z, n );
  z[n] = 0;
  z[n+1] = 0;
  pMem->z = z;
  pMem->flags &= ~(MEM_Ephem|MEM_Static);
  return SQLITE_OK;
}

/*
** Make sure the given Mem is \u0000 terminated.
*/
int sqlite3VdbeMemNulTerminate(Mem *pMem){
  /* In SQLite, a string without a nul terminator occurs when a string
  ** is loaded from disk (in this case the memory management is ephemeral),
  ** or when it is supplied by the user as a bound variable or function
  ** return value. Therefore, the memory management of the string must be
  ** either ephemeral, static or controlled by a user-supplied destructor.
  */
  assert(                         
    !(pMem->flags&MEM_Str) ||                /* it's not a string, or      */
    (pMem->flags&MEM_Term) ||                /* it's nul term. already, or */
    (pMem->flags&(MEM_Ephem|MEM_Static)) ||  /* it's static or ephem, or   */
    (pMem->flags&MEM_Dyn && pMem->xDel)      /* external management        */
  );
  if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
    return SQLITE_OK;   /* Nothing to do */
  }

  if( pMem->flags & (MEM_Static|MEM_Ephem) ){
    return sqlite3VdbeMemMakeWriteable(pMem);
  }else{
    char *z = sqliteMalloc(pMem->n+2);
    if( !z ) return SQLITE_NOMEM;
    memcpy(z, pMem->z, pMem->n);
    z[pMem->n] = 0;
    z[pMem->n+1] = 0;
    pMem->xDel(pMem->z);
    pMem->xDel = 0;
    pMem->z = z;
  }
  return SQLITE_OK;
}

/*
** Add MEM_Str to the set of representations for the given Mem.  Numbers
** are converted using sqlite3_snprintf().  Converting a BLOB to a string
** is a no-op.
**
** Existing representations MEM_Int and MEM_Real are *not* invalidated.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
** sqlite3_value_text()), or for ensuring that values to be used as btree
** keys are strings. In the former case a NULL pointer is returned the
** user and the later is an internal programming error.
*/
int sqlite3VdbeMemStringify(Mem *pMem, int enc){
  int rc = SQLITE_OK;
  int fg = pMem->flags;
  u8 *z = pMem->zShort;

  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );

  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
  ** string representation of the value. Then, if the required encoding
  ** is UTF-16le or UTF-16be do a translation.
  ** 
  ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
  */
  if( fg & MEM_Real ){
    sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
  }else{
    assert( fg & MEM_Int );
    sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
  }
  pMem->n = strlen(z);
  pMem->z = z;
  pMem->enc = SQLITE_UTF8;
  pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
  sqlite3VdbeChangeEncoding(pMem, enc);
  return rc;
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
*/
void sqlite3VdbeMemRelease(Mem *p){
  if( p->flags & MEM_Dyn ){
    if( p->xDel ){
      p->xDel((void *)p->z);
    }else{
      sqliteFree(p->z);
    }
    p->z = 0;
    p->xDel = 0;
  }
}

/*
** Return some kind of integer value which is the best we can do
** at representing the value that *pMem describes as an integer.
** If pMem is an integer, then the value is exact.  If pMem is
** a floating-point then the value returned is the integer part.
** If pMem is a string or blob, then we make an attempt to convert
** it into a integer and return that.  If pMem is NULL, return 0.
**
** If pMem is a string, its encoding might be changed.
*/
i64 sqlite3VdbeIntValue(Mem *pMem){
  int flags = pMem->flags;
  if( flags & MEM_Int ){
    return pMem->i;
  }else if( flags & MEM_Real ){
    return (i64)pMem->r;
  }else if( flags & (MEM_Str|MEM_Blob) ){
    i64 value;
    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
       || sqlite3VdbeMemNulTerminate(pMem) ){
      return SQLITE_NOMEM;
    }
    assert( pMem->z );
    sqlite3atoi64(pMem->z, &value);
    return value;
  }else{
    return 0;
  }
}

/*
** Convert pMem to type integer.  Invalidate any prior representations.
*/
int sqlite3VdbeMemIntegerify(Mem *pMem){
  pMem->i = sqlite3VdbeIntValue(pMem);
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Int;
  return SQLITE_OK;
}

/*
** Return the best representation of pMem that we can get into a
** double.  If pMem is already a double or an integer, return its
** value.  If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.
*/
double sqlite3VdbeRealValue(Mem *pMem){
  if( pMem->flags & MEM_Real ){
    return pMem->r;
  }else if( pMem->flags & MEM_Int ){
    return (double)pMem->i;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
       || sqlite3VdbeMemNulTerminate(pMem) ){
      return SQLITE_NOMEM;
    }
    assert( pMem->z );
    return sqlite3AtoF(pMem->z, 0);
  }else{
    return 0.0;
  }
}

/*
** Convert pMem so that it is of type MEM_Real.  Invalidate any
** prior representations.
*/
int sqlite3VdbeMemRealify(Mem *pMem){
  pMem->r = sqlite3VdbeRealValue(pMem);
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Real;
  return SQLITE_OK;
}

/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Null;
  pMem->type = SQLITE_NULL;
}

/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
  sqlite3VdbeMemRelease(pMem);
  pMem->i = val;
  pMem->flags = MEM_Int;
  pMem->type = SQLITE_INTEGER;
}

/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type REAL.
*/
void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
  sqlite3VdbeMemRelease(pMem);
  pMem->r = val;
  pMem->flags = MEM_Real;
  pMem->type = SQLITE_FLOAT;
}

/*
** Make an shallow copy of pFrom into pTo.  Prior contents of
** pTo are overwritten.  The pFrom->z field is not duplicated.  If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
  memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort));
  pTo->xDel = 0;
  if( pTo->flags & (MEM_Str|MEM_Blob) ){
    pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short|MEM_Ephem);
    assert( srcType==MEM_Ephem || srcType==MEM_Static );
    pTo->flags |= srcType;
  }
}

/*
** Make a full copy of pFrom into pTo.  Prior contents of pTo are
** freed before the copy is made.
*/
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
  int rc;
  if( pTo->flags & MEM_Dyn ){
    sqlite3VdbeMemRelease(pTo);
  }
  sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem);
  if( pTo->flags & MEM_Ephem ){
    rc = sqlite3VdbeMemMakeWriteable(pTo);
  }else{
    rc = SQLITE_OK;
  }
  return rc;
}

/*
** Transfer the contents of pFrom to pTo. Any existing value in pTo is
** freed. If pFrom contains ephemeral data, a copy is made.
**
** pFrom contains an SQL NULL when this routine returns.  SQLITE_NOMEM
** might be returned if pFrom held ephemeral data and we were unable
** to allocate enough space to make a copy.
*/
int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
  int rc;
  if( pTo->flags & MEM_Dyn ){
    sqlite3VdbeMemRelease(pTo);
  }
  memcpy(pTo, pFrom, sizeof(Mem));
  if( pFrom->flags & MEM_Short ){
    pTo->z = pTo->zShort;
  }
  pFrom->flags = MEM_Null;
  pFrom->xDel = 0;
  if( pTo->flags & MEM_Ephem ){
    rc = sqlite3VdbeMemMakeWriteable(pTo);
  }else{
    rc = SQLITE_OK;
  }
  return rc;
}

/*
** Change the value of a Mem to be a string or a BLOB.
*/
int sqlite3VdbeMemSetStr(
  Mem *pMem,          /* Memory cell to set to string value */
  const char *z,      /* String pointer */
  int n,              /* Bytes in string, or negative */
  u8 enc,             /* Encoding of z.  0 for BLOBs */
  void (*xDel)(void*) /* Destructor function */
){
  sqlite3VdbeMemRelease(pMem);
  if( !z ){
    pMem->flags = MEM_Null;
    pMem->type = SQLITE_NULL;
    return SQLITE_OK;
  }

  pMem->z = (char *)z;
  if( xDel==SQLITE_STATIC ){
    pMem->flags = MEM_Static;
  }else if( xDel==SQLITE_TRANSIENT ){
    pMem->flags = MEM_Ephem;
  }else{
    pMem->flags = MEM_Dyn;
    pMem->xDel = xDel;
  }

  pMem->enc = enc;
  pMem->type = enc==0 ? SQLITE_BLOB : SQLITE_TEXT;
  pMem->n = n;

  assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE 
      || enc==SQLITE_UTF16BE );
  switch( enc ){
    case 0:
      pMem->flags |= MEM_Blob;
      break;

    case SQLITE_UTF8:
      pMem->flags |= MEM_Str;
      if( n<0 ){
        pMem->n = strlen(z);
        pMem->flags |= MEM_Term;
      }
      break;

#ifndef SQLITE_OMIT_UTF16
    case SQLITE_UTF16LE:
    case SQLITE_UTF16BE:
      pMem->flags |= MEM_Str;
      if( pMem->n<0 ){
        pMem->n = sqlite3utf16ByteLen(pMem->z,-1);
        pMem->flags |= MEM_Term;
      }
      if( sqlite3VdbeMemHandleBom(pMem) ){
        return SQLITE_NOMEM;
      }
#endif /* SQLITE_OMIT_UTF16 */
  }
  if( pMem->flags&MEM_Ephem ){
    return sqlite3VdbeMemMakeWriteable(pMem);
  }
  return SQLITE_OK;
}

/*
** Compare the values contained by the two memory cells, returning
** negative, zero or positive if pMem1 is less than, equal to, or greater
** than pMem2. Sorting order is NULL's first, followed by numbers (integers
** and reals) sorted numerically, followed by text ordered by the collating
** sequence pColl and finally blob's ordered by memcmp().
**
** Two NULL values are considered equal by this function.
*/
int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
  int rc;
  int f1, f2;
  int combined_flags;

  /* Interchange pMem1 and pMem2 if the collating sequence specifies
  ** DESC order.
  */
  f1 = pMem1->flags;
  f2 = pMem2->flags;
  combined_flags = f1|f2;
 
  /* If one value is NULL, it is less than the other. If both values
  ** are NULL, return 0.
  */
  if( combined_flags&MEM_Null ){
    return (f2&MEM_Null) - (f1&MEM_Null);
  }

  /* If one value is a number and the other is not, the number is less.
  ** If both are numbers, compare as reals if one is a real, or as integers
  ** if both values are integers.
  */
  if( combined_flags&(MEM_Int|MEM_Real) ){
    if( !(f1&(MEM_Int|MEM_Real)) ){
      return 1;
    }
    if( !(f2&(MEM_Int|MEM_Real)) ){
      return -1;
    }
    if( (f1 & f2 & MEM_Int)==0 ){
      double r1, r2;
      if( (f1&MEM_Real)==0 ){
        r1 = pMem1->i;
      }else{
        r1 = pMem1->r;
      }
      if( (f2&MEM_Real)==0 ){
        r2 = pMem2->i;
      }else{
        r2 = pMem2->r;
      }
      if( r1<r2 ) return -1;
      if( r1>r2 ) return 1;
      return 0;
    }else{
      assert( f1&MEM_Int );
      assert( f2&MEM_Int );
      if( pMem1->i < pMem2->i ) return -1;
      if( pMem1->i > pMem2->i ) return 1;
      return 0;
    }
  }

  /* If one value is a string and the other is a blob, the string is less.
  ** If both are strings, compare using the collating functions.
  */
  if( combined_flags&MEM_Str ){
    if( (f1 & MEM_Str)==0 ){
      return 1;
    }
    if( (f2 & MEM_Str)==0 ){
      return -1;
    }

    assert( pMem1->enc==pMem2->enc );
    assert( pMem1->enc==SQLITE_UTF8 || 
            pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );

    /* This assert may fail if the collation sequence is deleted after this
    ** vdbe program is compiled. The documentation defines this as an
    ** undefined condition. A crash is usual result.
    */
    assert( !pColl || pColl->xCmp );

    if( pColl ){
      if( pMem1->enc==pColl->enc ){
        return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
      }else{
        u8 origEnc = pMem1->enc;
        rc = pColl->xCmp(
          pColl->pUser,
          sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc),
          sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc),
          sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc),
          sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc)
        );
        sqlite3ValueBytes((sqlite3_value*)pMem1, origEnc);
        sqlite3ValueText((sqlite3_value*)pMem1, origEnc);
        sqlite3ValueBytes((sqlite3_value*)pMem2, origEnc);
        sqlite3ValueText((sqlite3_value*)pMem2, origEnc);
        return rc;
      }
    }
    /* If a NULL pointer was passed as the collate function, fall through
    ** to the blob case and use memcmp().  */
  }
 
  /* Both values must be blobs.  Compare using memcmp().  */
  rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
  if( rc==0 ){
    rc = pMem1->n - pMem2->n;
  }
  return rc;
}

/*
** Move data out of a btree key or data field and into a Mem structure.
** The data or key is taken from the entry that pCur is currently pointing
** to.  offset and amt determine what portion of the data or key to retrieve.
** key is true to get the key or false to get data.  The result is written
** into the pMem element.
**
** The pMem structure is assumed to be uninitialized.  Any prior content
** is overwritten without being freed.
**
** If this routine fails for any reason (malloc returns NULL or unable
** to read from the disk) then the pMem is left in an inconsistent state.
*/
int sqlite3VdbeMemFromBtree(
  BtCursor *pCur,   /* Cursor pointing at record to retrieve. */
  int offset,       /* Offset from the start of data to return bytes from. */
  int amt,          /* Number of bytes to return. */
  int key,          /* If true, retrieve from the btree key, not data. */
  Mem *pMem         /* OUT: Return data in this Mem structure. */
){
  char *zData;      /* Data from the btree layer */
  int available;    /* Number of bytes available on the local btree page */

  if( key ){
    zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
  }else{
    zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
  }

  pMem->n = amt;
  if( offset+amt<=available ){
    pMem->z = &zData[offset];
    pMem->flags = MEM_Blob|MEM_Ephem;
  }else{
    int rc;
    if( amt>NBFS-2 ){
      zData = (char *)sqliteMallocRaw(amt+2);
      if( !zData ){
        return SQLITE_NOMEM;
      }
      pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
      pMem->xDel = 0;
    }else{
      zData = &(pMem->zShort[0]);
      pMem->flags = MEM_Blob|MEM_Short|MEM_Term;
    }
    pMem->z = zData;
    pMem->enc = 0;
    pMem->type = SQLITE_BLOB;

    if( key ){
      rc = sqlite3BtreeKey(pCur, offset, amt, zData);
    }else{
      rc = sqlite3BtreeData(pCur, offset, amt, zData);
    }
    zData[amt] = 0;
    zData[amt+1] = 0;
    if( rc!=SQLITE_OK ){
      if( amt>NBFS ){
        sqliteFree(zData);
      }
      return rc;
    }
  }

  return SQLITE_OK;
}

#ifndef NDEBUG
/*
** Perform various checks on the memory cell pMem. An assert() will
** fail if pMem is internally inconsistent.
*/
void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){
  int flags = pMem->flags;
  assert( flags!=0 );  /* Must define some type */
  if( pMem->flags & (MEM_Str|MEM_Blob) ){
    int x = pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
    assert( x!=0 );            /* Strings must define a string subtype */
    assert( (x & (x-1))==0 );  /* Only one string subtype can be defined */
    assert( pMem->z!=0 );      /* Strings must have a value */
    /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
    assert( (pMem->flags & MEM_Short)==0 || pMem->z==pMem->zShort );
    assert( (pMem->flags & MEM_Short)!=0 || pMem->z!=pMem->zShort );
    /* No destructor unless there is MEM_Dyn */
    assert( pMem->xDel==0 || (pMem->flags & MEM_Dyn)!=0 );

    if( (flags & MEM_Str) ){
      assert( pMem->enc==SQLITE_UTF8 || 
              pMem->enc==SQLITE_UTF16BE ||
              pMem->enc==SQLITE_UTF16LE 
      );
      /* If the string is UTF-8 encoded and nul terminated, then pMem->n
      ** must be the length of the string.  (Later:)  If the database file
      ** has been corrupted, '\000' characters might have been inserted
      ** into the middle of the string.  In that case, the strlen() might
      ** be less.
      */
      if( pMem->enc==SQLITE_UTF8 && (flags & MEM_Term) ){ 
        assert( strlen(pMem->z)<=pMem->n );
        assert( pMem->z[pMem->n]==0 );
      }
    }
  }else{
    /* Cannot define a string subtype for non-string objects */
    assert( (pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
    assert( pMem->xDel==0 );
  }
  /* MEM_Null excludes all other types */
  assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
          || (pMem->flags&MEM_Null)==0 );
  if( (pMem->flags & (MEM_Int|MEM_Real))==(MEM_Int|MEM_Real) ){
    assert( pMem->r==pMem->i );
  }
}
#endif

/* This function is only available internally, it is not part of the
** external API. It works in a similar way to sqlite3_value_text(),
** except the data returned is in the encoding specified by the second
** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
** SQLITE_UTF8.
*/
const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
  if( !pVal ) return 0;
  assert( enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE || enc==SQLITE_UTF8);

  if( pVal->flags&MEM_Null ){
    return 0;
  }
  if( pVal->flags&MEM_Str ){
    sqlite3VdbeChangeEncoding(pVal, enc);
  }else if( !(pVal->flags&MEM_Blob) ){
    sqlite3VdbeMemStringify(pVal, enc);
  }
  return (const void *)(pVal->z);
}

/*
** Create a new sqlite3_value object.
*/
sqlite3_value* sqlite3ValueNew(){
  Mem *p = sqliteMalloc(sizeof(*p));
  if( p ){
    p->flags = MEM_Null;
    p->type = SQLITE_NULL;
  }
  return p;
}

/*
** Change the string value of an sqlite3_value object
*/
void sqlite3ValueSetStr(
  sqlite3_value *v, 
  int n, 
  const void *z, 
  u8 enc,
  void (*xDel)(void*)
){
  if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel);
}

/*
** Free an sqlite3_value object
*/
void sqlite3ValueFree(sqlite3_value *v){
  if( !v ) return;
  sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
  sqliteFree(v);
}

/*
** Return the number of bytes in the sqlite3_value object assuming
** that it uses the encoding "enc"
*/
int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
  Mem *p = (Mem*)pVal;
  if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
    return p->n;
  }
  return 0;
}
Added SQLite.Interop/src/where.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
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
/*
** 2001 September 15
**
** 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 module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.1 2005/03/01 16:04:39 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
**
** The idxLeft and idxRight fields are the VDBE cursor numbers for the
** table that contains the column that appears on the left-hand and
** right-hand side of ExprInfo.p.  If either side of ExprInfo.p is
** something other than a simple column reference, then idxLeft or
** idxRight are -1.  
**
** It is the VDBE cursor number is the value stored in Expr.iTable
** when Expr.op==TK_COLUMN and the value stored in SrcList.a[].iCursor.
**
** prereqLeft, prereqRight, and prereqAll record sets of cursor numbers,
** but they do so indirectly.  A single ExprMaskSet structure translates
** cursor number into bits and the translated bit is stored in the prereq
** fields.  The translation is used in order to maximize the number of
** bits that will fit in a Bitmask.  The VDBE cursor numbers might be
** spread out over the non-negative integers.  For example, the cursor
** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45.  The ExprMaskSet
** translates these sparse cursor numbers into consecutive integers
** beginning with 0 in order to make the best possible use of the available
** bits in the Bitmask.  So, in the example above, the cursor numbers
** would be mapped into integers 0 through 7.
**
** prereqLeft tells us every VDBE cursor that is referenced on the
** left-hand side of ExprInfo.p.  prereqRight does the same for the
** right-hand side of the expression.  The following identity always
** holds:
**
**       prereqAll = prereqLeft | prereqRight
**
** The ExprInfo.indexable field is true if the ExprInfo.p expression
** is of a form that might control an index.  Indexable expressions
** look like this:
**
**              <column> <op> <expr>
**
** Where <column> is a simple column name and <op> is on of the operators
** that allowedOp() recognizes.  
*/
typedef struct ExprInfo ExprInfo;
struct ExprInfo {
  Expr *p;                /* Pointer to the subexpression */
  u8 indexable;           /* True if this subexprssion is usable by an index */
  short int idxLeft;      /* p->pLeft is a column in this table number. -1 if
                          ** p->pLeft is not the column of any table */
  short int idxRight;     /* p->pRight is a column in this table number. -1 if
                          ** p->pRight is not the column of any table */
  Bitmask prereqLeft;     /* Bitmask of tables referenced by p->pLeft */
  Bitmask prereqRight;    /* Bitmask of tables referenced by p->pRight */
  Bitmask prereqAll;      /* Bitmask of tables referenced by p */
};

/*
** An instance of the following structure keeps track of a mapping
** between VDBE cursor numbers and bits of the bitmasks in ExprInfo.
**
** The VDBE cursor numbers are small integers contained in 
** SrcList_item.iCursor and Expr.iTable fields.  For any given WHERE 
** clause, the cursor numbers might not begin with 0 and they might
** contain gaps in the numbering sequence.  But we want to make maximum
** use of the bits in our bitmasks.  This structure provides a mapping
** from the sparse cursor numbers into consecutive integers beginning
** with 0.
**
** If ExprMaskSet.ix[A]==B it means that The A-th bit of a Bitmask
** corresponds VDBE cursor number B.  The A-th bit of a bitmask is 1<<A.
**
** For example, if the WHERE clause expression used these VDBE
** cursors:  4, 5, 8, 29, 57, 73.  Then the  ExprMaskSet structure
** would map those cursor numbers into bits 0 through 5.
**
** Note that the mapping is not necessarily ordered.  In the example
** above, the mapping might go like this:  4->3, 5->1, 8->2, 29->0,
** 57->5, 73->4.  Or one of 719 other combinations might be used. It
** does not really matter.  What is important is that sparse cursor
** numbers all get mapped into bit numbers that begin with 0 and contain
** no gaps.
*/
typedef struct ExprMaskSet ExprMaskSet;
struct ExprMaskSet {
  int n;                        /* Number of assigned cursor values */
  int ix[sizeof(Bitmask)*8];    /* Cursor assigned to each bit */
};

/*
** Determine the number of elements in an array.
*/
#define ARRAYSIZE(X)  (sizeof(X)/sizeof(X[0]))

/*
** This routine identifies subexpressions in the WHERE clause where
** each subexpression is separate by the AND operator.  aSlot is 
** filled with pointers to the subexpressions.  For example:
**
**    WHERE  a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
**           \________/     \_______________/     \________________/
**            slot[0]            slot[1]               slot[2]
**
** The original WHERE clause in pExpr is unaltered.  All this routine
** does is make aSlot[] entries point to substructure within pExpr.
**
** aSlot[] is an array of subexpressions structures.  There are nSlot
** spaces left in this array.  This routine finds as many AND-separated
** subexpressions as it can and puts pointers to those subexpressions
** into aSlot[] entries.  The return value is the number of slots filled.
*/
static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){
  int cnt = 0;
  if( pExpr==0 || nSlot<1 ) return 0;
  if( nSlot==1 || pExpr->op!=TK_AND ){
    aSlot[0].p = pExpr;
    return 1;
  }
  if( pExpr->pLeft->op!=TK_AND ){
    aSlot[0].p = pExpr->pLeft;
    cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight);
  }else{
    cnt = exprSplit(nSlot, aSlot, pExpr->pLeft);
    cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight);
  }
  return cnt;
}

/*
** Initialize an expression mask set
*/
#define initMaskSet(P)  memset(P, 0, sizeof(*P))

/*
** Return the bitmask for the given cursor number.  Return 0 if
** iCursor is not in the set.
*/
static Bitmask getMask(ExprMaskSet *pMaskSet, int iCursor){
  int i;
  for(i=0; i<pMaskSet->n; i++){
    if( pMaskSet->ix[i]==iCursor ){
      return ((Bitmask)1)<<i;
    }
  }
  return 0;
}

/*
** Create a new mask for cursor iCursor.
*/
static void createMask(ExprMaskSet *pMaskSet, int iCursor){
  if( pMaskSet->n<ARRAYSIZE(pMaskSet->ix) ){
    pMaskSet->ix[pMaskSet->n++] = iCursor;
  }
}

/*
** Destroy an expression mask set
*/
#define freeMaskSet(P)   /* NO-OP */

/*
** This routine walks (recursively) an expression tree and generates
** a bitmask indicating which tables are used in that expression
** tree.
**
** In order for this routine to work, the calling function must have
** previously invoked sqlite3ExprResolveNames() on the expression.  See
** the header comment on that routine for additional information.
** The sqlite3ExprResolveNames() routines looks for column names and
** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
** the VDBE cursor number of the table.
*/
static Bitmask exprListTableUsage(ExprMaskSet *, ExprList *);
static Bitmask exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
  Bitmask mask = 0;
  if( p==0 ) return 0;
  if( p->op==TK_COLUMN ){
    mask = getMask(pMaskSet, p->iTable);
    return mask;
  }
  mask = exprTableUsage(pMaskSet, p->pRight);
  mask |= exprTableUsage(pMaskSet, p->pLeft);
  mask |= exprListTableUsage(pMaskSet, p->pList);
  if( p->pSelect ){
    Select *pS = p->pSelect;
    mask |= exprListTableUsage(pMaskSet, pS->pEList);
    mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
    mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
    mask |= exprTableUsage(pMaskSet, pS->pWhere);
    mask |= exprTableUsage(pMaskSet, pS->pHaving);
  }
  return mask;
}
static Bitmask exprListTableUsage(ExprMaskSet *pMaskSet, ExprList *pList){
  int i;
  Bitmask mask = 0;
  if( pList ){
    for(i=0; i<pList->nExpr; i++){
      mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
    }
  }
  return mask;
}

/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", and "IN".
*/
static int allowedOp(int op){
  assert( TK_GT==TK_LE-1 && TK_LE==TK_LT-1 && TK_LT==TK_GE-1 && TK_EQ==TK_GT-1);
  return op==TK_IN || (op>=TK_EQ && op<=TK_GE);
}

/*
** Swap two objects of type T.
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Return the index in the SrcList that uses cursor iCur.  If iCur is
** used by the first entry in SrcList return 0.  If iCur is used by
** the second entry return 1.  And so forth.
**
** SrcList is the set of tables in the FROM clause in the order that
** they will be processed.  The value returned here gives us an index
** of which tables will be processed first.
*/
static int tableOrder(SrcList *pList, int iCur){
  int i;
  struct SrcList_item *pItem;
  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pItem->iCursor==iCur ) return i;
  }
  return -1;
}

/*
** The input to this routine is an ExprInfo structure with only the
** "p" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the ExprInfo
** structure.
*/
static void exprAnalyze(SrcList *pSrc, ExprMaskSet *pMaskSet, ExprInfo *pInfo){
  Expr *pExpr = pInfo->p;
  pInfo->prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
  pInfo->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
  pInfo->prereqAll = exprTableUsage(pMaskSet, pExpr);
  pInfo->indexable = 0;
  pInfo->idxLeft = -1;
  pInfo->idxRight = -1;
  if( allowedOp(pExpr->op) && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){
    if( pExpr->pRight && pExpr->pRight->op==TK_COLUMN ){
      pInfo->idxRight = pExpr->pRight->iTable;
      pInfo->indexable = 1;
    }
    if( pExpr->pLeft->op==TK_COLUMN ){
      pInfo->idxLeft = pExpr->pLeft->iTable;
      pInfo->indexable = 1;
    }
  }
  if( pInfo->indexable ){
    assert( pInfo->idxLeft!=pInfo->idxRight );

    /* We want the expression to be of the form "X = expr", not "expr = X".
    ** So flip it over if necessary.  If the expression is "X = Y", then
    ** we want Y to come from an earlier table than X.
    **
    ** The collating sequence rule is to always choose the left expression.
    ** So if we do a flip, we also have to move the collating sequence.
    */
    if( tableOrder(pSrc,pInfo->idxLeft)<tableOrder(pSrc,pInfo->idxRight) ){
      assert( pExpr->op!=TK_IN );
      SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
      SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
      if( pExpr->op>=TK_GT ){
        assert( TK_LT==TK_GT+2 );
        assert( TK_GE==TK_LE+2 );
        assert( TK_GT>TK_EQ );
        assert( TK_GT<TK_LE );
        assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
        pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
      }
      SWAP(unsigned, pInfo->prereqLeft, pInfo->prereqRight);
      SWAP(short int, pInfo->idxLeft, pInfo->idxRight);
    }
  }      

}

/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
** clause.  If it can, it returns 1.  If pIdx cannot satisfy the
** ORDER BY clause, this routine returns 0.
**
** pOrderBy is an ORDER BY clause from a SELECT statement.  pTab is the
** left-most table in the FROM clause of that same SELECT statement and
** the table has a cursor number of "base".  pIdx is an index on pTab.
**
** nEqCol is the number of columns of pIdx that are used as equality
** constraints.  Any of these columns may be missing from the ORDER BY
** clause and the match can still be a success.
**
** If the index is UNIQUE, then the ORDER BY clause is allowed to have
** additional terms past the end of the index and the match will still
** be a success.
**
** All terms of the ORDER BY that match against the index must be either
** ASC or DESC.  (Terms of the ORDER BY clause past the end of a UNIQUE
** index do not need to satisfy this constraint.)  The *pbRev value is
** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
** the ORDER BY clause is all ASC.
*/
static int isSortingIndex(
  Parse *pParse,          /* Parsing context */
  Index *pIdx,            /* The index we are testing */
  Table *pTab,            /* The table to be sorted */
  int base,               /* Cursor number for pTab */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int nEqCol,             /* Number of index columns with == constraints */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  int i, j;                    /* Loop counters */
  int sortOrder;               /* Which direction we are sorting */
  int nTerm;                   /* Number of ORDER BY terms */
  struct ExprList_item *pTerm; /* A term of the ORDER BY clause */
  sqlite3 *db = pParse->db;

  assert( pOrderBy!=0 );
  nTerm = pOrderBy->nExpr;
  assert( nTerm>0 );

  /* Match terms of the ORDER BY clause against columns of
  ** the index.
  */
  for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<pIdx->nColumn; i++){
    Expr *pExpr;       /* The expression of the ORDER BY pTerm */
    CollSeq *pColl;    /* The collating sequence of pExpr */

    pExpr = pTerm->pExpr;
    if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
      /* Can not use an index sort on anything that is not a column in the
      ** left-most table of the FROM clause */
      return 0;
    }
    pColl = sqlite3ExprCollSeq(pParse, pExpr);
    if( !pColl ) pColl = db->pDfltColl;
    if( pExpr->iColumn!=pIdx->aiColumn[i] || pColl!=pIdx->keyInfo.aColl[i] ){
      /* Term j of the ORDER BY clause does not match column i of the index */
      if( i<nEqCol ){
        /* If an index column that is constrained by == fails to match an
        ** ORDER BY term, that is OK.  Just ignore that column of the index
        */
        continue;
      }else{
        /* If an index column fails to match and is not constrained by ==
        ** then the index cannot satisfy the ORDER BY constraint.
        */
        return 0;
      }
    }
    if( i>nEqCol ){
      if( pTerm->sortOrder!=sortOrder ){
        /* Indices can only be used if all ORDER BY terms past the
        ** equality constraints are all either DESC or ASC. */
        return 0;
      }
    }else{
      sortOrder = pTerm->sortOrder;
    }
    j++;
    pTerm++;
  }

  /* The index can be used for sorting if all terms of the ORDER BY clause
  ** or covered or if we ran out of index columns and the it is a UNIQUE
  ** index.
  */
  if( j>=nTerm || (i>=pIdx->nColumn && pIdx->onError!=OE_None) ){
    *pbRev = sortOrder==SQLITE_SO_DESC;
    return 1;
  }
  return 0;
}

/*
** Check table to see if the ORDER BY clause in pOrderBy can be satisfied
** by sorting in order of ROWID.  Return true if so and set *pbRev to be
** true for reverse ROWID and false for forward ROWID order.
*/
static int sortableByRowid(
  int base,               /* Cursor number for table to be sorted */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  Expr *p;

  assert( pOrderBy!=0 );
  assert( pOrderBy->nExpr>0 );
  p = pOrderBy->a[0].pExpr;
  if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1 ){
    *pbRev = pOrderBy->a[0].sortOrder;
    return 1;
  }
  return 0;
}


/*
** Disable a term in the WHERE clause.  Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:
**
**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
**
** The t2.z='ok' is disabled in the in (2) because it originates
** in the ON clause.  The term is disabled in (3) because it is not part
** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
**
** Disabling a term causes that term to not be tested in the inner loop
** of the join.  Disabling is an optimization.  We would get the correct
** results if nothing were ever disabled, but joins might run a little
** slower.  The trick is to disable as much as we can without disabling
** too much.  If we disabled in (1), we'd get the wrong answer.
** See ticket #813.
*/
static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){
  Expr *pExpr = *ppExpr;
  if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){
    *ppExpr = 0;
  }
}

/*
** Generate code that builds a probe for an index.  Details:
**
**    *  Check the top nColumn entries on the stack.  If any
**       of those entries are NULL, jump immediately to brk,
**       which is the loop exit, since no index entry will match
**       if any part of the key is NULL.
**
**    *  Construct a probe entry from the top nColumn entries in
**       the stack with affinities appropriate for index pIdx.
*/
static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){
  sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
  sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
  sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
  sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
  sqlite3IndexAffinityStr(v, pIdx);
}

/*
** Generate code for an equality term of the WHERE clause.  An equality
** term can be either X=expr  or X IN (...).   pTerm is the X.  
*/
static void codeEqualityTerm(
  Parse *pParse,      /* The parsing context */
  ExprInfo *pTerm,    /* The term of the WHERE clause to be coded */
  int brk,            /* Jump here to abandon the loop */
  WhereLevel *pLevel  /* When level of the FROM clause we are working on */
){
  Expr *pX = pTerm->p;
  if( pX->op!=TK_IN ){
    assert( pX->op==TK_EQ );
    sqlite3ExprCode(pParse, pX->pRight);
#ifndef SQLITE_OMIT_SUBQUERY
  }else{
    int iTab;
    Vdbe *v = pParse->pVdbe;

    sqlite3CodeSubselect(pParse, pX);
    iTab = pX->iTable;
    sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);
    sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
    VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));
    pLevel->inP2 = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);
    pLevel->inOp = OP_Next;
    pLevel->inP1 = iTab;
#endif
  }
  disableTerm(pLevel, &pTerm->p);
}

/*
** The number of bits in a Bitmask
*/
#define BMS  (sizeof(Bitmask)*8-1)


/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
** information needed to terminate the loop.  Later, the calling routine
** should invoke sqlite3WhereEnd() with the return value of this function
** in order to complete the WHERE clause processing.
**
** If an error occurs, this routine returns NULL.
**
** The basic idea is to do a nested loop, one loop for each table in
** the FROM clause of a select.  (INSERT and UPDATE statements are the
** same as a SELECT with only a single table in the FROM clause.)  For
** example, if the SQL is this:
**
**       SELECT * FROM t1, t2, t3 WHERE ...;
**
** Then the code generated is conceptually like the following:
**
**      foreach row1 in t1 do       \    Code generated
**        foreach row2 in t2 do      |-- by sqlite3WhereBegin()
**          foreach row3 in t3 do   /
**            ...
**          end                     \    Code generated
**        end                        |-- by sqlite3WhereEnd()
**      end                         /
**
** There are Btree cursors associated with each table.  t1 uses cursor
** number pTabList->a[0].iCursor.  t2 uses the cursor pTabList->a[1].iCursor.
** And so forth.  This routine generates code to open those VDBE cursors
** and sqlite3WhereEnd() generates the code to close them.
**
** The code that sqlite3WhereBegin() generates leaves the cursors named
** in pTabList pointing at their appropriate entries.  The [...] code
** can use OP_Column and OP_Recno opcodes on these cursors to extract
** data from the various tables of the loop.
**
** If the WHERE clause is empty, the foreach loops must each scan their
** entire tables.  Thus a three-way join is an O(N^3) operation.  But if
** the tables have indices and there are terms in the WHERE clause that
** refer to those indices, a complete table scan can be avoided and the
** code will run much faster.  Most of the work of this routine is checking
** to see if there are indices that can be used to speed up the loop.
**
** Terms of the WHERE clause are also used to limit which rows actually
** make it to the "..." in the middle of the loop.  After each "foreach",
** terms of the WHERE clause that use only terms in that loop and outer
** loops are evaluated and if false a jump is made around all subsequent
** inner loops (or around the "..." if the test occurs within the inner-
** most loop)
**
** OUTER JOINS
**
** An outer join of tables t1 and t2 is conceptally coded as follows:
**
**    foreach row1 in t1 do
**      flag = 0
**      foreach row2 in t2 do
**        start:
**          ...
**          flag = 1
**      end
**      if flag==0 then
**        move the row2 cursor to a null row
**        goto start
**      fi
**    end
**
** ORDER BY CLAUSE PROCESSING
**
** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
** if there is one.  If there is no ORDER BY clause or if this routine
** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.
**
** If an index can be used so that the natural output order of the table
** scan is correct for the ORDER BY clause, then that index is used and
** *ppOrderBy is set to NULL.  This is an optimization that prevents an
** unnecessary sort of the result set if an index appropriate for the
** ORDER BY clause already exists.
**
** If the where clause loops cannot be arranged to provide the correct
** output order, then the *ppOrderBy is unchanged.
*/
WhereInfo *sqlite3WhereBegin(
  Parse *pParse,        /* The parser context */
  SrcList *pTabList,    /* A list of all tables to be scanned */
  Expr *pWhere,         /* The WHERE clause */
  ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
  Fetch *pFetch         /* Initial location of cursors.  NULL otherwise */
){
  int i;                     /* Loop counter */
  WhereInfo *pWInfo;         /* Will become the return value of this function */
  Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
  int brk, cont = 0;         /* Addresses used during code generation */
  int nExpr;           /* Number of subexpressions in the WHERE clause */
  Bitmask loopMask;    /* One bit set for each outer loop */
  ExprInfo *pTerm;     /* A single term in the WHERE clause; ptr to aExpr[] */
  ExprMaskSet maskSet; /* The expression mask set */
  int iDirectEq[BMS];  /* Term of the form ROWID==X for the N-th table */
  int iDirectLt[BMS];  /* Term of the form ROWID<X or ROWID<=X */
  int iDirectGt[BMS];  /* Term of the form ROWID>X or ROWID>=X */
  ExprInfo aExpr[101]; /* The WHERE clause is divided into these terms */
  struct SrcList_item *pTabItem;  /* A single entry from pTabList */
  WhereLevel *pLevel;             /* A single level in the pWInfo list */

  /* The number of terms in the FROM clause is limited by the number of
  ** bits in a Bitmask 
  */
  if( pTabList->nSrc>sizeof(Bitmask)*8 ){
    sqlite3ErrorMsg(pParse, "at most %d tables in a join",
       sizeof(Bitmask)*8);
    return 0;
  }

  /* Split the WHERE clause into separate subexpressions where each
  ** subexpression is separated by an AND operator.  If the aExpr[]
  ** array fills up, the last entry might point to an expression which
  ** contains additional unfactored AND operators.
  */
  initMaskSet(&maskSet);
  memset(aExpr, 0, sizeof(aExpr));
  nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere);
  if( nExpr==ARRAYSIZE(aExpr) ){
    sqlite3ErrorMsg(pParse, "WHERE clause too complex - no more "
       "than %d terms allowed", (int)ARRAYSIZE(aExpr)-1);
    return 0;
  }
    
  /* Allocate and initialize the WhereInfo structure that will become the
  ** return value.
  */
  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
  if( sqlite3_malloc_failed ){
    /* sqliteFree(pWInfo); // Leak memory when malloc fails */
    return 0;
  }
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->iBreak = sqlite3VdbeMakeLabel(v);

  /* Special case: a WHERE clause that is constant.  Evaluate the
  ** expression and either jump over all of the code or fall thru.
  */
  if( pWhere && (pTabList->nSrc==0 || sqlite3ExprIsConstant(pWhere)) ){
    sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
    pWhere = 0;
  }

  /* Analyze all of the subexpressions.
  */
  for(i=0; i<pTabList->nSrc; i++){
    createMask(&maskSet, pTabList->a[i].iCursor);
  }
  for(pTerm=aExpr, i=0; i<nExpr; i++, pTerm++){
    exprAnalyze(pTabList, &maskSet, pTerm);
  }

  /* Figure out what index to use (if any) for each nested loop.
  ** Make pWInfo->a[i].pIdx point to the index to use for the i-th nested
  ** loop where i==0 is the outer loop and i==pTabList->nSrc-1 is the inner
  ** loop. 
  **
  ** If terms exist that use the ROWID of any table, then set the
  ** iDirectEq[], iDirectLt[], or iDirectGt[] elements for that table
  ** to the index of the term containing the ROWID.  We always prefer
  ** to use a ROWID which can directly access a table rather than an
  ** index which requires reading an index first to get the rowid then
  ** doing a second read of the actual database table.
  **
  ** Actually, if there are more than 32 tables in the join, only the
  ** first 32 tables are candidates for indices.  This is (again) due
  ** to the limit of 32 bits in an integer bitmask.
  */
  loopMask = 0;
  pTabItem = pTabList->a;
  pLevel = pWInfo->a;
  for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++,pTabItem++,pLevel++){
    int j;
    int iCur = pTabItem->iCursor;            /* The cursor for this table */
    Bitmask mask = getMask(&maskSet, iCur);  /* Cursor mask for this table */
    Table *pTab = pTabItem->pTab;
    Index *pIdx;
    Index *pBestIdx = 0;
    int bestScore = 0;
    int bestRev = 0;

    /* Check to see if there is an expression that uses only the
    ** ROWID field of this table.  For terms of the form ROWID==expr
    ** set iDirectEq[i] to the index of the term.  For terms of the
    ** form ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index.
    ** For terms like ROWID>expr or ROWID>=expr set iDirectGt[i].
    **
    ** (Added:) Treat ROWID IN expr like ROWID=expr.
    */
    pLevel->iIdxCur = -1;
    iDirectEq[i] = -1;
    iDirectLt[i] = -1;
    iDirectGt[i] = -1;
    for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
      Expr *pX = pTerm->p;
      if( pTerm->idxLeft==iCur && pX->pLeft->iColumn<0
            && (pTerm->prereqRight & loopMask)==pTerm->prereqRight ){
        switch( pX->op ){
          case TK_IN:
          case TK_EQ: iDirectEq[i] = j; break;
          case TK_LE:
          case TK_LT: iDirectLt[i] = j; break;
          case TK_GE:
          case TK_GT: iDirectGt[i] = j;  break;
        }
      }
    }

    /* If we found a term that tests ROWID with == or IN, that term
    ** will be used to locate the rows in the database table.  There
    ** is not need to continue into the code below that looks for
    ** an index.  We will always use the ROWID over an index.
    */
    if( iDirectEq[i]>=0 ){
      loopMask |= mask;
      pLevel->pIdx = 0;
      continue;
    }

    /* Do a search for usable indices.  Leave pBestIdx pointing to
    ** the "best" index.  pBestIdx is left set to NULL if no indices
    ** are usable.
    **
    ** The best index is the one with the highest score.  The score
    ** for the index is determined as follows.  For each of the
    ** left-most terms that is fixed by an equality operator, add
    ** 32 to the score.  The right-most term of the index may be
    ** constrained by an inequality.  Add 4 if for an "x<..." constraint
    ** and add 8 for an "x>..." constraint.  If both constraints
    ** are present, add 12.
    **
    ** If the left-most term of the index uses an IN operator
    ** (ex:  "x IN (...)")  then add 16 to the score.
    **
    ** If an index can be used for sorting, add 2 to the score.
    ** If an index contains all the terms of a table that are ever
    ** used by any expression in the SQL statement, then add 1 to
    ** the score.
    **
    ** This scoring system is designed so that the score can later be
    ** used to determine how the index is used.  If the score&0x1c is 0
    ** then all constraints are equalities.  If score&0x4 is not 0 then
    ** there is an inequality used as a termination key.  (ex: "x<...")
    ** If score&0x8 is not 0 then there is an inequality used as the
    ** start key.  (ex: "x>...").  A score or 0x10 is the special case
    ** of an IN operator constraint.  (ex:  "x IN ...").
    **
    ** The IN operator (as in "<expr> IN (...)") is treated the same as
    ** an equality comparison except that it can only be used on the
    ** left-most column of an index and other terms of the WHERE clause
    ** cannot be used in conjunction with the IN operator to help satisfy
    ** other columns of the index.
    */
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      Bitmask eqMask = 0;  /* Index columns covered by an x=... term */
      Bitmask ltMask = 0;  /* Index columns covered by an x<... term */
      Bitmask gtMask = 0;  /* Index columns covered by an x>... term */
      Bitmask inMask = 0;  /* Index columns covered by an x IN .. term */
      Bitmask m;
      int nEq, score, bRev = 0;

      if( pIdx->nColumn>sizeof(eqMask)*8 ){
        continue;  /* Ignore indices with too many columns to analyze */
      }
      for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
        Expr *pX = pTerm->p;
        CollSeq *pColl = sqlite3ExprCollSeq(pParse, pX->pLeft);
        if( !pColl && pX->pRight ){
          pColl = sqlite3ExprCollSeq(pParse, pX->pRight);
        }
        if( !pColl ){
          pColl = pParse->db->pDfltColl;
        }
        if( pTerm->idxLeft==iCur 
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight ){
          int iColumn = pX->pLeft->iColumn;
          int k;
          char idxaff = pIdx->pTable->aCol[iColumn].affinity; 
          for(k=0; k<pIdx->nColumn; k++){
            /* If the collating sequences or affinities don't match, 
            ** ignore this index.  */
            if( pColl!=pIdx->keyInfo.aColl[k] ) continue;
            if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
            if( pIdx->aiColumn[k]==iColumn ){
              switch( pX->op ){
                case TK_IN: {
                  if( k==0 ) inMask |= 1;
                  break;
                }
                case TK_EQ: {
                  eqMask |= ((Bitmask)1)<<k;
                  break;
                }
                case TK_LE:
                case TK_LT: {
                  ltMask |= ((Bitmask)1)<<k;
                  break;
                }
                case TK_GE:
                case TK_GT: {
                  gtMask |= ((Bitmask)1)<<k;
                  break;
                }
                default: {
                  /* CANT_HAPPEN */
                  assert( 0 );
                  break;
                }
              }
              break;
            }
          }
        }
      }

      /* The following loop ends with nEq set to the number of columns
      ** on the left of the index with == constraints.
      */
      for(nEq=0; nEq<pIdx->nColumn; nEq++){
        m = (((Bitmask)1)<<(nEq+1))-1;
        if( (m & eqMask)!=m ) break;
      }

      /* Begin assemblying the score
      */
      score = nEq*32;   /* Base score is 32 times number of == constraints */
      m = ((Bitmask)1)<<nEq;
      if( m & ltMask ) score+=4;    /* Increase score for a < constraint */
      if( m & gtMask ) score+=8;    /* Increase score for a > constraint */
      if( score==0 && inMask ) score = 16; /* Default score for IN constraint */

      /* Give bonus points if this index can be used for sorting
      */
      if( i==0 && score!=16 && ppOrderBy && *ppOrderBy ){
        int base = pTabList->a[0].iCursor;
        if( isSortingIndex(pParse, pIdx, pTab, base, *ppOrderBy, nEq, &bRev) ){
          score += 2;
        }
      }

      /* Check to see if we can get away with using just the index without
      ** ever reading the table.  If that is the case, then add one bonus
      ** point to the score.
      */
      if( score && pTabItem->colUsed < (((Bitmask)1)<<(BMS-1)) ){
        for(m=0, j=0; j<pIdx->nColumn; j++){
          int x = pIdx->aiColumn[j];
          if( x<BMS-1 ){
            m |= ((Bitmask)1)<<x;
          }
        }
        if( (pTabItem->colUsed & m)==pTabItem->colUsed ){
          score++;
        }
      }

      /* If the score for this index is the best we have seen so far, then
      ** save it
      */
      if( score>bestScore ){
        pBestIdx = pIdx;
        bestScore = score;
        bestRev = bRev;
      }
    }
    pLevel->pIdx = pBestIdx;
    pLevel->score = bestScore;
    pLevel->bRev = bestRev;
    loopMask |= mask;
    if( pBestIdx ){
      pLevel->iIdxCur = pParse->nTab++;
    }
  }

  /* Check to see if the ORDER BY clause is or can be satisfied by the
  ** use of an index on the first table.
  */
  if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ){
    Index *pIdx;             /* Index derived from the WHERE clause */
    Table *pTab;             /* Left-most table in the FROM clause */
    int bRev = 0;            /* True to reverse the output order */
    int iCur;                /* Btree-cursor that will be used by pTab */
    WhereLevel *pLevel0 = &pWInfo->a[0];

    pTab = pTabList->a[0].pTab;
    pIdx = pLevel0->pIdx;
    iCur = pTabList->a[0].iCursor;
    if( pIdx==0 && sortableByRowid(iCur, *ppOrderBy, &bRev) ){
      /* The ORDER BY clause specifies ROWID order, which is what we
      ** were going to be doing anyway...
      */
      *ppOrderBy = 0;
      pLevel0->bRev = bRev;
    }else if( pLevel0->score==16 ){
      /* If there is already an IN index on the left-most table,
      ** it will not give the correct sort order.
      ** So, pretend that no suitable index is found.
      */
    }else if( iDirectEq[0]>=0 || iDirectLt[0]>=0 || iDirectGt[0]>=0 ){
      /* If the left-most column is accessed using its ROWID, then do
      ** not try to sort by index.  But do delete the ORDER BY clause
      ** if it is redundant.
      */
    }else if( (pLevel0->score&2)!=0 ){
      /* The index that was selected for searching will cause rows to
      ** appear in sorted order.
      */
      *ppOrderBy = 0;
    }
  }

  /* Open all tables in the pTabList and any indices selected for
  ** searching those tables.
  */
  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
  pLevel = pWInfo->a;
  for(i=0, pTabItem=pTabList->a; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
    Table *pTab;
    Index *pIx;
    int iIdxCur = pLevel->iIdxCur;

    pTab = pTabItem->pTab;
    if( pTab->isTransient || pTab->pSelect ) continue;
    if( (pLevel->score & 1)==0 ){
      sqlite3OpenTableForReading(v, pTabItem->iCursor, pTab);
    }
    pLevel->iTabCur = pTabItem->iCursor;
    if( (pIx = pLevel->pIdx)!=0 ){
      sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
      sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
                     (char*)&pIx->keyInfo, P3_KEYINFO);
    }
    if( (pLevel->score & 1)!=0 ){
      sqlite3VdbeAddOp(v, OP_KeyAsData, iIdxCur, 1);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
    }
    sqlite3CodeVerifySchema(pParse, pTab->iDb);
  }
  pWInfo->iTop = sqlite3VdbeCurrentAddr(v);

  /* Generate the code to do the search
  */
  loopMask = 0;
  pLevel = pWInfo->a;
  pTabItem = pTabList->a;
  for(i=0; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
    int j, k;
    int iCur = pTabItem->iCursor;  /* The VDBE cursor for the table */
    Index *pIdx;       /* The index we will be using */
    int iIdxCur;       /* The VDBE cursor for the index */
    int omitTable;     /* True if we use the index only */

    pIdx = pLevel->pIdx;
    iIdxCur = pLevel->iIdxCur;
    pLevel->inOp = OP_Noop;

    /* Check to see if it is appropriate to omit the use of the table
    ** here and use its index instead.
    */
    omitTable = (pLevel->score&1)!=0;

    /* If this is the right table of a LEFT OUTER JOIN, allocate and
    ** initialize a memory cell that records if this table matches any
    ** row of the left table of the join.
    */
    if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
      if( !pParse->nMem ) pParse->nMem++;
      pLevel->iLeftJoin = pParse->nMem++;
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
      VdbeComment((v, "# init LEFT JOIN no-match flag"));
    }

    if( i<ARRAYSIZE(iDirectEq) && (k = iDirectEq[i])>=0 ){
      /* Case 1:  We can directly reference a single row using an
      **          equality comparison against the ROWID field.  Or
      **          we reference multiple rows using a "rowid IN (...)"
      **          construct.
      */
      assert( k<nExpr );
      pTerm = &aExpr[k];
      assert( pTerm->p!=0 );
      assert( pTerm->idxLeft==iCur );
      assert( omitTable==0 );
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
      codeEqualityTerm(pParse, pTerm, brk, pLevel);
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk);
      sqlite3VdbeAddOp(v, OP_NotExists, iCur, brk);
      VdbeComment((v, "pk"));
      pLevel->op = OP_Noop;
    }else if( pIdx!=0 && pLevel->score>3 && (pLevel->score&0x0c)==0 ){
      /* Case 2:  There is an index and all terms of the WHERE clause that
      **          refer to the index using the "==" or "IN" operators.
      */
      int start;
      int nColumn = (pLevel->score+16)/32;
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);

      /* For each column of the index, find the term of the WHERE clause that
      ** constraints that column.  If the WHERE clause term is X=expr, then
      ** evaluation expr and leave the result on the stack */
      for(j=0; j<nColumn; j++){
        for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
          Expr *pX = pTerm->p;
          if( pX==0 ) continue;
          if( pTerm->idxLeft==iCur
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight 
             && pX->pLeft->iColumn==pIdx->aiColumn[j]
             && (pX->op==TK_EQ || pX->op==TK_IN)
          ){
            char idxaff = pIdx->pTable->aCol[pX->pLeft->iColumn].affinity;
            if( sqlite3IndexAffinityOk(pX, idxaff) ){
              codeEqualityTerm(pParse, pTerm, brk, pLevel);
              break;
            }
          }
        }
      }
      pLevel->iMem = pParse->nMem++;
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      buildIndexProbe(v, nColumn, brk, pIdx);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);

      /* Generate code (1) to move to the first matching element of the table.
      ** Then generate code (2) that jumps to "brk" after the cursor is past
      ** the last matching element of the table.  The code (1) is executed
      ** once to initialize the search, the code (2) is executed before each
      ** iteration of the scan to see if the scan has finished. */
      if( pLevel->bRev ){
        /* Scan in reverse order */
        sqlite3VdbeAddOp(v, OP_MoveLe, iIdxCur, brk);
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, OP_IdxLT, iIdxCur, brk);
        pLevel->op = OP_Prev;
      }else{
        /* Scan in the forward order */
        sqlite3VdbeAddOp(v, OP_MoveGe, iIdxCur, brk);
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC);
        pLevel->op = OP_Next;
      }
      sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
      sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
      if( !omitTable ){
        sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0);
        sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      }
      pLevel->p1 = iIdxCur;
      pLevel->p2 = start;
    }else if( i<ARRAYSIZE(iDirectLt) && (iDirectLt[i]>=0 || iDirectGt[i]>=0) ){
      /* Case 3:  We have an inequality comparison against the ROWID field.
      */
      int testOp = OP_Noop;
      int start;
      int bRev = pLevel->bRev;

      assert( omitTable==0 );
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      if( bRev ){
        int t = iDirectGt[i];
        iDirectGt[i] = iDirectLt[i];
        iDirectLt[i] = t;
      }
      if( iDirectGt[i]>=0 ){
        Expr *pX;
        k = iDirectGt[i];
        assert( k<nExpr );
        pTerm = &aExpr[k];
        pX = pTerm->p;
        assert( pX!=0 );
        assert( pTerm->idxLeft==iCur );
        sqlite3ExprCode(pParse, pX->pRight);
        sqlite3VdbeAddOp(v, OP_ForceInt, pX->op==TK_LE || pX->op==TK_GT, brk);
        sqlite3VdbeAddOp(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk);
        VdbeComment((v, "pk"));
        disableTerm(pLevel, &pTerm->p);
      }else{
        sqlite3VdbeAddOp(v, bRev ? OP_Last : OP_Rewind, iCur, brk);
      }
      if( iDirectLt[i]>=0 ){
        Expr *pX;
        k = iDirectLt[i];
        assert( k<nExpr );
        pTerm = &aExpr[k];
        pX = pTerm->p;
        assert( pX!=0 );
        assert( pTerm->idxLeft==iCur );
        sqlite3ExprCode(pParse, pX->pRight);
        pLevel->iMem = pParse->nMem++;
        sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
        if( pX->op==TK_LT || pX->op==TK_GT ){
          testOp = bRev ? OP_Le : OP_Ge;
        }else{
          testOp = bRev ? OP_Lt : OP_Gt;
        }
        disableTerm(pLevel, &pTerm->p);
      }
      start = sqlite3VdbeCurrentAddr(v);
      pLevel->op = bRev ? OP_Prev : OP_Next;
      pLevel->p1 = iCur;
      pLevel->p2 = start;
      if( testOp!=OP_Noop ){
        sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
        sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, testOp, 0, brk);
      }
    }else if( pIdx==0 ){
      /* Case 4:  There is no usable index.  We must do a complete
      **          scan of the entire database table.
      */
      int start;
      int opRewind;

      assert( omitTable==0 );
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      if( pLevel->bRev ){
        opRewind = OP_Last;
        pLevel->op = OP_Prev;
      }else{
        opRewind = OP_Rewind;
        pLevel->op = OP_Next;
      }
      sqlite3VdbeAddOp(v, opRewind, iCur, brk);
      start = sqlite3VdbeCurrentAddr(v);
      pLevel->p1 = iCur;
      pLevel->p2 = start;
    }else{
      /* Case 5: The WHERE clause term that refers to the right-most
      **         column of the index is an inequality.  For example, if
      **         the index is on (x,y,z) and the WHERE clause is of the
      **         form "x=5 AND y<10" then this case is used.  Only the
      **         right-most column can be an inequality - the rest must
      **         use the "==" operator.
      **
      **         This case is also used when there are no WHERE clause
      **         constraints but an index is selected anyway, in order
      **         to force the output order to conform to an ORDER BY.
      */
      int score = pLevel->score;
      int nEqColumn = score/32;
      int start;
      int leFlag=0, geFlag=0;
      int testOp;

      /* Evaluate the equality constraints
      */
      for(j=0; j<nEqColumn; j++){
        int iIdxCol = pIdx->aiColumn[j];
        for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
          Expr *pX = pTerm->p;
          if( pX==0 ) continue;
          if( pTerm->idxLeft==iCur
             && pX->op==TK_EQ
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight 
             && pX->pLeft->iColumn==iIdxCol
          ){
            sqlite3ExprCode(pParse, pX->pRight);
            disableTerm(pLevel, &pTerm->p);
            break;
          }
        }
      }

      /* Duplicate the equality term values because they will all be
      ** used twice: once to make the termination key and once to make the
      ** start key.
      */
      for(j=0; j<nEqColumn; j++){
        sqlite3VdbeAddOp(v, OP_Dup, nEqColumn-1, 0);
      }

      /* Labels for the beginning and end of the loop
      */
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);

      /* Generate the termination key.  This is the key value that
      ** will end the search.  There is no termination key if there
      ** are no equality terms and no "X<..." term.
      **
      ** 2002-Dec-04: On a reverse-order scan, the so-called "termination"
      ** key computed here really ends up being the start key.
      */
      if( (score & 4)!=0 ){
        for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
          Expr *pX = pTerm->p;
          if( pX==0 ) continue;
          if( pTerm->idxLeft==iCur
             && (pX->op==TK_LT || pX->op==TK_LE)
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight 
             && pX->pLeft->iColumn==pIdx->aiColumn[j]
          ){
            sqlite3ExprCode(pParse, pX->pRight);
            leFlag = pX->op==TK_LE;
            disableTerm(pLevel, &pTerm->p);
            break;
          }
        }
        testOp = OP_IdxGE;
      }else{
        testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop;
        leFlag = 1;
      }
      if( testOp!=OP_Noop ){
        int nCol = nEqColumn + ((score & 4)!=0);
        pLevel->iMem = pParse->nMem++;
        buildIndexProbe(v, nCol, brk, pIdx);
        if( pLevel->bRev ){
          int op = leFlag ? OP_MoveLe : OP_MoveLt;
          sqlite3VdbeAddOp(v, op, iIdxCur, brk);
        }else{
          sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
        }
      }else if( pLevel->bRev ){
        sqlite3VdbeAddOp(v, OP_Last, iIdxCur, brk);
      }

      /* Generate the start key.  This is the key that defines the lower
      ** bound on the search.  There is no start key if there are no
      ** equality terms and if there is no "X>..." term.  In
      ** that case, generate a "Rewind" instruction in place of the
      ** start key search.
      **
      ** 2002-Dec-04: In the case of a reverse-order search, the so-called
      ** "start" key really ends up being used as the termination key.
      */
      if( (score & 8)!=0 ){
        for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
          Expr *pX = pTerm->p;
          if( pX==0 ) continue;
          if( pTerm->idxLeft==iCur
             && (pX->op==TK_GT || pX->op==TK_GE)
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight 
             && pX->pLeft->iColumn==pIdx->aiColumn[j]
          ){
            sqlite3ExprCode(pParse, pX->pRight);
            geFlag = pX->op==TK_GE;
            disableTerm(pLevel, &pTerm->p);
            break;
          }
        }
      }else{
        geFlag = 1;
      }
      if( nEqColumn>0 || (score&8)!=0 ){
        int nCol = nEqColumn + ((score&8)!=0);
        buildIndexProbe(v, nCol, brk, pIdx);
        if( pLevel->bRev ){
          pLevel->iMem = pParse->nMem++;
          sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
          testOp = OP_IdxLT;
        }else{
          int op = geFlag ? OP_MoveGe : OP_MoveGt;
          sqlite3VdbeAddOp(v, op, iIdxCur, brk);
        }
      }else if( pLevel->bRev ){
        testOp = OP_Noop;
      }else{
        sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, brk);
      }

      /* Generate the the top of the loop.  If there is a termination
      ** key we have to test for that key and abort at the top of the
      ** loop.
      */
      start = sqlite3VdbeCurrentAddr(v);
      if( testOp!=OP_Noop ){
        sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, testOp, iIdxCur, brk);
        if( (leFlag && !pLevel->bRev) || (!geFlag && pLevel->bRev) ){
          sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
        }
      }
      sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
      sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + ((score&4)!=0), cont);
      if( !omitTable ){
        sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0);
        sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      }

      /* Record the instruction used to terminate the loop.
      */
      pLevel->op = pLevel->bRev ? OP_Prev : OP_Next;
      pLevel->p1 = iIdxCur;
      pLevel->p2 = start;
    }
    loopMask |= getMask(&maskSet, iCur);

    /* Insert code to test every subexpression that can be completely
    ** computed using the current set of tables.
    */
    for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
      if( pTerm->p==0 ) continue;
      if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue;
      if( pLevel->iLeftJoin && !ExprHasProperty(pTerm->p,EP_FromJoin) ){
        continue;
      }
      sqlite3ExprIfFalse(pParse, pTerm->p, cont, 1);
      pTerm->p = 0;
    }
    brk = cont;

    /* For a LEFT OUTER JOIN, generate code that will record the fact that
    ** at least one row of the right table has matched the left table.  
    */
    if( pLevel->iLeftJoin ){
      pLevel->top = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
      VdbeComment((v, "# record LEFT JOIN hit"));
      for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
        if( pTerm->p==0 ) continue;
        if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue;
        sqlite3ExprIfFalse(pParse, pTerm->p, cont, 1);
        pTerm->p = 0;
      }
    }
  }
  pWInfo->iContinue = cont;
  freeMaskSet(&maskSet);
  return pWInfo;
}

/*
** Generate the end of the WHERE loop.  See comments on 
** sqlite3WhereBegin() for additional information.
*/
void sqlite3WhereEnd(WhereInfo *pWInfo){
  Vdbe *v = pWInfo->pParse->pVdbe;
  int i;
  WhereLevel *pLevel;
  SrcList *pTabList = pWInfo->pTabList;
  struct SrcList_item *pTabItem;

  /* Generate loop termination code.
  */
  for(i=pTabList->nSrc-1; i>=0; i--){
    pLevel = &pWInfo->a[i];
    sqlite3VdbeResolveLabel(v, pLevel->cont);
    if( pLevel->op!=OP_Noop ){
      sqlite3VdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
    }
    sqlite3VdbeResolveLabel(v, pLevel->brk);
    if( pLevel->inOp!=OP_Noop ){
      sqlite3VdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2);
    }
    if( pLevel->iLeftJoin ){
      int addr;
      addr = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
      sqlite3VdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iIdxCur>=0));
      sqlite3VdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
      if( pLevel->iIdxCur>=0 ){
        sqlite3VdbeAddOp(v, OP_NullRow, pLevel->iIdxCur, 0);
      }
      sqlite3VdbeAddOp(v, OP_Goto, 0, pLevel->top);
    }
  }

  /* The "break" point is here, just past the end of the outer loop.
  ** Set it.
  */
  sqlite3VdbeResolveLabel(v, pWInfo->iBreak);

  /* Close all of the cursors that were opend by sqlite3WhereBegin.
  */
  pLevel = pWInfo->a;
  pTabItem = pTabList->a;
  for(i=0; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    if( pTab->isTransient || pTab->pSelect ) continue;
    if( (pLevel->score & 1)==0 ){
      sqlite3VdbeAddOp(v, OP_Close, pTabItem->iCursor, 0);
    }
    if( pLevel->pIdx!=0 ){
      sqlite3VdbeAddOp(v, OP_Close, pLevel->iIdxCur, 0);
    }

    /* Make cursor substitutions for cases where we want to use
    ** just the index and never reference the table.
    ** 
    ** Calls to the code generator in between sqlite3WhereBegin and
    ** sqlite3WhereEnd will have created code that references the table
    ** directly.  This loop scans all that code looking for opcodes
    ** that reference the table and converts them into opcodes that
    ** reference the index.
    */
    if( pLevel->score & 1 ){
      int i, j, last;
      VdbeOp *pOp;
      Index *pIdx = pLevel->pIdx;

      assert( pIdx!=0 );
      pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
      last = sqlite3VdbeCurrentAddr(v);
      for(i=pWInfo->iTop; i<last; i++, pOp++){
        if( pOp->p1!=pLevel->iTabCur ) continue;
        if( pOp->opcode==OP_Column ){
          pOp->p1 = pLevel->iIdxCur;
          for(j=0; j<pIdx->nColumn; j++){
            if( pOp->p2==pIdx->aiColumn[j] ){
              pOp->p2 = j;
              break;
            }
          }
        }else if( pOp->opcode==OP_Recno ){
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRecno;
        }else if( pOp->opcode==OP_NullRow ){
          pOp->opcode = OP_Noop;
        }
      }
    }
  }

  /* Final cleanup
  */
  sqliteFree(pWInfo);
  return;
}
Deleted SQLite.Interop/src/win/AssemblyInfo.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using namespace System::Reflection;
using namespace System::Resources;
using namespace System::Runtime::InteropServices;

#include "interop.h"

[assembly:AssemblyTitleAttribute("SQLite.Interop")];
[assembly:AssemblyCompanyAttribute("Robert Simpson, et al.")];
[assembly:AssemblyDescriptionAttribute("System.Data.SQLite Interop Assembly")];
[assembly:AssemblyProductAttribute("System.Data.SQLite")];
[assembly:AssemblyCopyrightAttribute("Public Domain")];
[assembly:AssemblyVersionAttribute(INTEROP_VERSION)];
[assembly:AssemblyFileVersionAttribute(INTEROP_VERSION)];

#if DEBUG
[assembly:AssemblyConfiguration("Debug")];
#else
[assembly:AssemblyConfiguration("Release")];
#endif

[assembly:NeutralResourcesLanguage("en-US")];
[assembly:ComVisible(false)];
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Deleted 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
//
// Microsoft Visual C++ generated resource script.
//

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

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

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

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

/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION INTEROP_RC_VERSION
 PRODUCTVERSION INTEROP_RC_VERSION
 FILEFLAGSMASK 0x17L
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x2L
 FILESUBTYPE 0x0L
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 "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
    END
END
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted SQLite.Interop/src/win/crypt.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
#ifndef SQLITE_OMIT_DISKIO
#ifdef SQLITE_HAS_CODEC

//#ifdef SQLITE_DEBUG
//#include "splitsource\pager.c"
//#endif

#include <windows.h>
#include <wincrypt.h>

// Extra padding before and after the cryptographic buffer
#define CRYPT_OFFSET 8

typedef struct _CRYPTBLOCK
{
  Pager    *pPager;       // Pager this cryptblock belongs to
  HCRYPTKEY hReadKey;     // Key used to read from the database and write to the journal
  HCRYPTKEY hWriteKey;    // Key used to write to the database
  DWORD     dwPageSize;   // Size of pages
  LPVOID    pvCrypt;      // A buffer for encrypting/decrypting (if necessary)
  DWORD     dwCryptSize;  // Equal to or greater than dwPageSize.  If larger, pvCrypt is valid and this is its size
} CRYPTBLOCK, *LPCRYPTBLOCK;

HCRYPTPROV g_hProvider = 0; // Global instance of the cryptographic provider

#define SQLITECRYPTERROR_PROVIDER "Cryptographic provider not available"

// Needed for re-keying
static void * sqlite3pager_get_codecarg(Pager *pPager)
{
  return (pPager->xCodec) ? pPager->pCodec: NULL;
}

void sqlite3_activate_see(const char *info)
{
}

// Create a cryptographic context.  Use the enhanced provider because it is available on
// most platforms
static BOOL InitializeProvider()
{
  if (g_hProvider) return TRUE;

  if (!CryptAcquireContext(&g_hProvider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
  {
    return FALSE;
  }
  return TRUE;
}

// Create or update a cryptographic context for a pager.
// This function will automatically determine if the encryption algorithm requires
// extra padding, and if it does, will create a temp buffer big enough to provide
// space to hold it.
static LPCRYPTBLOCK CreateCryptBlock(HCRYPTKEY hKey, Pager *pager, int pageSize, LPCRYPTBLOCK pExisting)
{
  LPCRYPTBLOCK pBlock;

  if (!pExisting) // Creating a new cryptblock
  {
    pBlock = sqlite3_malloc(sizeof(CRYPTBLOCK));
    if (!pBlock) return NULL;

    ZeroMemory(pBlock, sizeof(CRYPTBLOCK));
    pBlock->hReadKey = hKey;
    pBlock->hWriteKey = hKey;
  }
  else // Updating an existing cryptblock
  {
    pBlock = pExisting;
  }

  if (pageSize == -1)
    pageSize = pager->pageSize;

  pBlock->pPager = pager;
  pBlock->dwPageSize = (DWORD)pageSize;
  pBlock->dwCryptSize = pBlock->dwPageSize;

  // Existing cryptblocks may have a buffer, if so, delete it
  if (pBlock->pvCrypt)
  {
    sqlite3_free(pBlock->pvCrypt);
    pBlock->pvCrypt = NULL;
  }

  // Figure out how big to make our spare crypt block
  CryptEncrypt(hKey, 0, TRUE, 0, NULL, &pBlock->dwCryptSize, pBlock->dwCryptSize * 2);
  pBlock->pvCrypt = sqlite3_malloc(pBlock->dwCryptSize + (CRYPT_OFFSET * 2));
  if (!pBlock->pvCrypt)
  {
    // We created a new block in here, so free it.  Otherwise leave the original intact
    if (pBlock != pExisting) 
      sqlite3_free(pBlock);

    return NULL;
  }

  return pBlock;
}

// Destroy a cryptographic context and any buffers and keys allocated therein
static void sqlite3CodecFree(LPVOID pv)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pv;
  // Destroy the read key if there is one
  if (pBlock->hReadKey)
  {
    CryptDestroyKey(pBlock->hReadKey);
  }

  // If there's a writekey and its not equal to the readkey, destroy it
  if (pBlock->hWriteKey && pBlock->hWriteKey != pBlock->hReadKey)
  {
    CryptDestroyKey(pBlock->hWriteKey);
  }

  // If there's extra buffer space allocated, free it as well
  if (pBlock->pvCrypt)
  {
    sqlite3_free(pBlock->pvCrypt);
  }

  // All done with this cryptblock
  sqlite3_free(pBlock);
}

void sqlite3CodecSizeChange(void *pArg, int pageSize, int reservedSize)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;

  if (pBlock->dwPageSize != pageSize)
  {
    CreateCryptBlock(pBlock->hReadKey, pBlock->pPager, pageSize, pBlock);
    // If this fails, pvCrypt will be NULL, and the next time sqlite3Codec() is called, it will result in an error
  }
}

// Encrypt/Decrypt functionality, called by pager.c
void * sqlite3Codec(void *pArg, void *data, Pgno nPageNum, int nMode)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;
  DWORD dwPageSize;
  LPVOID pvTemp;

  if (!pBlock) return data;
  if (pBlock->pvCrypt == NULL) return NULL; // This only happens if CreateCryptBlock() failed to make scratch space

  switch(nMode)
  {
  case 0: // Undo a "case 7" journal file encryption
  case 2: // Reload a page
  case 3: // Load a page
    if (!pBlock->hReadKey) break;

    /* Block ciphers often need to write extra padding beyond the 
    data block.  We don't have that luxury for a given page of data so
    we must copy the page data to a buffer that IS large enough to hold
    the padding.  We then encrypt the block and write the buffer back to
    the page without the unnecessary padding.
    We only use the special block of memory if its absolutely necessary. */
    if (pBlock->dwCryptSize != pBlock->dwPageSize)
    {
      CopyMemory(((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, data, pBlock->dwPageSize);
      pvTemp = data;
      data = ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET;
    }

    dwPageSize = pBlock->dwCryptSize;
    CryptDecrypt(pBlock->hReadKey, 0, TRUE, 0, (LPBYTE)data, &dwPageSize);

    // If the encryption algorithm required extra padding and we were forced to encrypt or
    // decrypt a copy of the page data to a temp buffer, then write the contents of the temp
    // buffer back to the page data minus any padding applied.
    if (pBlock->dwCryptSize != pBlock->dwPageSize)
    {
      CopyMemory(pvTemp, data, pBlock->dwPageSize);
      data = pvTemp;
    }
    break;
  case 6: // Encrypt a page for the main database file
    if (!pBlock->hWriteKey) break;

    CopyMemory(((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, data, pBlock->dwPageSize);
    data = ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET;

    dwPageSize = pBlock->dwPageSize;
    CryptEncrypt(pBlock->hWriteKey, 0, TRUE, 0, ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, &dwPageSize, pBlock->dwCryptSize);
    break;
  case 7: // Encrypt a page for the journal file
    /* Under normal circumstances, the readkey is the same as the writekey.  However,
    when the database is being rekeyed, the readkey is not the same as the writekey.
    The rollback journal must be written using the original key for the
    database file because it is, by nature, a rollback journal.
    Therefore, for case 7, when the rollback is being written, always encrypt using
    the database's readkey, which is guaranteed to be the same key that was used to
    read the original data.
    */
    if (!pBlock->hReadKey) break;

    CopyMemory(((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, data, pBlock->dwPageSize);
    data = ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET;

    dwPageSize = pBlock->dwPageSize;
    CryptEncrypt(pBlock->hReadKey, 0, TRUE, 0, ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, &dwPageSize, pBlock->dwCryptSize);
    break;
  }

  return data;
}

// Derive an encryption key from a user-supplied buffer
static HCRYPTKEY DeriveKey(const void *pKey, int nKeyLen)
{
  HCRYPTHASH hHash = 0;
  HCRYPTKEY  hKey;

  if (!pKey || !nKeyLen) return 0;

  if (!InitializeProvider())
  {
    return MAXDWORD;
  }

  if (CryptCreateHash(g_hProvider, CALG_SHA1, 0, 0, &hHash))
  {
    if (CryptHashData(hHash, (LPBYTE)pKey, nKeyLen, 0))
    {
      CryptDeriveKey(g_hProvider, CALG_RC4, hHash, 0, &hKey);
    }
    CryptDestroyHash(hHash);
  }  
  return hKey;
}

// Called by sqlite and sqlite3_key_interop to attach a key to a database.
int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen)
{
  int rc = SQLITE_ERROR;
  HCRYPTKEY hKey = 0;

  // No key specified, could mean either use the main db's encryption or no encryption
  if (!pKey || !nKeyLen)
  {
    if (!nDb)
    {
      return SQLITE_OK; // Main database, no key specified so not encrypted
    }
    else // Attached database, use the main database's key
    {
      // Get the encryption block for the main database and attempt to duplicate the key
      // for use by the attached database
      Pager *p = sqlite3BtreePager(db->aDb[0].pBt);
      LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p);

      if (!pBlock) return SQLITE_OK; // Main database is not encrypted so neither will be any attached database
      if (!pBlock->hReadKey) return SQLITE_OK; // Not encrypted

      if (!CryptDuplicateKey(pBlock->hReadKey, NULL, 0, &hKey))
        return rc; // Unable to duplicate the key
    }
  }
  else // User-supplied passphrase, so create a cryptographic key out of it
  {
    hKey = DeriveKey(pKey, nKeyLen);
    if (hKey == MAXDWORD)
    {
      sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER);
      return rc;
    }
  }

  // Create a new encryption block and assign the codec to the new attached database
  if (hKey)
  {
    Pager *p = sqlite3BtreePager(db->aDb[nDb].pBt);
    LPCRYPTBLOCK pBlock = CreateCryptBlock(hKey, p, -1, NULL);
    if (!pBlock) return SQLITE_NOMEM;

    sqlite3PagerSetCodec(p, sqlite3Codec, sqlite3CodecSizeChange, sqlite3CodecFree, pBlock);
    //db->aDb[nDb].pAux = pBlock;
    //db->aDb[nDb].xFreeAux = DestroyCryptBlock;

    rc = SQLITE_OK;
  }
  return rc;
}

// Once a password has been supplied and a key created, we don't keep the 
// original password for security purposes.  Therefore return NULL.
void sqlite3CodecGetKey(sqlite3 *db, int nDb, void **ppKey, int *pnKeyLen)
{
  Btree *pbt = db->aDb[0].pBt;
  Pager *p = sqlite3BtreePager(pbt);
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p);

  if (ppKey) *ppKey = 0;
  if (pnKeyLen && pBlock) *pnKeyLen = 1;
}

// We do not attach this key to the temp store, only the main database.
SQLITE_API int sqlite3_key(sqlite3 *db, const unsigned char *pKey, int nKeySize)
{
  return sqlite3CodecAttach(db, 0, pKey, nKeySize);
}

// Changes the encryption key for an existing database.
SQLITE_API int sqlite3_rekey(sqlite3 *db, const unsigned char *pKey, int nKeySize)
{
  Btree *pbt = db->aDb[0].pBt;
  Pager *p = sqlite3BtreePager(pbt);
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p);
  HCRYPTKEY hKey = DeriveKey(pKey, nKeySize);
  int rc = SQLITE_ERROR;

  if (hKey == MAXDWORD)
  {
    sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER);
    return rc;
  }

  if (!pBlock && !hKey) return SQLITE_OK; // Wasn't encrypted to begin with

  // To rekey a database, we change the writekey for the pager.  The readkey remains
  // the same
  if (!pBlock) // Encrypt an unencrypted database
  {
    pBlock = CreateCryptBlock(hKey, p, -1, NULL);
    if (!pBlock)
      return SQLITE_NOMEM;

    pBlock->hReadKey = 0; // Original database is not encrypted
    sqlite3PagerSetCodec(sqlite3BtreePager(pbt), sqlite3Codec, sqlite3CodecSizeChange, sqlite3CodecFree, pBlock);
    //db->aDb[0].pAux = pBlock;
    //db->aDb[0].xFreeAux = DestroyCryptBlock;
  }
  else // Change the writekey for an already-encrypted database
  {
    pBlock->hWriteKey = hKey;
  }

  sqlite3_mutex_enter(db->mutex);

  // Start a transaction
  rc = sqlite3BtreeBeginTrans(pbt, 1);

  if (!rc)
  {
    // Rewrite all the pages in the database using the new encryption key
    Pgno nPage;
    Pgno nSkip = PAGER_MJ_PGNO(p);
    DbPage *pPage;
    Pgno n;
    int count;

    sqlite3PagerPagecount(p, &count);
    nPage = (Pgno)count;

    for(n = 1; n <= nPage; n ++)
    {
      if (n == nSkip) continue;
      rc = sqlite3PagerGet(p, n, &pPage);
      if(!rc)
      {
        rc = sqlite3PagerWrite(pPage);
        sqlite3PagerUnref(pPage);
      }
    }
  }

  // If we succeeded, try and commit the transaction
  if (!rc)
  {
    rc = sqlite3BtreeCommit(pbt);
  }

  // If we failed, rollback
  if (rc)
  {
    sqlite3BtreeRollback(pbt);
  }

  // If we succeeded, destroy any previous read key this database used
  // and make the readkey equal to the writekey
  if (!rc)
  {
    if (pBlock->hReadKey)
    {
      CryptDestroyKey(pBlock->hReadKey);
    }
    pBlock->hReadKey = pBlock->hWriteKey;
  }
  // We failed.  Destroy the new writekey (if there was one) and revert it back to
  // the original readkey
  else
  {
    if (pBlock->hWriteKey)
    {
      CryptDestroyKey(pBlock->hWriteKey);
    }
    pBlock->hWriteKey = pBlock->hReadKey;
  }

  // If the readkey and writekey are both empty, there's no need for a codec on this
  // pager anymore.  Destroy the crypt block and remove the codec from the pager.
  if (!pBlock->hReadKey && !pBlock->hWriteKey)
  {
    sqlite3PagerSetCodec(p, NULL, NULL, NULL, NULL);
  }

  sqlite3_mutex_leave(db->mutex);

  return rc;
}

#endif // SQLITE_HAS_CODEC

#endif // SQLITE_OMIT_DISKIO
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/src/win/interop.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
#define SQLITE_API __declspec(dllexport)
#include "../core/sqlite3.c"
#include "../contrib/extension-functions.c"
#include "crypt.c"

extern int RegisterExtensionFunctions(sqlite3 *db);

#ifdef SQLITE_OS_WIN

// Additional open flags, we use this one privately
//#define SQLITE_OPEN_SHAREDCACHE      0x01000000

typedef void (*SQLITEUSERFUNC)(sqlite3_context *, int, sqlite3_value **);
typedef void (*SQLITEFUNCFINAL)(sqlite3_context *);

SQLITE_PRIVATE void * sqlite3DbMallocZero_interop(sqlite3 *db, int n)
{
  void *p;
  if (db) {
    sqlite3_mutex_enter(db->mutex);
  }
  p = sqlite3DbMallocZero(db,n);
  if (db) {
    sqlite3_mutex_leave(db->mutex);
  }
  return p;
}

SQLITE_PRIVATE void sqlite3DbFree_interop(sqlite3 *db, void *p)
{
  if (db) {
    sqlite3_mutex_enter(db->mutex);
  }
  if (p) {
    sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
  }
  sqlite3DbFree(db,p);
  if (db) {
    sqlite3_mutex_leave(db->mutex);
  }
}

/*
    The goal of this version of close is different than that of sqlite3_close(), and is designed to lend itself better to .NET's non-deterministic finalizers and
    the GC thread.  SQLite will not close a database if statements are open on it -- but for our purposes, we'd rather finalize all active statements
    and forcibly close the database.  The reason is simple -- a lot of people don't Dispose() of their objects correctly and let the garbage collector
    do it.  This leads to unexpected behavior when a user thinks they've closed a database, but it's still open because not all the statements have
    hit the GC yet.

    So, here we have a problem ... .NET has a pointer to any number of sqlite3_stmt objects.  We can't call sqlite3_finalize() on these because
    their memory is freed and can be used for something else.  The GC thread could potentially try and call finalize again on the statement after
    that memory was deallocated.  BAD.  So, what we need to do is make a copy of each statement, and call finalize() on the copy -- so that the original
    statement's memory is preserved, and marked as BAD, but we can still manage to finalize everything and forcibly close the database.  Later when the 
    GC gets around to calling finalize_interop() on the "bad" statement, we detect that and finish deallocating the pointer.
*/
SQLITE_API int WINAPI sqlite3_close_interop(sqlite3 *db)
{
  int ret;
  
  ret = sqlite3_close(db);

  if (ret == SQLITE_BUSY && db->pVdbe)
  {
    while (db->pVdbe)
    {
      // Make a copy of the first prepared statement
      Vdbe *p = (Vdbe *)sqlite3DbMallocZero_interop(db, sizeof(Vdbe));
      Vdbe *po = db->pVdbe;

      if (!p) 
      {
        ret = SQLITE_NOMEM;
        break;
      }

      CopyMemory(p, po, sizeof(Vdbe));

      // Put it on the chain so we can free it
      db->pVdbe = p;
      ret = sqlite3_finalize((sqlite3_stmt *)p); // This will also free the copy's memory
      if (ret)
      {
        // finalize failed -- so we must put back anything we munged
        CopyMemory(po, p, sizeof(Vdbe));
        db->pVdbe = po;

        //
        // NOTE: Ok, we must free this block that *we* allocated (above) since
        //       finalize did not do so.
        //
        sqlite3DbFree_interop(db, p);
        break;
      }
      else
      {
        ZeroMemory(po, sizeof(Vdbe));
        po->magic = VDBE_MAGIC_DEAD;
      }
    }
    ret = sqlite3_close(db);
  }

  return ret;
}

SQLITE_API int WINAPI sqlite3_open_interop(const char*filename, int flags, sqlite3 **ppdb)
{
  int ret;
  //int sharedcache = ((flags & SQLITE_OPEN_SHAREDCACHE) != 0);
  //flags &= ~SQLITE_OPEN_SHAREDCACHE;

  //sqlite3_enable_shared_cache(sharedcache);
  ret = sqlite3_open_v2(filename, ppdb, flags, NULL);
  //sqlite3_enable_shared_cache(0);

  if (ret == 0)
    RegisterExtensionFunctions(*ppdb);

  return ret;
}

SQLITE_API int WINAPI sqlite3_open16_interop(const char *filename, int flags, sqlite3 **ppdb)
{
  int ret = sqlite3_open_interop(filename, flags, ppdb);
  if (!ret)
  {
    if(!DbHasProperty(*ppdb, 0, DB_SchemaLoaded))
      ENC(*ppdb) = SQLITE_UTF16NATIVE;
  }
  return ret;
}

SQLITE_API const char * WINAPI sqlite3_errmsg_interop(sqlite3 *db, int *plen)
{
  const char *pval = sqlite3_errmsg(db);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

SQLITE_API int WINAPI sqlite3_prepare_interop(sqlite3 *db, const char *sql, int nbytes, sqlite3_stmt **ppstmt, const char **pztail, int *plen)
{
  int n;

  n = sqlite3_prepare(db, sql, nbytes, ppstmt, pztail);
  *plen = (*pztail != 0) ? strlen(*pztail) : 0;

  return n;
}

SQLITE_API int WINAPI sqlite3_prepare16_interop(sqlite3 *db, const void *sql, int nchars, sqlite3_stmt **ppstmt, const void **pztail, int *plen)
{
  int n;

  n = sqlite3_prepare16(db, sql, nchars * sizeof(wchar_t), ppstmt, pztail);
  *plen = (*pztail != 0) ? wcslen((wchar_t *)*pztail) * sizeof(wchar_t) : 0;

  return n;
}

SQLITE_API int WINAPI sqlite3_bind_double_interop(sqlite3_stmt *stmt, int iCol, double *val)
{
	return sqlite3_bind_double(stmt,iCol,*val);
}

SQLITE_API int WINAPI sqlite3_bind_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	return sqlite3_bind_int64(stmt,iCol,*val);
}

SQLITE_API const char * WINAPI sqlite3_bind_parameter_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_bind_parameter_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

SQLITE_API const char * WINAPI sqlite3_column_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

SQLITE_API const void * WINAPI sqlite3_column_name16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_name16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

SQLITE_API const char * WINAPI sqlite3_column_decltype_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_decltype(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

SQLITE_API const void * WINAPI sqlite3_column_decltype16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_decltype16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

SQLITE_API void WINAPI sqlite3_column_double_interop(sqlite3_stmt *stmt, int iCol, double *val)
{
	*val = sqlite3_column_double(stmt,iCol);
}

SQLITE_API void WINAPI sqlite3_column_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	*val = sqlite3_column_int64(stmt,iCol);
}

SQLITE_API const unsigned char * WINAPI sqlite3_column_text_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const unsigned char *pval = sqlite3_column_text(stmt, iCol);
  *plen = (pval != 0) ? strlen((char *)pval) : 0;
  return pval;
}

SQLITE_API const void * WINAPI sqlite3_column_text16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_text16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t): 0;
  return pval;
}

SQLITE_API int WINAPI sqlite3_finalize_interop(sqlite3_stmt *stmt)
{
  Vdbe *p;
  sqlite3 *db;
  int ret;

  p = (Vdbe *)stmt;
  if (p && p->magic == VDBE_MAGIC_DEAD)
  {
    db = p->db;
    if (db == NULL)
    {
      sqlite3DbFree_interop(db, p);
      ret = SQLITE_OK;
    }
  }
  else
    ret = sqlite3_finalize(stmt);

  return ret;
}

SQLITE_API int WINAPI sqlite3_reset_interop(sqlite3_stmt *stmt)
{
  int ret;

  if (((Vdbe *)stmt)->magic == VDBE_MAGIC_DEAD) return SQLITE_SCHEMA;
  ret = sqlite3_reset(stmt);
  return ret;
}

SQLITE_API int WINAPI sqlite3_create_function_interop(sqlite3 *psql, const char *zFunctionName, int nArg, int eTextRep, void *pvUser, SQLITEUSERFUNC func, SQLITEUSERFUNC funcstep, SQLITEFUNCFINAL funcfinal, int needCollSeq)
{
  int n;

  if (eTextRep == SQLITE_UTF16)
    eTextRep = SQLITE_UTF16NATIVE;

  n = sqlite3_create_function(psql, zFunctionName, nArg, eTextRep, 0, func, funcstep, funcfinal);
  if (n == 0)
  {
    if (needCollSeq)
    {
      FuncDef *pFunc = sqlite3FindFunction(psql, zFunctionName, strlen(zFunctionName), nArg, eTextRep, 0);
      if( pFunc )
      {
        pFunc->flags |= SQLITE_FUNC_NEEDCOLL;
      }
    }
  }

  return n;
}

SQLITE_API void WINAPI sqlite3_value_double_interop(sqlite3_value *pval, double *val)
{
  *val = sqlite3_value_double(pval);
}

SQLITE_API void WINAPI sqlite3_value_int64_interop(sqlite3_value *pval, sqlite_int64 *val)
{
  *val = sqlite3_value_int64(pval);
}

SQLITE_API const unsigned char * WINAPI sqlite3_value_text_interop(sqlite3_value *val, int *plen)
{
  const unsigned char *pval = sqlite3_value_text(val);
  *plen = (pval != 0) ? strlen((char *)pval) : 0;
  return pval;
}

SQLITE_API const void * WINAPI sqlite3_value_text16_interop(sqlite3_value *val, int *plen)
{
  const void *pval = sqlite3_value_text16(val);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

SQLITE_API void WINAPI sqlite3_result_double_interop(sqlite3_context *pctx, double *val)
{
  sqlite3_result_double(pctx, *val);
}

SQLITE_API void WINAPI sqlite3_result_int64_interop(sqlite3_context *pctx, sqlite_int64 *val)
{
  sqlite3_result_int64(pctx, *val);
}

SQLITE_API int WINAPI sqlite3_context_collcompare(sqlite3_context *ctx, const void *p1, int p1len, const void *p2, int p2len)
{
  if ((ctx->pFunc->flags & SQLITE_FUNC_NEEDCOLL) == 0) return 2;
  return ctx->pColl->xCmp(ctx->pColl->pUser, p1len, p1, p2len, p2);
}

SQLITE_API const char * WINAPI sqlite3_context_collseq(sqlite3_context *ctx, int *ptype, int *enc, int *plen)
{
  CollSeq *pColl = ctx->pColl;
  *ptype = 0;
  *plen = 0;
  *enc = 0;

  if ((ctx->pFunc->flags & SQLITE_FUNC_NEEDCOLL) == 0) return NULL;

  if (pColl)
  {
    *enc = pColl->enc;
    *ptype = pColl->type;
    *plen = (pColl->zName != 0) ? strlen(pColl->zName) : 0;

    return pColl->zName;
  }
  return NULL;
}

SQLITE_API const char * WINAPI sqlite3_column_database_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_database_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

SQLITE_API const void * WINAPI sqlite3_column_database_name16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_database_name16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

SQLITE_API const char * WINAPI sqlite3_column_table_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_table_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

SQLITE_API const void * WINAPI sqlite3_column_table_name16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_table_name16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

SQLITE_API const char * WINAPI sqlite3_column_origin_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_origin_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

SQLITE_API const void * WINAPI sqlite3_column_origin_name16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_origin_name16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

SQLITE_API int WINAPI sqlite3_table_column_metadata_interop(sqlite3 *db, const char *zDbName, const char *zTableName, const char *zColumnName, char **pzDataType, char **pzCollSeq, int *pNotNull, int *pPrimaryKey, int *pAutoinc, int *pdtLen, int *pcsLen)
{
  int n;
  
  n = sqlite3_table_column_metadata(db, zDbName, zTableName, zColumnName, pzDataType, pzCollSeq, pNotNull, pPrimaryKey, pAutoinc);
  *pdtLen = (*pzDataType != 0) ? strlen(*pzDataType) : 0;
  *pcsLen = (*pzCollSeq != 0) ? strlen(*pzCollSeq) : 0;

  return n;
}

SQLITE_API int WINAPI sqlite3_index_column_info_interop(sqlite3 *db, const char *zDb, const char *zIndexName, const char *zColumnName, int *sortOrder, int *onError, char **pzColl, int *plen)
{
  Index *pIdx;
  Table *pTab;
  int n;

  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);

  pIdx = sqlite3FindIndex(db, zIndexName, zDb);

  sqlite3BtreeLeaveAll(db);
  sqlite3_mutex_leave(db->mutex);

  if (!pIdx) return SQLITE_ERROR;

  pTab = pIdx->pTable;
  for (n = 0; n < pIdx->nColumn; n++)
  {
    int cnum = pIdx->aiColumn[n];
    if (sqlite3StrICmp(pTab->aCol[cnum].zName, zColumnName) == 0)
    {
      *sortOrder = pIdx->aSortOrder[n];
      *pzColl = pIdx->azColl[n];
      *plen = strlen(*pzColl);
      *onError = pIdx->onError;

      return SQLITE_OK;
    }
  }
  return SQLITE_ERROR;
}

SQLITE_API int WINAPI sqlite3_table_cursor(sqlite3_stmt *pstmt, int iDb, Pgno tableRootPage)
{
  Vdbe *p = (Vdbe *)pstmt;
  sqlite3 *db = (p == NULL) ? NULL : p->db;
  int n;
  int ret = -1;

  sqlite3_mutex_enter(db->mutex);
  for (n = 0; n < p->nCursor && p->apCsr[n] != NULL; n++)
  {
    if (p->apCsr[n]->isTable == FALSE) continue;
    if (p->apCsr[n]->iDb != iDb) continue;
    if (p->apCsr[n]->pCursor->pgnoRoot == tableRootPage)
    {
      ret = n;
      break;
    }
  }
  sqlite3_mutex_leave(db->mutex);

  return ret;
}

SQLITE_API int WINAPI sqlite3_cursor_rowid(sqlite3_stmt *pstmt, int cursor, sqlite_int64 *prowid)
{
  Vdbe *p = (Vdbe *)pstmt;
  sqlite3 *db = (p == NULL) ? NULL : p->db;
  VdbeCursor *pC;
  int ret = 0;

  sqlite3_mutex_enter(db->mutex);
  while (1)
  {
    if (cursor < 0 || cursor >= p->nCursor)
    {
      ret = SQLITE_ERROR;
      break;
    }
    if (p->apCsr[cursor] == NULL)
    {
      ret = SQLITE_ERROR;
      break;
    }

    pC = p->apCsr[cursor];

    ret = sqlite3VdbeCursorMoveto(pC);
    if(ret)
      break;

    if(pC->rowidIsValid)
    {
      *prowid = pC->lastRowid;
    }
    else if(pC->pseudoTableReg > 0)
    {
      ret = SQLITE_ERROR;
      break;
    }
    else if(pC->nullRow || pC->pCursor==0)
    {
      ret = SQLITE_ERROR;
      break;
    }
    else
    {
      if (pC->pCursor == NULL)
      {
        ret = SQLITE_ERROR;
        break;
      }
      sqlite3BtreeKeySize(pC->pCursor, prowid);
      *prowid = *prowid;
    }
    break;
  }
  sqlite3_mutex_leave(db->mutex);

  return ret;
}

#endif // SQLITE_OS_WIN
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/src/win/interop.h.
1
2
3
4
5
6
7
8
9
10
11
12
/*
 *
 * interop.h -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
 */

#ifndef INTEROP_VERSION
#define INTEROP_VERSION       "1.0.77.0"
#endif
<
<
<
<
<
<
<
<
<
<
<
<
























Deleted SQLite.MSIL.nuspec.
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"?>
<package>
  <metadata>
    <id>System.Data.SQLite.MSIL</id>
    <version>1.0.77.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>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\Release\bin\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
  </files>
</package>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted SQLite.NET.2008.MSBuild.sln.
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
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}"
	ProjectSection(SolutionItems) = preProject
		readme.htm = readme.htm
		SQLite.NET.Settings.targets = SQLite.NET.Settings.targets
		System.Data.SQLite\System.Data.SQLite.Files.targets = System.Data.SQLite\System.Data.SQLite.Files.targets
		System.Data.SQLite\System.Data.SQLite.Properties.targets = System.Data.SQLite\System.Data.SQLite.Properties.targets
		System.Data.SQLite\System.Data.SQLite.References.targets = System.Data.SQLite\System.Data.SQLite.References.targets
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.2008", "System.Data.SQLite\System.Data.SQLite.2008.csproj", "{AC139952-261A-4463-B6FA-AEBC25283A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Module.2008", "System.Data.SQLite\System.Data.SQLite.Module.2008.csproj", "{AC139952-261A-4463-B6FA-AEBC25284A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test.2008", "test\test.2008.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.2008", "SQLite.Interop\SQLite.Interop.2008.vcproj", "{53784BC1-A8BC-4AC8-8A3E-158D6807345A}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Linq.2008", "System.Data.SQLite.Linq\System.Data.SQLite.Linq.2008.csproj", "{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testlinq.2008", "testlinq\testlinq.2008.csproj", "{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25283A66} = {AC139952-261A-4463-B6FA-AEBC25283A66}
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D} = {E6BF9F74-58E2-413B-A7CE-EA653ECB728D}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Compact.2008", "System.Data.SQLite\System.Data.SQLite.Compact.2008.csproj", "{AC139951-261A-4463-B6FA-AEBC25283A66}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.CE.2008", "SQLite.Interop\SQLite.Interop.CE.2008.vcproj", "{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testce.2008", "testce\testce.2008.csproj", "{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.Static.2008", "SQLite.Interop\SQLite.Interop.Static.2008.vcproj", "{490CBC51-A3B2-4397-89F9-16E858DCB4F8}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer.2008", "tools\install\Installer.2008.csproj", "{A41FE2A5-07AD-4CE7-B836-1544634816F5}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Debug|Mixed Platforms = Debug|Mixed Platforms
		Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4)
		Debug|Win32 = Debug|Win32
		Debug|x64 = Debug|x64
		DebugManagedOnly|Any CPU = DebugManagedOnly|Any CPU
		DebugManagedOnly|Mixed Platforms = DebugManagedOnly|Mixed Platforms
		DebugManagedOnly|Pocket PC 2003 (ARMV4) = DebugManagedOnly|Pocket PC 2003 (ARMV4)
		DebugManagedOnly|Win32 = DebugManagedOnly|Win32
		DebugManagedOnly|x64 = DebugManagedOnly|x64
		DebugNativeOnly|Any CPU = DebugNativeOnly|Any CPU
		DebugNativeOnly|Mixed Platforms = DebugNativeOnly|Mixed Platforms
		DebugNativeOnly|Pocket PC 2003 (ARMV4) = DebugNativeOnly|Pocket PC 2003 (ARMV4)
		DebugNativeOnly|Win32 = DebugNativeOnly|Win32
		DebugNativeOnly|x64 = DebugNativeOnly|x64
		Release|Any CPU = Release|Any CPU
		Release|Mixed Platforms = Release|Mixed Platforms
		Release|Pocket PC 2003 (ARMV4) = Release|Pocket PC 2003 (ARMV4)
		Release|Win32 = Release|Win32
		Release|x64 = Release|x64
		ReleaseManagedOnly|Any CPU = ReleaseManagedOnly|Any CPU
		ReleaseManagedOnly|Mixed Platforms = ReleaseManagedOnly|Mixed Platforms
		ReleaseManagedOnly|Pocket PC 2003 (ARMV4) = ReleaseManagedOnly|Pocket PC 2003 (ARMV4)
		ReleaseManagedOnly|Win32 = ReleaseManagedOnly|Win32
		ReleaseManagedOnly|x64 = ReleaseManagedOnly|x64
		ReleaseNativeOnly|Any CPU = ReleaseNativeOnly|Any CPU
		ReleaseNativeOnly|Mixed Platforms = ReleaseNativeOnly|Mixed Platforms
		ReleaseNativeOnly|Pocket PC 2003 (ARMV4) = ReleaseNativeOnly|Pocket PC 2003 (ARMV4)
		ReleaseNativeOnly|Win32 = ReleaseNativeOnly|Win32
		ReleaseNativeOnly|x64 = ReleaseNativeOnly|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.ActiveCfg = Debug|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.Build.0 = Debug|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.ActiveCfg = Release|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.Build.0 = Release|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Win32.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|x64.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Any CPU.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Win32.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|x64.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|x64.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Win32.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|x64.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Any CPU.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Win32.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|x64.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|x64.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Any CPU.Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Mixed Platforms.Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Win32.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|x64.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Any CPU.Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Mixed Platforms.Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.ActiveCfg = Debug|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.Build.0 = Debug|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.ActiveCfg = Release|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.Build.0 = Release|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.NET.2008.sln.
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
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}"
	ProjectSection(SolutionItems) = preProject
		readme.htm = readme.htm
		SQLite.NET.Settings.targets = SQLite.NET.Settings.targets
		System.Data.SQLite\System.Data.SQLite.Files.targets = System.Data.SQLite\System.Data.SQLite.Files.targets
		System.Data.SQLite\System.Data.SQLite.Properties.targets = System.Data.SQLite\System.Data.SQLite.Properties.targets
		System.Data.SQLite\System.Data.SQLite.References.targets = System.Data.SQLite\System.Data.SQLite.References.targets
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.2008", "System.Data.SQLite\System.Data.SQLite.2008.csproj", "{AC139952-261A-4463-B6FA-AEBC25283A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Module.2008", "System.Data.SQLite\System.Data.SQLite.Module.2008.csproj", "{AC139952-261A-4463-B6FA-AEBC25284A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Compact.2008", "System.Data.SQLite\System.Data.SQLite.Compact.2008.csproj", "{AC139951-261A-4463-B6FA-AEBC25283A66}"
	ProjectSection(ProjectDependencies) = postProject
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6} = {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test.2008", "test\test.2008.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.2008", "SQLite.Interop\SQLite.Interop.2008.vcproj", "{53784BC1-A8BC-4AC8-8A3E-158D6807345A}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Linq.2008", "System.Data.SQLite.Linq\System.Data.SQLite.Linq.2008.csproj", "{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite.Designer.2008", "SQLite.Designer\SQLite.Designer.2008.csproj", "{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testlinq.2008", "testlinq\testlinq.2008.csproj", "{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25283A66} = {AC139952-261A-4463-B6FA-AEBC25283A66}
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D} = {E6BF9F74-58E2-413B-A7CE-EA653ECB728D}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testce.2008", "testce\testce.2008.csproj", "{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.CE.2008", "SQLite.Interop\SQLite.Interop.CE.2008.vcproj", "{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.Static.2008", "SQLite.Interop\SQLite.Interop.Static.2008.vcproj", "{490CBC51-A3B2-4397-89F9-16E858DCB4F8}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer.2008", "tools\install\Installer.2008.csproj", "{A41FE2A5-07AD-4CE7-B836-1544634816F5}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Debug|Mixed Platforms = Debug|Mixed Platforms
		Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4)
		Debug|Win32 = Debug|Win32
		Debug|x64 = Debug|x64
		DebugNativeOnly|Any CPU = DebugNativeOnly|Any CPU
		DebugNativeOnly|Mixed Platforms = DebugNativeOnly|Mixed Platforms
		DebugNativeOnly|Pocket PC 2003 (ARMV4) = DebugNativeOnly|Pocket PC 2003 (ARMV4)
		DebugNativeOnly|Win32 = DebugNativeOnly|Win32
		DebugNativeOnly|x64 = DebugNativeOnly|x64
		Release|Any CPU = Release|Any CPU
		Release|Mixed Platforms = Release|Mixed Platforms
		Release|Pocket PC 2003 (ARMV4) = Release|Pocket PC 2003 (ARMV4)
		Release|Win32 = Release|Win32
		Release|x64 = Release|x64
		ReleaseNativeOnly|Any CPU = ReleaseNativeOnly|Any CPU
		ReleaseNativeOnly|Mixed Platforms = ReleaseNativeOnly|Mixed Platforms
		ReleaseNativeOnly|Pocket PC 2003 (ARMV4) = ReleaseNativeOnly|Pocket PC 2003 (ARMV4)
		ReleaseNativeOnly|Win32 = ReleaseNativeOnly|Win32
		ReleaseNativeOnly|x64 = ReleaseNativeOnly|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.ActiveCfg = Debug|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.Build.0 = Debug|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.ActiveCfg = Release|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.Build.0 = Release|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Win32.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|x64.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Any CPU.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Win32.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|x64.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|x64.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Any CPU.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Win32.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|x64.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Any CPU.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Win32.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|x64.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|x64.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Win32.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|x64.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.ActiveCfg = Debug|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.Build.0 = Debug|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.ActiveCfg = Release|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.Build.0 = Release|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.NET.2010.MSBuild.sln.
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
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}"
	ProjectSection(SolutionItems) = preProject
		readme.htm = readme.htm
		SQLite.NET.Settings.targets = SQLite.NET.Settings.targets
		System.Data.SQLite\System.Data.SQLite.Files.targets = System.Data.SQLite\System.Data.SQLite.Files.targets
		System.Data.SQLite\System.Data.SQLite.Properties.targets = System.Data.SQLite\System.Data.SQLite.Properties.targets
		System.Data.SQLite\System.Data.SQLite.References.targets = System.Data.SQLite\System.Data.SQLite.References.targets
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.2010", "System.Data.SQLite\System.Data.SQLite.2010.csproj", "{AC139952-261A-4463-B6FA-AEBC25283A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Module.2010", "System.Data.SQLite\System.Data.SQLite.Module.2010.csproj", "{AC139952-261A-4463-B6FA-AEBC25284A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test.2010", "test\test.2010.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.2010", "SQLite.Interop\SQLite.Interop.2010.vcxproj", "{53784BC1-A8BC-4AC8-8A3E-158D6807345A}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Linq.2010", "System.Data.SQLite.Linq\System.Data.SQLite.Linq.2010.csproj", "{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testlinq.2010", "testlinq\testlinq.2010.csproj", "{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25283A66} = {AC139952-261A-4463-B6FA-AEBC25283A66}
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D} = {E6BF9F74-58E2-413B-A7CE-EA653ECB728D}
	EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.Static.2010", "SQLite.Interop\SQLite.Interop.Static.2010.vcxproj", "{490CBC51-A3B2-4397-89F9-16E858DCB4F8}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer.2010", "tools\install\Installer.2010.csproj", "{A41FE2A5-07AD-4CE7-B836-1544634816F5}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Debug|Mixed Platforms = Debug|Mixed Platforms
		Debug|Win32 = Debug|Win32
		Debug|x64 = Debug|x64
		DebugManagedOnly|Any CPU = DebugManagedOnly|Any CPU
		DebugManagedOnly|Mixed Platforms = DebugManagedOnly|Mixed Platforms
		DebugManagedOnly|Win32 = DebugManagedOnly|Win32
		DebugManagedOnly|x64 = DebugManagedOnly|x64
		DebugNativeOnly|Any CPU = DebugNativeOnly|Any CPU
		DebugNativeOnly|Mixed Platforms = DebugNativeOnly|Mixed Platforms
		DebugNativeOnly|Win32 = DebugNativeOnly|Win32
		DebugNativeOnly|x64 = DebugNativeOnly|x64
		Release|Any CPU = Release|Any CPU
		Release|Mixed Platforms = Release|Mixed Platforms
		Release|Win32 = Release|Win32
		Release|x64 = Release|x64
		ReleaseManagedOnly|Any CPU = ReleaseManagedOnly|Any CPU
		ReleaseManagedOnly|Mixed Platforms = ReleaseManagedOnly|Mixed Platforms
		ReleaseManagedOnly|Win32 = ReleaseManagedOnly|Win32
		ReleaseManagedOnly|x64 = ReleaseManagedOnly|x64
		ReleaseNativeOnly|Any CPU = ReleaseNativeOnly|Any CPU
		ReleaseNativeOnly|Mixed Platforms = ReleaseNativeOnly|Mixed Platforms
		ReleaseNativeOnly|Win32 = ReleaseNativeOnly|Win32
		ReleaseNativeOnly|x64 = ReleaseNativeOnly|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.ActiveCfg = Debug|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.Build.0 = Debug|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.ActiveCfg = Release|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.Build.0 = Release|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Win32.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|x64.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Any CPU.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Win32.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|x64.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|x64.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Win32.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|x64.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Any CPU.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Win32.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|x64.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.ActiveCfg = Debug|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.Build.0 = Debug|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.ActiveCfg = Release|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.Build.0 = Release|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.NET.2010.sln.
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
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}"
	ProjectSection(SolutionItems) = preProject
		readme.htm = readme.htm
		SQLite.NET.Settings.targets = SQLite.NET.Settings.targets
		System.Data.SQLite\System.Data.SQLite.Files.targets = System.Data.SQLite\System.Data.SQLite.Files.targets
		System.Data.SQLite\System.Data.SQLite.Properties.targets = System.Data.SQLite\System.Data.SQLite.Properties.targets
		System.Data.SQLite\System.Data.SQLite.References.targets = System.Data.SQLite\System.Data.SQLite.References.targets
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.2010", "System.Data.SQLite\System.Data.SQLite.2010.csproj", "{AC139952-261A-4463-B6FA-AEBC25283A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Module.2010", "System.Data.SQLite\System.Data.SQLite.Module.2010.csproj", "{AC139952-261A-4463-B6FA-AEBC25284A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test.2010", "test\test.2010.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.2010", "SQLite.Interop\SQLite.Interop.2010.vcxproj", "{53784BC1-A8BC-4AC8-8A3E-158D6807345A}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Linq.2010", "System.Data.SQLite.Linq\System.Data.SQLite.Linq.2010.csproj", "{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite.Designer.2010", "SQLite.Designer\SQLite.Designer.2010.csproj", "{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testlinq.2010", "testlinq\testlinq.2010.csproj", "{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25283A66} = {AC139952-261A-4463-B6FA-AEBC25283A66}
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D} = {E6BF9F74-58E2-413B-A7CE-EA653ECB728D}
	EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.Static.2010", "SQLite.Interop\SQLite.Interop.Static.2010.vcxproj", "{490CBC51-A3B2-4397-89F9-16E858DCB4F8}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer.2010", "tools\install\Installer.2010.csproj", "{A41FE2A5-07AD-4CE7-B836-1544634816F5}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Debug|Mixed Platforms = Debug|Mixed Platforms
		Debug|Win32 = Debug|Win32
		Debug|x64 = Debug|x64
		DebugNativeOnly|Any CPU = DebugNativeOnly|Any CPU
		DebugNativeOnly|Mixed Platforms = DebugNativeOnly|Mixed Platforms
		DebugNativeOnly|Win32 = DebugNativeOnly|Win32
		DebugNativeOnly|x64 = DebugNativeOnly|x64
		Release|Any CPU = Release|Any CPU
		Release|Mixed Platforms = Release|Mixed Platforms
		Release|Win32 = Release|Win32
		Release|x64 = Release|x64
		ReleaseNativeOnly|Any CPU = ReleaseNativeOnly|Any CPU
		ReleaseNativeOnly|Mixed Platforms = ReleaseNativeOnly|Mixed Platforms
		ReleaseNativeOnly|Win32 = ReleaseNativeOnly|Win32
		ReleaseNativeOnly|x64 = ReleaseNativeOnly|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.ActiveCfg = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.Build.0 = Debug|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.ActiveCfg = Debug|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.Build.0 = Debug|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.ActiveCfg = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.Build.0 = Release|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.ActiveCfg = Release|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.Build.0 = Release|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|Win32.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Debug|x64.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Any CPU.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|Win32.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|x64.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.Release|x64.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Any CPU.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|Win32.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Debug|x64.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Any CPU.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|Win32.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.Release|x64.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.ActiveCfg = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.Build.0 = Debug|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.ActiveCfg = Debug|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.Build.0 = Debug|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.ActiveCfg = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.Build.0 = Release|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.ActiveCfg = Release|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.Build.0 = Release|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64
		{490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU
		{A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.NET.Settings.targets.
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
<!--
 *
 * SQLite.NET.Settings.targets -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!--
  ******************************************************************************
  **                          Load Per-User Settings                          **
  ******************************************************************************
  -->

  <!--
      NOTE: If the per-user settings file exists, import it now.  The contained
            settings, if any, will override the default ones provided below.
  -->
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets.user"
          Condition="Exists('$(SQLiteNetDir)\SQLite.NET.Settings.targets.user')" />

  <!--
  ******************************************************************************
  **                       [Fairly] Generic Properties                        **
  ******************************************************************************
  -->

  <PropertyGroup>
    <!--
        NOTE: *UNCONDITIONAL* We never want to use the hosting process for
              debugging.  It causes problems.
    -->
    <UseVSHostingProcess>false</UseVSHostingProcess>

    <!--
        NOTE: *UNCONDITIONAL* We never want to use the fast up-to-date check
              that Visual Studio provides.
    -->
    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>

    <!--
        HACK: *UNCONDITIONAL* The Visual Studio IDE ignores the
              BaseIntermediateOutputPath property and creates empty "bin" and
              "obj" directories for every project whenever the project is opened
              or built.  Also, the Visual Studio IDE will occasionally fail to
              rebuild the project due to this confusion.  The situation appears
              to improve somewhat when this is set to false.  Please note that
              even if this is set to false, things still do not work 100%
              correctly; however, at least there appears to be less build
              failures.

              Please see Microsoft Connect FeedbackID 105854 for their official
              list of excuses, on this now more than 3 year old bug.
    -->
    <UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
  </PropertyGroup>

  <!--
  ******************************************************************************
  **                            Common Properties                             **
  ******************************************************************************
  -->

  <PropertyGroup>
    <!--
        NOTE: Only use functionality available in the .NET Framework 2.0?  By
              default, this is disabled.  This must be enabled to successfully
              build the project using Visual Studio 2008 and/or the .NET
              Framework 2.0 (if necessary, it will typically be enabled from
              within the project file itself).
    -->
    <NetFx20 Condition="'$(NetFx20)' == ''">false</NetFx20>

    <!--
        NOTE: The suffix for the name of the build configuration directory .  By
              default, this is an empty string.
    -->
    <ConfigurationSuffix Condition="'$(ConfigurationSuffix)' == ''"></ConfigurationSuffix>

    <!--
        NOTE: For interaction with the native SQLite implementation, use the
              custom built interop DLL (i.e. "SQLite.Interop.dll")?  By default,
              this is enabled.  This property is mutually exclusive with the
              "UseSqliteStandard" one, below.  This should always be disabled in
              the project file that builds the NetModule target.
    -->
    <UseInteropDll Condition="'$(UseInteropDll)' == ''">true</UseInteropDll>

    <!--
        NOTE: For interaction with the native SQLite implementation, use the
              standard DLL (i.e. "sqlite3.dll")?  By default, this is disabled.
              This property is mutually exclusive with the "UseInteropDll" one,
              above.  This should always be disabled in the project file that
              builds the NetModule target.
    -->
    <UseSqliteStandard Condition="'$(UseSqliteStandard)' == ''">false</UseSqliteStandard>

    <!--
        NOTE: Is the project being built to support the .NET Compact Framework?
    -->
    <IsCompactFramework Condition="'$(IsCompactFramework)' == ''">false</IsCompactFramework>

    <!--
        NOTE: Emit an AssemblyFlags attribute that includes the Retargetable
              flag from the AssemblyNameFlags enumeration?
    -->
    <IsRetargetable Condition="'$(IsRetargetable)' == ''">false</IsRetargetable>

    <!--
        NOTE: Throw an exception if an object has already been disposed?  By
              default, this is enabled.  If this is disabled, an exception will
              not be thrown when a SQLite object which has already been disposed
              is accessed.
    -->
    <ThrowOnDisposed Condition="'$(ThrowOnDisposed)' == ''">true</ThrowOnDisposed>
  </PropertyGroup>

  <!--
  ******************************************************************************
  **                            Warning Properties                            **
  ******************************************************************************
  -->

  <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <!--
        NOTE: Debug build.  Set the warning level to maximum.  Also, disable
              warnings that tend to cause too much noise.
    -->
    <WarningLevel>4</WarningLevel>
    <NoWarn>618,1591;3001</NoWarn>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <!--
        NOTE: Release build.  Set the warning level to maximum.  Also, disable
              warnings that tend to cause too much noise.
    -->
    <WarningLevel>4</WarningLevel>
    <NoWarn>618,1591;3001</NoWarn>
  </PropertyGroup>

  <!--
  ******************************************************************************
  **                         Relative Path Properties                         **
  ******************************************************************************
  -->

  <PropertyGroup Condition="'$(SQLiteNetDir)' != ''">
    <!--
        NOTE: Keep all the intermediate files in one place.  The Visual Studio
              IDE seems to have a nasty habit of ignoring this setting.  The
              Visual Studio IDE then fails to build the project(s) properly when
              the output does not end up where it expects the output to be.  The
              value of this property must have a trailing backslash.
    -->
    <BaseIntermediateOutputPath Condition="'$(ConfigurationSuffix)' == ''">$(SQLiteNetDir)\obj\$(ConfigurationYear)\</BaseIntermediateOutputPath>
    <BaseIntermediateOutputPath Condition="'$(ConfigurationSuffix)' != ''">$(SQLiteNetDir)\obj\$(ConfigurationYear)\$(ConfigurationSuffix)\</BaseIntermediateOutputPath>
  </PropertyGroup>

  <!--
  ******************************************************************************
  **                Per-Configuration Relative Path Properties                **
  ******************************************************************************
  -->

  <PropertyGroup Condition="'$(SQLiteNetDir)' != '' And '$(Configuration)' != ''">
    <!--
        NOTE: The final output files need to end up in one place.  The value of
              this property must have a trailing backslash.
    -->
    <BinaryOutputPath Condition="'$(BinaryOutputPath)' == ''">$(SQLiteNetDir)\bin\$(ConfigurationYear)\$(Configuration)$(ConfigurationSuffix)\bin\</BinaryOutputPath>
  </PropertyGroup>

  <!--
  ******************************************************************************
  **                      Strong Name Signing Properties                      **
  ******************************************************************************
  -->

  <PropertyGroup Condition="'$(SQLiteNetDir)' != '' And
                            !HasTrailingSlash('$(SQLiteNetDir)') And
                            (('$(IsCompactFramework)' == 'false' And Exists('$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.snk')) Or
                             ('$(IsCompactFramework)' != 'false' And Exists('$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.CF.snk')))">
    <!--
        NOTE: Sign the assembly?  By default, this is enabled.
    -->
    <SignAssembly Condition="'$(SignAssembly)' == ''">true</SignAssembly>

    <!--
        NOTE: Use delay signing?  By default, this is disabled because the
              default strong name key pair is included with the source code.
    -->
    <DelaySign Condition="'$(DelaySign)' == ''">false</DelaySign>

    <!--
        NOTE: The full path and file name for the strong name key pair to use.
    -->
    <AssemblyOriginatorKeyFile Condition="'$(AssemblyOriginatorKeyFile)' == '' And '$(IsCompactFramework)' == 'false'">$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.snk</AssemblyOriginatorKeyFile>
    <AssemblyOriginatorKeyFile Condition="'$(AssemblyOriginatorKeyFile)' == '' And '$(IsCompactFramework)' != 'false'">$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.CF.snk</AssemblyOriginatorKeyFile>
  </PropertyGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































Added SQLite.NET.sln.






















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite", "System.Data.SQLite\System.Data.SQLite.csproj", "{AC139951-261A-4463-B6FA-AEBC25283A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}"
	ProjectSection(SolutionItems) = postProject
		readme.htm = readme.htm
	EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop", "SQLite.Interop\SQLite.Interop.vcproj", "{10B51CE8-A838-44DE-BD82-B658F0296F80}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Debug|Mixed Platforms = Debug|Mixed Platforms
		Debug|Win32 = Debug|Win32
		Release|Any CPU = Release|Any CPU
		Release|Mixed Platforms = Release|Mixed Platforms
		Release|Win32 = Release|Win32
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Any CPU.ActiveCfg = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Win32.ActiveCfg = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Win32.Build.0 = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Any CPU.ActiveCfg = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Mixed Platforms.Build.0 = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Win32.ActiveCfg = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Win32.Build.0 = Release|Win32
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
Deleted SQLite.nuspec.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="utf-8"?>
<package>
  <metadata>
    <id>System.Data.SQLite</id>
    <title>System.Data.SQLite (x86)</title>
    <version>1.0.77.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>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\Win32\ReleaseStatic\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\Win32\ReleaseStatic\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
  </files>
</package>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Deleted SQLite.x64.nuspec.
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"?>
<package>
  <metadata>
    <id>System.Data.SQLite.x64</id>
    <version>1.0.77.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>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\x64\ReleaseStatic\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\x64\ReleaseStatic\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
  </files>
</package>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted SQLite.x86.nuspec.
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"?>
<package>
  <metadata>
    <id>System.Data.SQLite.x86</id>
    <version>1.0.77.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>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\Win32\ReleaseStatic\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\Win32\ReleaseStatic\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
  </files>
</package>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted Setup/CheckForNetFx.pas.
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
{
  CheckForNetFx.iss --

  Written by Joe Mistachkin.
  Released to the public domain, use at your own risk!
}

var
  IsNetFx2Setup : Boolean;
  IsNetFx4Setup : Boolean;

  NetFxSubKeyName: String;
  NetFxInstallRoot: String;
  NetFxSetupSubKeyName: String;
  NetFxIsInstalled: String;

  NetFx2Version: String;
  NetFx2SetupVersion: String;
  NetFx2HasServicePack: String;
  NetFx2ServicePack: Integer;
  NetFx2ErrorMessage: String;

  NetFx35SetupVersion: String;
  NetFx35HasServicePack: String;
  NetFx35ServicePack: Integer;
  NetFx35ErrorMessage: String;

  NetFx4Version: String;
  NetFx4SetupVersion: String;
  NetFx4HasServicePack: String;
  NetFx4ServicePack: Integer;
  NetFx4ErrorMessage: String;

  VcRuntimeRedistributable: String;

function CheckForNetFx2(const NeedServicePack: Integer): Boolean;
var
  SubKeyName: String;
  IsInstalled: Cardinal;
  HasServicePack: Cardinal;
begin
  Result := False;

  SubKeyName := NetFxSetupSubKeyName + '\' + NetFx2SetupVersion;

  if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFxIsInstalled,
      IsInstalled) then
  begin
    if IsInstalled <> 0 then
    begin
      if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName,
          NetFx2HasServicePack, HasServicePack) then
      begin
        if HasServicePack >= NeedServicePack then
        begin
          Result := True;
        end;
      end;
    end;
  end;
end;

function CheckForNetFx35(const NeedServicePack: Integer): Boolean;
var
  SubKeyName: String;
  IsInstalled: Cardinal;
  HasServicePack: Cardinal;
begin
  Result := False;

  SubKeyName := NetFxSetupSubKeyName + '\' + NetFx35SetupVersion;

  if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFxIsInstalled,
      IsInstalled) then
  begin
    if IsInstalled <> 0 then
    begin
      if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName,
          NetFx35HasServicePack, HasServicePack) then
      begin
        if HasServicePack >= NeedServicePack then
        begin
          Result := True;
        end;
      end;
    end;
  end;
end;

function CheckForNetFx4(const NeedServicePack: Integer): Boolean;
var
  SubKeyName: String;
  IsInstalled: Cardinal;
  HasServicePack: Cardinal;
begin
  Result := False;

  SubKeyName := NetFxSetupSubKeyName + '\' + NetFx4SetupVersion;

  if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFxIsInstalled,
      IsInstalled) then
  begin
    if IsInstalled <> 0 then
    begin
      if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName,
          NetFx4HasServicePack, HasServicePack) then
      begin
        if HasServicePack >= NeedServicePack then
        begin
          Result := True;
        end;
      end;
    end;
  end;
end;

function GetNetFx2InstallRoot(const FileName: String): String;
var
  InstallRoot: String;
begin
  Result := '';

  if RegQueryStringValue(HKEY_LOCAL_MACHINE, NetFxSubKeyName,
      NetFxInstallRoot, InstallRoot) then
  begin
    Result := InstallRoot + '\' + NetFx2Version;

    if FileName <> '' then
    begin
      Result := Result + '\' + FileName;
    end;
  end;
end;

function GetNetFx4InstallRoot(const FileName: String): String;
var
  InstallRoot: String;
begin
  Result := '';

  if RegQueryStringValue(HKEY_LOCAL_MACHINE, NetFxSubKeyName,
      NetFxInstallRoot, InstallRoot) then
  begin
    Result := InstallRoot + '\' + NetFx4Version;

    if FileName <> '' then
    begin
      Result := Result + '\' + FileName;
    end;
  end;
end;

function CheckIsNetFx2Setup(): Boolean;
begin
  Result := IsNetFx2Setup;
end;

function CheckIsNetFx4Setup(): Boolean;
begin
  Result := IsNetFx4Setup;
end;

function ExtractAndInstallVcRuntime(var ResultCode: Integer): Boolean;
begin
  ExtractTemporaryFile(VcRuntimeRedistributable);

  if Exec(ExpandConstant(
      '{tmp}\' + VcRuntimeRedistributable),
      '/q', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
  begin
    Result := True;
  end
  else begin
    Result := False;
  end;
end;

function NetFxInitializeSetup(): Boolean;
var
  ResultCode: Integer;
begin
  IsNetFx2Setup := {#IsNetFx2};
  IsNetFx4Setup := not IsNetFx2Setup;

  NetFxSubKeyName := 'Software\Microsoft\.NETFramework';
  NetFxInstallRoot := 'InstallRoot';
  NetFxSetupSubKeyName := 'Software\Microsoft\NET Framework Setup\NDP';
  NetFxIsInstalled := 'Install';

  NetFx2Version := 'v2.0.50727';
  NetFx2SetupVersion := 'v2.0.50727';
  NetFx2HasServicePack := 'SP';
  NetFx2ServicePack := 2;
  NetFx2ErrorMessage := 'The Microsoft .NET Framework v2.0 with Service Pack '
      + IntToStr(NetFx2ServicePack) + ' or higher is required.';

  NetFx35SetupVersion := 'v3.5';
  NetFx35HasServicePack := 'SP';
  NetFx35ServicePack := 1;
  NetFx35ErrorMessage := 'The Microsoft .NET Framework v3.5 with Service Pack '
      + IntToStr(NetFx35ServicePack) + ' or higher is required for LINQ support.';

  NetFx4Version := 'v4.0.30319';
  NetFx4SetupVersion := 'v4\Full';
  NetFx4HasServicePack := 'Servicing';
  NetFx4ServicePack := 0;
  NetFx4ErrorMessage := 'The Microsoft .NET Framework v4.0 with Service Pack '
      + IntToStr(NetFx4ServicePack) + ' or higher is required.';

  VcRuntimeRedistributable := 'vcredist_{#AppProcessor}_{#VcRuntime}.exe';

  if IsNetFx2Setup then
  begin
    Result := CheckForNetFx2(NetFx2ServicePack);

    if not Result then
    begin
      MsgBox(NetFx2ErrorMessage, mbError, MB_OK);
    end;

    if Result and not CheckForNetFx35(NetFx35ServicePack) then
    begin
      MsgBox(NetFx35ErrorMessage, mbInformation, MB_OK);
    end;
  end;

  if IsNetFx4Setup then
  begin
    Result := CheckForNetFx4(NetFx4ServicePack);

    if not Result then
    begin
      MsgBox(NetFx4ErrorMessage, mbError, MB_OK);
    end;
  end;

  if Result then
  begin
    Result := ExtractAndInstallVcRuntime(ResultCode);

    if not Result or (ResultCode <> 0) then
    begin
      MsgBox('Failed to install Microsoft Visual C++ Runtime: ' +
          VcRuntimeRedistributable + ', ' + SysErrorMessage(ResultCode),
          mbError, MB_OK);

      if Result then
      begin
        Result := False;
      end;
    end;
  end;
end;

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































Deleted Setup/InitializeSetup.pas.
1
2
3
4
5
6
7
8
9
10
11
12
{
  InitializeSetup.iss --

  Written by Joe Mistachkin.
  Released to the public domain, use at your own risk!
}

function InitializeSetup(): Boolean;
begin
  Result := NetFxInitializeSetup();
end;

<
<
<
<
<
<
<
<
<
<
<
<
























Deleted Setup/SQLite.iss.
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
;
; SQLite.iss --
;
; Written by Joe Mistachkin.
; Released to the public domain, use at your own risk!
;

#define BaseConfiguration StringChange(AppConfiguration, "NativeOnly", "")
#define GacProcessor StringChange(AppProcessor, "x64", "amd64")

#if Pos("NativeOnly", AppConfiguration) == 0
#define AppVersion GetStringFileInfo("..\bin\" + Year + "\" + AppPlatform + "\" + AppConfiguration + "\System.Data.SQLite.dll", PRODUCT_VERSION)
#define OutputConfiguration StringChange(StringChange(AppConfiguration, "Debug", "setup"), "Release", "setup") + "-bundle"
#else
#define AppVersion GetStringFileInfo("..\bin\" + Year + "\" + BaseConfiguration + "\bin\System.Data.SQLite.dll", PRODUCT_VERSION)
#define OutputConfiguration StringChange(StringChange(BaseConfiguration, "Debug", "setup"), "Release", "setup")
#endif

[Setup]
AllowNoIcons=true

#if AppProcessor != "x86"
ArchitecturesAllowed={#AppProcessor}
ArchitecturesInstallIn64BitMode={#AppProcessor}
#endif

AlwaysShowComponentsList=false
AppCopyright=Public Domain
AppID={#AppId}
AppName=System.Data.SQLite
AppPublisher=System.Data.SQLite Team
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
AppVerName=System.Data.SQLite v{#AppVersion}
AppVersion={#AppVersion}
AppComments=The ADO.NET adapter for the SQLite database engine.
AppReadmeFile={app}\readme.htm
DefaultDirName={pf}\System.Data.SQLite\{#Year}
DefaultGroupName=System.Data.SQLite\{#Year}
OutputBaseFilename=sqlite-{#Framework}-{#OutputConfiguration}-{#AppProcessor}-{#Year}-{#AppVersion}
OutputManifestFile=sqlite-{#Framework}-{#OutputConfiguration}-{#AppProcessor}-{#Year}-{#AppVersion}-manifest.txt
SetupLogging=true
UninstallFilesDir={app}\uninstall
VersionInfoVersion={#AppVersion}
ExtraDiskSpaceRequired=2097152
ChangesEnvironment=true

[Code]
#include "CheckForNetFx.pas"
#include "InitializeSetup.pas"

[Components]
Name: Application; Description: System.Data.SQLite components.; Types: custom compact full
Name: Application\Core; Description: Core components.; Types: custom compact full
Name: Application\Core\MSIL; Description: Core managed components.; Types: custom compact full
Name: Application\Core\{#AppProcessor}; Description: Core native components.; Types: custom compact full
Name: Application\LINQ; Description: LINQ support components.; Types: custom compact full
Name: Application\Symbols; Description: Debugging symbol components.; Types: custom compact full
Name: Application\Documentation; Description: Documentation components.; Types: custom compact full
Name: Application\Test; Description: Test components.; Types: custom compact full

[Tasks]
Components: Application\Core\MSIL Or Application\LINQ; Name: ngen; Description: Generate native images for the assemblies and install the images in the native image cache.; Check: CheckIsNetFx2Setup() or CheckIsNetFx4Setup()

#if Pos("NativeOnly", AppConfiguration) == 0
Components: Application\Core\MSIL Or Application\LINQ; Name: gac; Description: Install the assemblies into the global assembly cache.; Flags: unchecked; Check: CheckIsNetFx2Setup() or CheckIsNetFx4Setup()
#endif

[Run]
Components: Application\Core\MSIL; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup()
Components: Application\Core\MSIL; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() and CheckForNetFx35(1)
Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()

[UninstallRun]
Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() and CheckForNetFx35(1)
Components: Application\Core\MSIL; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
Components: Application\Core\MSIL; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup()

[Dirs]
Name: {app}\bin
Name: {app}\doc

#if Pos("NativeOnly", AppConfiguration) == 0
Name: {app}\GAC
#endif

[Files]
Components: Application\Core\{#AppProcessor}; Source: ..\Externals\MSVCPP\vcredist_{#AppProcessor}_{#VcRuntime}.exe; DestDir: {tmp}; Flags: dontcopy
Components: Application; Source: ..\readme.htm; DestDir: {app}; Flags: restartreplace uninsrestartdelete isreadme

#if Pos("NativeOnly", AppConfiguration) == 0
Components: Application\Core\MSIL; Tasks: gac; Source: ..\bin\{#Year}\{#AppPlatform}\{#AppConfiguration}\System.Data.SQLite.dll; DestDir: {app}\GAC; StrongAssemblyName: "System.Data.SQLite, Version={#AppVersion}, Culture=neutral, PublicKeyToken={#AppPublicKey}, ProcessorArchitecture={#GacProcessor}"; Flags: restartreplace uninsrestartdelete uninsnosharedfileprompt sharedfile gacinstall
Components: Application\Core\MSIL; Source: ..\bin\{#Year}\{#AppPlatform}\{#AppConfiguration}\System.Data.SQLite.dll; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Core\MSIL and Application\Symbols; Source: ..\bin\{#Year}\{#AppPlatform}\{#AppConfiguration}\System.Data.SQLite.pdb; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
#else
Components: Application\Core\MSIL; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\System.Data.SQLite.dll; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Core\MSIL and Application\Symbols; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\System.Data.SQLite.pdb; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
#endif

#if Pos("NativeOnly", AppConfiguration) == 0
Components: Application\LINQ; Tasks: gac; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\System.Data.SQLite.Linq.dll; DestDir: {app}\GAC; StrongAssemblyName: "System.Data.SQLite.Linq, Version={#AppVersion}, Culture=neutral, PublicKeyToken={#AppPublicKey}, ProcessorArchitecture=MSIL"; Flags: restartreplace uninsrestartdelete uninsnosharedfileprompt sharedfile gacinstall
#endif

Components: Application\LINQ; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\System.Data.SQLite.Linq.dll; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\LINQ and Application\Symbols; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\System.Data.SQLite.Linq.pdb; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete

#if Pos("NativeOnly", AppConfiguration) != 0
Components: Application\Core\{#AppProcessor}; Source: ..\bin\{#Year}\{#AppPlatform}\{#AppConfiguration}\SQLite.Interop.dll; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Core\{#AppProcessor} and Application\Symbols; Source: ..\bin\{#Year}\{#AppPlatform}\{#AppConfiguration}\SQLite.Interop.pdb; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
#endif

Components: Application\Documentation; Source: ..\doc\SQLite.NET.chm; DestDir: {app}\doc; Flags: restartreplace uninsrestartdelete
Components: Application\Test; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\test.exe; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Test and Application\Symbols; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\test.pdb; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Test; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\test.exe.config; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Test and Application\LINQ; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\testlinq.exe; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Test and Application\LINQ and Application\Symbols; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\testlinq.pdb; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Test and Application\LINQ; Source: ..\bin\{#Year}\{#BaseConfiguration}\bin\testlinq.exe.config; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete
Components: Application\Test and Application\LINQ; Source: ..\testlinq\northwindEF.db; DestDir: {app}\bin; Flags: restartreplace uninsrestartdelete

[Icons]
Name: {group}\Test Application; Filename: {app}\bin\test.exe; WorkingDir: {app}\bin; IconFilename: {app}\bin\test.exe; Comment: Launch Test Application; IconIndex: 0; Flags: createonlyiffileexists
Name: {group}\Class Library Documentation; Filename: {app}\doc\SQLite.NET.chm; WorkingDir: {app}\doc; Comment: Launch Class Library Documentation; Flags: createonlyiffileexists
Name: {group}\README File; Filename: {app}\readme.htm; WorkingDir: {app}; Comment: View README File; Flags: createonlyiffileexists
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































Deleted Setup/archive.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
@ECHO OFF

::
:: archive.bat --
::
:: Source Archiving Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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:\\=\%

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

%_VECHO% Root = '%ROOT%'
%_VECHO% Tools = '%TOOLS%'

CALL :fn_ResetErrorLevel

%_ECHO% PUSHD "%ROOT%"

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

FOR /F "delims=" %%V IN ('find.exe "AssemblyVersion" System.Data.SQLite\AssemblyInfo.cs') DO (
  SET VERSION=%%V
)

IF NOT DEFINED VERSION (
  SET VERSION=1.0.0.0
  GOTO skip_mungeVersion
)

REM
REM NOTE: Strip off all the extra stuff from the AssemblyVersion line we found
REM       in the AssemblyInfo.cs file that we do not need (i.e. everything
REM       except the raw version number itself).
REM
SET VERSION=%VERSION:(=%
SET VERSION=%VERSION:)=%
SET VERSION=%VERSION:[=%
SET VERSION=%VERSION:]=%
SET VERSION=%VERSION: =%
SET VERSION=%VERSION:assembly:=%
SET VERSION=%VERSION:AssemblyVersion=%
SET VERSION=%VERSION:"=%
REM "

:skip_mungeVersion

%_VECHO% Version = '%VERSION%'

CALL :fn_ResetErrorLevel

IF NOT EXIST Setup\Output (
  %_ECHO% MKDIR Setup\Output

  IF ERRORLEVEL 1 (
    ECHO Could not create directory "Setup\Output".
    GOTO errors
  )
)

%_ECHO% zip.exe -v -r Setup\Output\sqlite-netFx-source-%VERSION%.zip * -x @exclude_src.txt

IF ERRORLEVEL 1 (
  ECHO Failed to archive source files.
  GOTO errors
)

%_ECHO% 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
  ECHO.
  GOTO errors

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

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































Deleted Setup/bake.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
@ECHO OFF

::
:: bake.bat --
::
:: Setup Preparation & Baking Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

IF NOT DEFINED FRAMEWORK (
  IF DEFINED YEAR (
    CALL :fn_SetVariable FRAMEWORK FRAMEWORK%YEAR%
  ) ELSE (
    SET FRAMEWORK=netFx20
  )
)

%_VECHO% Framework = '%FRAMEWORK%'

IF "%PROCESSOR_ARCHITECTURE%"=="x86" GOTO set_path_32
SET PATH=%ProgramFiles(x86)%\Inno Setup 5;%PATH%
GOTO set_path_done
:set_path_32
SET PATH=%ProgramFiles%\Inno Setup 5;%PATH%
:set_path_done

%_VECHO% Path = '%PATH%'

%_ECHO% ISCC.exe "%TOOLS%\SQLite.iss" "/dAppId=%APPID%" "/dAppPublicKey=%PUBLICKEY%" "/dAppURL=%URL%" "/dIsNetFx2=%ISNETFX2%" "/dVcRuntime=%VCRUNTIME%" "/dAppConfiguration=%CONFIGURATION%" "/dAppPlatform=%PLATFORM%" "/dAppProcessor=%PROCESSOR%" "/dFramework=%FRAMEWORK%" "/dYear=%YEAR%"

IF %ERRORLEVEL% NEQ 0 (
  ECHO Failed to compile setup.
  GOTO errors
)

GOTO no_errors

:fn_SetVariable
  SETLOCAL
  SET _ECHO_CMD=ECHO %%%2%%
  FOR /F "delims=" %%V IN ('%_ECHO_CMD%') DO (
    SET VALUE=%%V
  )
  ENDLOCAL && (
    SET %1=%VALUE%
  )
  GOTO :EOF

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

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

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































Deleted Setup/bake_all.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
102
103
104
105
@ECHO OFF

::
:: bake_all.bat --
::
:: Multi-Setup Preparation & Baking Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

CALL :fn_ResetErrorLevel

%_ECHO% CALL "%TOOLS%\vsSp.bat"

IF ERRORLEVEL 1 (
  ECHO Could not detect Visual Studio.
  GOTO errors
)

%_ECHO% CALL "%TOOLS%\set_common.bat"

IF ERRORLEVEL 1 (
  ECHO Could not set common variables.
  GOTO errors
)

IF NOT DEFINED BAKE_CONFIGURATIONS (
  SET BAKE_CONFIGURATIONS=Release
)

%_VECHO% BakeConfigurations = '%BAKE_CONFIGURATIONS%'

IF NOT DEFINED PROCESSORS (
  SET PROCESSORS=x86
)

%_VECHO% Processors = '%PROCESSORS%'

IF NOT DEFINED YEARS (
  SET YEARS=2008
)

%_VECHO% Years = '%YEARS%'

FOR %%C IN (%BAKE_CONFIGURATIONS%) DO (
  FOR %%P IN (%PROCESSORS%) DO (
    FOR %%Y IN (%YEARS%) DO (
      %_ECHO% CALL "%TOOLS%\set_%%C_%%P_%%Y.bat"

      IF ERRORLEVEL 1 (
        ECHO Could not set variables for %%C/%%P/%%Y.
        GOTO errors
      )

      %_ECHO% CALL "%TOOLS%\bake.bat"

      IF ERRORLEVEL 1 (
        ECHO Could not bake setup for %%C/%%P/%%Y.
        GOTO errors
      )
    )
  )
)

GOTO no_errors

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

: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%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































Deleted Setup/build.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
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
@ECHO OFF

::
:: build.bat --
::
:: Wrapper Tool for MSBuild
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 CONFIGURATION=%1

IF DEFINED CONFIGURATION (
  CALL :fn_UnquoteVariable CONFIGURATION
) ELSE (
  %_AECHO% No configuration specified, using default...
  SET CONFIGURATION=Release
)

%_VECHO% Configuration = '%CONFIGURATION%'

SET PLATFORM=%2

IF DEFINED PLATFORM (
  CALL :fn_UnquoteVariable PLATFORM
) ELSE (
  %_AECHO% No platform specified, using default...
  SET PLATFORM=Win32
)

%_VECHO% Platform = '%PLATFORM%'

SET TOOLS=%~dp0
SET TOOLS=%TOOLS:\\=\%

%_VECHO% Tools = '%TOOLS%'

IF EXIST "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat" (
  CALL :fn_ResetErrorLevel

  %_AECHO% Running "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat"...
  %_ECHO% CALL "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat"

  IF ERRORLEVEL 1 (
    ECHO File "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat" failed.
    GOTO errors
  )
)

IF DEFINED NETFX20ONLY (
  %_AECHO% Forcing the use of the .NET Framework 2.0...
  SET YEAR=2005
  SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v2.0.50727
  GOTO skip_netFxCheck
)

IF DEFINED NETFX35ONLY (
  %_AECHO% Forcing the use of the .NET Framework 3.5...
  SET YEAR=2008
  SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v3.5
  GOTO skip_netFxCheck
)

IF DEFINED NETFX40ONLY (
  %_AECHO% Forcing the use of the .NET Framework 4.0...
  SET YEAR=2010
  SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v4.0.30319
  GOTO skip_netFxCheck
)

IF DEFINED FRAMEWORKDIR (
  IF NOT EXIST "%FRAMEWORKDIR%" (
    CALL :fn_UnsetVariable FRAMEWORKDIR
  )
)

IF DEFINED FRAMEWORKDIR (
  IF NOT EXIST "%FRAMEWORKDIR%\csc.exe" (
    CALL :fn_UnsetVariable FRAMEWORKDIR
  )
)

IF NOT DEFINED FRAMEWORKDIR (
  %_AECHO% Checking for the .NET Framework 4.0...
  SET YEAR=2010
  SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v4.0.30319
)

IF NOT EXIST "%FRAMEWORKDIR%" (
  %_AECHO% Checking for the .NET Framework 3.5...
  SET YEAR=2008
  SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v3.5
)

IF NOT EXIST "%FRAMEWORKDIR%" (
  %_AECHO% Checking for the .NET Framework 2.0...
  SET YEAR=2005
  SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v2.0.50727
)

:skip_netFxCheck

IF NOT EXIST "%FRAMEWORKDIR%" (
  ECHO.
  ECHO The .NET Framework directory "%FRAMEWORKDIR%" was not found.
  ECHO.
  ECHO Please install the .NET Framework or set the "FRAMEWORKDIR"
  ECHO environment variable to the location where it is installed.
  ECHO.
  GOTO errors
)

%_VECHO% Year = '%YEAR%'
%_VECHO% FrameworkDir = '%FRAMEWORKDIR%'

CALL :fn_ResetErrorLevel

%_ECHO% PUSHD "%ROOT%"

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

SET PATH=%FRAMEWORKDIR%;%PATH%

%_VECHO% Path = '%PATH%'

IF NOT DEFINED SOLUTION (
  %_AECHO% Building all projects...
  SET SOLUTION=.\SQLite.NET.%YEAR%.MSBuild.sln
)

IF NOT EXIST "%SOLUTION%" (
  %_AECHO% Building all projects...
  SET SOLUTION=.\SQLite.NET.%YEAR%.sln
)

%_VECHO% Solution = '%SOLUTION%'

IF NOT DEFINED TARGET (
  SET TARGET=Rebuild
)

%_VECHO% Target = '%TARGET%'

IF NOT DEFINED TEMP (
  ECHO Temporary directory must be defined.
  GOTO errors
)

%_VECHO% Temp = '%TEMP%'

IF NOT DEFINED LOGDIR (
  SET LOGDIR=%TEMP%
)

%_VECHO% LogDir = '%LOGDIR%'

IF NOT DEFINED LOGPREFIX (
  SET LOGPREFIX=System.Data.SQLite.Build
)

%_VECHO% LogPrefix = '%LOGPREFIX%'

IF NOT DEFINED LOGSUFFIX (
  SET LOGSUFFIX=Unknown
)

%_VECHO% LogSuffix = '%LOGSUFFIX%'

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

%_VECHO% Logging = '%LOGGING%'

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

IF ERRORLEVEL 1 (
  ECHO Build failed.
  GOTO errors
)

%_ECHO% POPD

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

GOTO no_errors

:fn_UnquoteVariable
  SETLOCAL
  IF NOT DEFINED %1 GOTO :EOF
  SET _ECHO_CMD=ECHO %%%1%%
  FOR /F "delims=" %%V IN ('%_ECHO_CMD%') DO (
    SET VALUE=%%V
  )
  SET VALUE=%VALUE:"=%
  REM "
  ENDLOCAL && SET %1=%VALUE%
  GOTO :EOF

:fn_UnsetVariable
  IF NOT "%1" == "" (
    SET %1=
    CALL :fn_ResetErrorLevel
  )
  GOTO :EOF

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

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

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

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































Deleted Setup/build_all.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
102
103
104
105
@ECHO OFF

::
:: build_all.bat --
::
:: Multi-Wrapper Tool for MSBuild
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

CALL :fn_ResetErrorLevel

%_ECHO% CALL "%TOOLS%\vsSp.bat"

IF ERRORLEVEL 1 (
  ECHO Could not detect Visual Studio.
  GOTO errors
)

%_ECHO% CALL "%TOOLS%\set_common.bat"

IF ERRORLEVEL 1 (
  ECHO Could not set common variables.
  GOTO errors
)

IF NOT DEFINED BUILD_CONFIGURATIONS (
  SET BUILD_CONFIGURATIONS=Release
)

%_VECHO% BuildConfigurations = '%BUILD_CONFIGURATIONS%'

IF NOT DEFINED PLATFORMS (
  SET PLATFORMS=Win32
)

%_VECHO% Platforms = '%PLATFORMS%'

IF NOT DEFINED YEARS (
  SET YEARS=2008
)

%_VECHO% Years = '%YEARS%'

FOR %%C IN (%BUILD_CONFIGURATIONS%) DO (
  FOR %%P IN (%PLATFORMS%) DO (
    FOR %%Y IN (%YEARS%) DO (
      %_ECHO% CALL "%TOOLS%\set_%%Y.bat"

      IF ERRORLEVEL 1 (
        ECHO Could not set variables for %%Y.
        GOTO errors
      )

      %_ECHO% CALL "%TOOLS%\build.bat" %%C %%P

      IF ERRORLEVEL 1 (
        ECHO Could not build binaries for %%C/%%P/%%Y.
        GOTO errors
      )
    )
  )
)

GOTO no_errors

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

: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%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































Deleted Setup/build_ce.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
@ECHO OFF

::
:: build_ce.bat --
::
:: WinCE Wrapper Tool for MSBuild
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

SET BUILD_CONFIGURATIONS=Release
SET BASE_CONFIGURATIONSUFFIX=Compact
SET PLATFORMS="Pocket PC 2003 (ARMV4)"
SET PROCESSORS=arm
SET YEARS=2008
SET BASE_PLATFORM=PocketPC

CALL :fn_ResetErrorLevel

%_ECHO% CALL "%TOOLS%\build_all.bat"

IF ERRORLEVEL 1 (
  ECHO Failed to build PocketPC binaries.
  GOTO errors
)

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

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

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

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































Deleted Setup/clean.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
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
@ECHO OFF

::
:: clean.bat --
::
:: Build Cleaning Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 DUMMY2=%1

IF DEFINED DUMMY2 (
  GOTO usage
)

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

%_VECHO% Source = '%SOURCE%'
%_VECHO% Temp = '%TEMP%'

IF NOT DEFINED TEMP (
  ECHO The TEMP environment variable must be set first.
  GOTO usage
)

IF NOT EXIST "%TEMP%" (
  ECHO The TEMP directory, "%TEMP%", does not exist.
  GOTO usage
)

IF DEFINED CLEANDIRS GOTO skip_cleanDirs

SET CLEANDIRS=bin obj Doc\Output Membership\bin Membership\obj Setup\Output
SET CLEANDIRS=%CLEANDIRS% SQLite.Designer\bin SQLite.Designer\obj
SET CLEANDIRS=%CLEANDIRS% SQLite.Interop\bin SQLite.Interop\obj
SET CLEANDIRS=%CLEANDIRS% System.Data.SQLite\bin System.Data.SQLite\obj
SET CLEANDIRS=%CLEANDIRS% System.Data.SQLite.Linq\bin System.Data.SQLite.Linq\obj
SET CLEANDIRS=%CLEANDIRS% test\bin test\obj testce\bin testce\obj testlinq\bin
SET CLEANDIRS=%CLEANDIRS% testlinq\obj tools\install\bin tools\install\obj

:skip_cleanDirs

%_VECHO% CleanDirs = '%CLEANDIRS%'

CALL :fn_ResetErrorLevel

%_AECHO%.

FOR %%D IN (%CLEANDIRS%) DO (
  IF EXIST "%SOURCE%\%%D" (
    %_ECHO% RMDIR /S /Q "%SOURCE%\%%D"

    IF ERRORLEVEL 1 (
      ECHO Could not remove directory "%SOURCE%\%%D".
      ECHO.
      GOTO errors
    ) ELSE (
      %_AECHO% Removed directory "%SOURCE%\%%D".
      %_AECHO%.
    )
  ) ELSE (
    %_AECHO% Directory "%SOURCE%\%%D" does not exist.
    %_AECHO%.
  )
)

IF EXIST "%SOURCE%\*.nupkg" (
  %_ECHO% DEL /Q "%SOURCE%\*.nupkg"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%SOURCE%\*.nupkg".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%SOURCE%\*.nupkg".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%SOURCE%\*.nupkg" exist.
  %_AECHO%.
)

IF EXIST "%SOURCE%\Doc\SQLite.NET.chw" (
  %_ECHO% DEL /Q "%SOURCE%\Doc\SQLite.NET.chw"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%SOURCE%\Doc\SQLite.NET.chw".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%SOURCE%\Doc\SQLite.NET.chw".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%SOURCE%\Doc\SQLite.NET.chw" exist.
  %_AECHO%.
)

IF EXIST "%SOURCE%\Externals\Eagle\bin\sqlite3.*" (
  %_ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\sqlite3.*"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%SOURCE%\Externals\Eagle\bin\sqlite3.*".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%SOURCE%\Externals\Eagle\bin\sqlite3.*".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%SOURCE%\Externals\Eagle\bin\sqlite3.*" exist.
  %_AECHO%.
)

IF EXIST "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*" (
  %_ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*" exist.
  %_AECHO%.
)

IF EXIST "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*" (
  %_ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*" exist.
  %_AECHO%.
)

IF EXIST "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*" (
  %_ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*" exist.
  %_AECHO%.
)

IF EXIST "%TEMP%\EagleShell.exe.test.*.log" (
  %_ECHO% DEL /Q "%TEMP%\EagleShell.exe.test.*.log"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%TEMP%\EagleShell.exe.test.*.log".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%TEMP%\EagleShell.exe.test.*.log".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%TEMP%\EagleShell.exe.test.*.log" exist.
  %_AECHO%.
)

IF EXIST "%TEMP%\mono.exe.test.*.log" (
  %_ECHO% DEL /Q "%TEMP%\mono.exe.test.*.log"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%TEMP%\mono.exe.test.*.log".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%TEMP%\mono.exe.test.*.log".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%TEMP%\mono.exe.test.*.log" exist.
  %_AECHO%.
)

IF EXIST "%TEMP%\tclsh*.exe.test.*.log" (
  %_ECHO% DEL /Q "%TEMP%\tclsh*.exe.test.*.log"

  IF ERRORLEVEL 1 (
    ECHO Could not delete "%TEMP%\tclsh*.exe.test.*.log".
    ECHO.
    GOTO errors
  ) ELSE (
    %_AECHO% Deleted "%TEMP%\tclsh*.exe.test.*.log".
    %_AECHO%.
  )
) ELSE (
  %_AECHO% No files matching "%TEMP%\tclsh*.exe.test.*.log" exist.
  %_AECHO%.
)

GOTO no_errors

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

:usage
  ECHO.
  ECHO Usage: %~nx0
  ECHO.
  ECHO The TEMP environment variable must be set to the full path of the existing
  ECHO directory used to store temporary files.
  GOTO errors

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

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































Deleted Setup/release.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
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
@ECHO OFF

::
:: release.bat --
::
:: Binary Release Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

SET CONFIGURATION=%1

IF DEFINED CONFIGURATION (
  CALL :fn_UnquoteVariable CONFIGURATION
) ELSE (
  %_AECHO% No configuration specified, using default...
  SET CONFIGURATION=Release
)

%_VECHO% Configuration = '%CONFIGURATION%'
%_VECHO% ConfigurationSuffix = '%CONFIGURATIONSUFFIX%'

SET PLATFORM=%2

IF DEFINED PLATFORM (
  CALL :fn_UnquoteVariable PLATFORM
) ELSE (
  %_AECHO% No platform specified, using default...
  SET PLATFORM=Win32
)

%_VECHO% Platform = '%PLATFORM%'

SET YEAR=%3

IF DEFINED YEAR (
  CALL :fn_UnquoteVariable YEAR
) ELSE (
  %_AECHO% No year specified, using default...
  SET YEAR=2008
)

%_VECHO% Year = '%YEAR%'

SET BASE_CONFIGURATION=%CONFIGURATION%
SET BASE_CONFIGURATION=%BASE_CONFIGURATION:ManagedOnly=%
SET BASE_CONFIGURATION=%BASE_CONFIGURATION:NativeOnly=%

%_VECHO% BaseConfiguration = '%BASE_CONFIGURATION%'
%_VECHO% BaseConfigurationSuffix = '%BASE_CONFIGURATIONSUFFIX%'

IF NOT DEFINED BASE_PLATFORM (
  CALL :fn_SetVariable BASE_PLATFORM PLATFORM
)

%_VECHO% BasePlatform = '%BASE_PLATFORM%'

IF NOT DEFINED TYPE (
  IF /I "%CONFIGURATION%" == "%BASE_CONFIGURATION%" (
    SET TYPE=%TYPE_PREFIX%binary-bundle
  ) ELSE (
    SET TYPE=%TYPE_PREFIX%binary
  )
)

%_VECHO% Type = '%TYPE%'

CALL :fn_ResetErrorLevel

%_ECHO% CALL "%TOOLS%\set_common.bat"

IF ERRORLEVEL 1 (
  ECHO Could not set common variables.
  GOTO errors
)

IF NOT DEFINED FRAMEWORK (
  IF DEFINED YEAR (
    CALL :fn_SetVariable FRAMEWORK FRAMEWORK%YEAR%
  ) ELSE (
    SET FRAMEWORK=netFx20
  )
)

%_VECHO% Framework = '%FRAMEWORK%'

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

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

%_VECHO% Root = '%ROOT%'
%_VECHO% Tools = '%TOOLS%'

CALL :fn_ResetErrorLevel

%_ECHO% PUSHD "%ROOT%"

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

FOR /F "delims=" %%V IN ('find.exe "AssemblyVersion" System.Data.SQLite\AssemblyInfo.cs') DO (
  SET VERSION=%%V
)

IF NOT DEFINED VERSION (
  SET VERSION=1.0.0.0
  GOTO skip_mungeVersion
)

REM
REM NOTE: Strip off all the extra stuff from the AssemblyVersion line we found
REM       in the AssemblyInfo.cs file that we do not need (i.e. everything
REM       except the raw version number itself).
REM
SET VERSION=%VERSION:(=%
SET VERSION=%VERSION:)=%
SET VERSION=%VERSION:[=%
SET VERSION=%VERSION:]=%
SET VERSION=%VERSION: =%
SET VERSION=%VERSION:assembly:=%
SET VERSION=%VERSION:AssemblyVersion=%
SET VERSION=%VERSION:"=%
REM "

:skip_mungeVersion

%_VECHO% Version = '%VERSION%'

CALL :fn_ResetErrorLevel

IF NOT EXIST Setup\Output (
  %_ECHO% MKDIR Setup\Output

  IF ERRORLEVEL 1 (
    ECHO Could not create directory "Setup\Output".
    GOTO errors
  )
)

IF DEFINED BASE_CONFIGURATIONSUFFIX (
  %_ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%BASE_CONFIGURATION%%BASE_CONFIGURATIONSUFFIX%\bin" -x @exclude_bin.txt
) ELSE (
  %_ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%BASE_CONFIGURATION%\bin" -x @exclude_bin.txt
)

IF /I "%CONFIGURATION%" == "%BASE_CONFIGURATION%" (
  IF NOT DEFINED BASE_CONFIGURATIONSUFFIX (
    %_ECHO% zip -v -d "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" SQLite.Interop.*
  )
)

%_ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%PLATFORM%\%CONFIGURATION%%CONFIGURATIONSUFFIX%" -x @exclude_bin.txt

IF ERRORLEVEL 1 (
  ECHO Failed to archive binary files.
  GOTO errors
)

%_ECHO% POPD

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

GOTO no_errors

:fn_SetVariable
  SETLOCAL
  SET _ECHO_CMD=ECHO %%%2%%
  FOR /F "delims=" %%V IN ('%_ECHO_CMD%') DO (
    SET VALUE=%%V
  )
  ENDLOCAL && (
    SET %1=%VALUE%
  )
  GOTO :EOF

:fn_UnquoteVariable
  SETLOCAL
  IF NOT DEFINED %1 GOTO :EOF
  SET _ECHO_CMD=ECHO %%%1%%
  FOR /F "delims=" %%V IN ('%_ECHO_CMD%') DO (
    SET VALUE=%%V
  )
  SET VALUE=%VALUE:"=%
  REM "
  ENDLOCAL && SET %1=%VALUE%
  GOTO :EOF

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

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

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

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































Deleted Setup/release_all.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
@ECHO OFF

::
:: release_all.bat --
::
:: Multi-Binary Release Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

CALL :fn_ResetErrorLevel

%_ECHO% CALL "%TOOLS%\vsSp.bat"

IF ERRORLEVEL 1 (
  ECHO Could not detect Visual Studio.
  GOTO errors
)

%_ECHO% CALL "%TOOLS%\set_common.bat"

IF ERRORLEVEL 1 (
  ECHO Could not set common variables.
  GOTO errors
)

IF NOT DEFINED RELEASE_CONFIGURATIONS (
  SET RELEASE_CONFIGURATIONS=Release
)

%_VECHO% ReleaseConfigurations = '%RELEASE_CONFIGURATIONS%'

IF NOT DEFINED PLATFORMS (
  SET PLATFORMS=Win32
)

%_VECHO% Platforms = '%PLATFORMS%'

IF NOT DEFINED YEARS (
  SET YEARS=2008
)

%_VECHO% Years = '%YEARS%'

FOR %%C IN (%RELEASE_CONFIGURATIONS%) DO (
  FOR %%P IN (%PLATFORMS%) DO (
    FOR %%Y IN (%YEARS%) DO (
      %_ECHO% CALL "%TOOLS%\release.bat" %%C %%P %%Y

      IF ERRORLEVEL 1 (
        ECHO Could not build release archive for %%C/%%P/%%Y.
        GOTO errors
      )
    )
  )
)

GOTO no_errors

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

: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%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted Setup/release_ce.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
@ECHO OFF

::
:: release_ce.bat --
::
:: WinCE Binary Release Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

SET RELEASE_CONFIGURATIONS=Release
SET BASE_CONFIGURATIONSUFFIX=Compact
SET PLATFORMS="Pocket PC 2003 (ARMV4)"
SET PROCESSORS=arm
SET YEARS=2008
SET BASE_PLATFORM=PocketPC
SET TYPE=binary

CALL :fn_ResetErrorLevel

%_ECHO% CALL "%TOOLS%\release_all.bat"

IF ERRORLEVEL 1 (
  ECHO Failed to build PocketPC release files.
  GOTO errors
)

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

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

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

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































Deleted Setup/release_static.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
@ECHO OFF

::
:: release_static.bat --
::
:: Static Binary Release Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

SET CONFIGURATIONSUFFIX=Static
SET TYPE_PREFIX=static-

CALL :fn_ResetErrorLevel

%_ECHO% CALL "%TOOLS%\release_all.bat"

IF ERRORLEVEL 1 (
  ECHO Failed to build static release files.
  GOTO errors
)

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

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

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

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































Deleted Setup/set_2008.bat.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ECHO OFF

::
:: set_2008.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET NETFX20ONLY=
SET NETFX40ONLY=
SET NETFX35ONLY=1

VERIFY > NUL
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted Setup/set_2010.bat.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ECHO OFF

::
:: set_2010.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET NETFX20ONLY=
SET NETFX35ONLY=
SET NETFX40ONLY=1

VERIFY > NUL
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted Setup/set_Release.bat.
1
2
3
4
5
6
7
8
9
10
@ECHO OFF

::
:: set_Release.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

REM SET MSBUILD_ARGS=/p:TargetFrameworkVersion=v3.5 /p:PlatformToolset=v100
<
<
<
<
<
<
<
<
<
<




















Deleted Setup/set_ReleaseNativeOnly.bat.
1
2
3
4
5
6
7
8
9
10
@ECHO OFF

::
:: set_ReleaseNativeOnly.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

REM SET MSBUILD_ARGS=/property:TargetFrameworkVersion=v3.5
<
<
<
<
<
<
<
<
<
<




















Deleted Setup/set_ReleaseNativeOnly_Pocket PC 2003 (ARMV4).bat.
1
2
3
4
5
6
7
8
9
10
@ECHO OFF

::
:: set_ReleaseNativeOnly_Pocket PC 2003 (ARMV4).bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

CALL "%~dp0\set_ReleaseNativeOnly.bat"
<
<
<
<
<
<
<
<
<
<




















Deleted Setup/set_ReleaseNativeOnly_Win32.bat.
1
2
3
4
5
6
7
8
9
10
@ECHO OFF

::
:: set_ReleaseNativeOnly_Win32.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

CALL "%~dp0\set_ReleaseNativeOnly.bat"
<
<
<
<
<
<
<
<
<
<




















Deleted Setup/set_ReleaseNativeOnly_x64.bat.
1
2
3
4
5
6
7
8
9
10
@ECHO OFF

::
:: set_ReleaseNativeOnly_x64.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

CALL "%~dp0\set_ReleaseNativeOnly.bat"
<
<
<
<
<
<
<
<
<
<




















Deleted Setup/set_ReleaseNativeOnly_x64_2008.bat.
1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF

::
:: set_ReleaseNativeOnly_x64_2008.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET CONFIGURATION=ReleaseNativeOnly
CALL "%~dp0\set_x64_2008.bat"
<
<
<
<
<
<
<
<
<
<
<






















Deleted Setup/set_ReleaseNativeOnly_x64_2010.bat.
1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF

::
:: set_ReleaseNativeOnly_x64_2010.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET CONFIGURATION=ReleaseNativeOnly
CALL "%~dp0\set_x64_2010.bat"
<
<
<
<
<
<
<
<
<
<
<






















Deleted Setup/set_ReleaseNativeOnly_x86_2008.bat.
1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF

::
:: set_ReleaseNativeOnly_x86_2008.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET CONFIGURATION=ReleaseNativeOnly
CALL "%~dp0\set_x86_2008.bat"
<
<
<
<
<
<
<
<
<
<
<






















Deleted Setup/set_ReleaseNativeOnly_x86_2010.bat.
1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF

::
:: set_ReleaseNativeOnly_x86_2010.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET CONFIGURATION=ReleaseNativeOnly
CALL "%~dp0\set_x86_2010.bat"
<
<
<
<
<
<
<
<
<
<
<






















Deleted Setup/set_Release_Pocket PC 2003 (ARMV4).bat.
1
2
3
4
5
6
7
8
9
10
@ECHO OFF

::
:: set_Release_Pocket PC 2003 (ARMV4).bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

CALL "%~dp0\set_Release.bat"
<
<
<
<
<
<
<
<
<
<




















Deleted Setup/set_Release_Win32.bat.
1
2
3
4
5
6
7
8
9
10
@ECHO OFF

::
:: set_Release_Win32.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

CALL "%~dp0\set_Release.bat"
<
<
<
<
<
<
<
<
<
<




















Deleted Setup/set_Release_x64.bat.
1
2
3
4
5
6
7
8
9
10
@ECHO OFF

::
:: set_Release_x64.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

CALL "%~dp0\set_Release.bat"
<
<
<
<
<
<
<
<
<
<




















Deleted Setup/set_Release_x64_2008.bat.
1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF

::
:: set_Release_x64_2008.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET CONFIGURATION=Release
CALL "%~dp0\set_x64_2008.bat"
<
<
<
<
<
<
<
<
<
<
<






















Deleted Setup/set_Release_x64_2010.bat.
1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF

::
:: set_Release_x64_2010.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET CONFIGURATION=Release
CALL "%~dp0\set_x64_2010.bat"
<
<
<
<
<
<
<
<
<
<
<






















Deleted Setup/set_Release_x86_2008.bat.
1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF

::
:: set_Release_x86_2008.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET CONFIGURATION=Release
CALL "%~dp0\set_x86_2008.bat"
<
<
<
<
<
<
<
<
<
<
<






















Deleted Setup/set_Release_x86_2010.bat.
1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF

::
:: set_Release_x86_2010.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET CONFIGURATION=Release
CALL "%~dp0\set_x86_2010.bat"
<
<
<
<
<
<
<
<
<
<
<






















Deleted Setup/set_common.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
@ECHO OFF

::
:: set_common.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

IF NOT DEFINED APPID (
  SET APPID={{02E43EC2-6B1C-45B5-9E48-941C3E1B204A}
)

IF NOT DEFINED URL (
  SET URL=http://system.data.sqlite.org/
)

IF NOT DEFINED PUBLICKEY (
  SET PUBLICKEY=db937bc2d44ff139
)

IF NOT DEFINED BUILD_CONFIGURATIONS (
  SET BUILD_CONFIGURATIONS=Release ReleaseNativeOnly
)

IF NOT DEFINED BAKE_CONFIGURATIONS (
  SET BAKE_CONFIGURATIONS=Release ReleaseNativeOnly
)

IF NOT DEFINED RELEASE_CONFIGURATIONS (
  SET RELEASE_CONFIGURATIONS=Release ReleaseNativeOnly
)

IF NOT DEFINED PLATFORMS (
  SET PLATFORMS=Win32 x64
)

IF NOT DEFINED PROCESSORS (
  SET PROCESSORS=x86 x64
)

IF NOT DEFINED FRAMEWORK2008 (
  SET FRAMEWORK2008=netFx35
)

IF NOT DEFINED FRAMEWORK2010 (
  SET FRAMEWORK2010=netFx40
)

IF DEFINED YEARS GOTO end_of_file

IF DEFINED VS2008SP (
  SET YEARS=%YEARS% 2008
)

IF DEFINED VS2010SP (
  SET YEARS=%YEARS% 2010
)

:end_of_file
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































Deleted Setup/set_x64_2008.bat.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ECHO OFF

::
:: set_x64_2008.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET ISNETFX2=True
SET VCRUNTIME=2008_SP1
SET PLATFORM=x64
SET PROCESSOR=x64
SET YEAR=2008
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted Setup/set_x64_2010.bat.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ECHO OFF

::
:: set_x64_2010.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET ISNETFX2=True
SET VCRUNTIME=2010_SP1
SET PLATFORM=x64
SET PROCESSOR=x64
SET YEAR=2010
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted Setup/set_x86_2008.bat.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ECHO OFF

::
:: set_x86_2008.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET ISNETFX2=True
SET VCRUNTIME=2008_SP1
SET PLATFORM=Win32
SET PROCESSOR=x86
SET YEAR=2008
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted Setup/set_x86_2010.bat.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ECHO OFF

::
:: set_x86_2010.bat --
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SET ISNETFX2=True
SET VCRUNTIME=2010_SP1
SET PLATFORM=Win32
SET PROCESSOR=x86
SET YEAR=2010
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted Setup/test_all.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
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
@ECHO OFF

::
:: test_all.bat --
::
:: Multiplexing Wrapper Tool for Unit Tests
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 DUMMY2=%1

IF DEFINED DUMMY2 (
  GOTO usage
)

REM SET DFLAGS=/L

%_VECHO% DFlags = '%DFLAGS%'

SET FFLAGS=/V /F /G /H /I /R /Y /Z

%_VECHO% FFlags = '%FFLAGS%'

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

%_VECHO% Root = '%ROOT%'

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

%_VECHO% Tools = '%TOOLS%'

CALL :fn_ResetErrorLevel

%_ECHO% CALL "%TOOLS%\vsSp.bat"

IF ERRORLEVEL 1 (
  ECHO Could not detect Visual Studio.
  GOTO errors
)

%_ECHO% CALL "%TOOLS%\set_common.bat"

IF ERRORLEVEL 1 (
  ECHO Could not set common variables.
  GOTO errors
)

IF NOT DEFINED YEARS (
  SET YEARS=2008
)

%_VECHO% Years = '%YEARS%'

IF /I "%PROCESSOR_ARCHITECTURE%" == "x86" (
  SET PLATFORM=Win32
)

IF /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
  SET PLATFORM=x64
)

IF NOT DEFINED PLATFORM (
  ECHO Unsupported platform.
  GOTO errors
)

%_VECHO% Platform = '%PLATFORM%'

%_ECHO% PUSHD "%ROOT%"

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

FOR %%Y IN (%YEARS%) DO (
  %_ECHO% Externals\Eagle\bin\EagleShell.exe -preInitialize "set test_year {%%Y}" -file Tests\all.eagle

  IF ERRORLEVEL 1 (
    ECHO Testing of "%%Y" managed-only assembly failed.
    GOTO errors
  )

  %_ECHO% XCOPY "bin\%%Y\Release\bin\test.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS%

  IF ERRORLEVEL 1 (
    ECHO Failed to copy "bin\%%Y\Release\bin\test.*" to "bin\%%Y\%PLATFORM%\Release".
    GOTO errors
  )

  %_ECHO% XCOPY "bin\%%Y\Release\bin\System.Data.SQLite.Linq.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS%

  IF ERRORLEVEL 1 (
    ECHO Failed to copy "bin\%%Y\Release\bin\System.Data.SQLite.Linq.*" to "bin\%%Y\%PLATFORM%\Release".
    GOTO errors
  )

  %_ECHO% XCOPY "bin\%%Y\Release\bin\testlinq.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS%

  IF ERRORLEVEL 1 (
    ECHO Failed to copy "bin\%%Y\Release\bin\testlinq.*" to "bin\%%Y\%PLATFORM%\Release".
    GOTO errors
  )

  %_ECHO% XCOPY "bin\%%Y\Release\bin\northwindEF.db" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS%

  IF ERRORLEVEL 1 (
    ECHO Failed to copy "bin\%%Y\Release\bin\northwindEF.db" to "bin\%%Y\%PLATFORM%\Release".
    GOTO errors
  )

  %_ECHO% Externals\Eagle\bin\EagleShell.exe -preInitialize "set test_year {%%Y}" -initialize -runtimeOption native -file Tests\all.eagle

  IF ERRORLEVEL 1 (
    ECHO Testing of "%%Y" mixed-mode assembly failed.
    GOTO errors
  )
)

%_ECHO% 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 Test failure, errors were encountered.
  GOTO end_of_file

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

:end_of_file
%_ECHO% EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































Deleted Setup/updateFileInfo.tcl.
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
###############################################################################
#
# updateFileInfo.tcl -- File Metadata Updating Tool
#
# WARNING: This tool requires the Fossil binary to exist somewhere along the
#          PATH.
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

proc readFile { fileName } {
  set file_id [open $fileName RDONLY]
  fconfigure $file_id -encoding binary -translation binary
  set result [read $file_id]
  close $file_id
  return $result
}

proc writeFile { fileName data } {
  set file_id [open $fileName {WRONLY CREAT TRUNC}]
  fconfigure $file_id -encoding binary -translation binary
  puts -nonewline $file_id $data
  close $file_id
  return ""
}

proc getFileSize { fileName } {
  #
  # NOTE: Return the number of mebibytes in the file with two digits after the
  #       decimal.
  #
  return [format %.2f [expr {[file size $fileName] / 1048576.0}]]
}

proc getFileHash { fileName } {
  #
  # NOTE: Return the SHA1 hash of the file, making use of Fossil via [exec] to
  #       actually calculate it.
  #
  return [string trim [lindex [regexp -inline -nocase -- {[0-9A-F]{40} } \
      [exec fossil sha1sum $fileName]] 0]]
}

#
# NOTE: Grab the fully qualified directory name of the directory containing
#       this script file.
#
set path [file normalize [file dirname [info script]]]

#
# NOTE: *WARNING* This assumes that the root of the source check-out is one
#       directory above the directory containing this script.
#
set root [file normalize [file dirname $path]]

#
# NOTE: Grab the name of the file to be updated from the command line, if
#       available; otherwise, use the default (i.e. "../www/downloads.wiki").
#
if {[info exists argv] && [llength $argv] > 0} then {
  set updateFileName [lindex $argv 0]
} else {
  set updateFileName [file join $root www downloads.wiki]
}

#
# NOTE: Grab the directory containing the files referenced in the data of the
#       file to be updated from the command line, if available; otherwise, use
#       the default (i.e. "./Output").
#
if {[info exists argv] && [llength $argv] > 1} then {
  set directory [lindex $argv 1]
} else {
  set directory [file join $path Output]
}

#
# NOTE: Setup the regular expression pattern with the necessary captures.  This
#       pattern is mostly non-greedy; however, at the end we need to match
#       exactly 40 hexadecimal characters.  In theory, in Tcl, this could have
#       an undefined result due to the mixing of greedy and non-greedy
#       quantifiers; however, in practice, this seems to work properly.  Also,
#       this pattern assumes a particular structure for the [HTML] file to be
#       updated.
#
set pattern {<a\
    href=".*?/(.*?\.(?:exe|zip))">.*?\((\d+?\.\d+?) MiB\).*?sha1:\
    ([0-9A-F]{40})}

#
# NOTE: Grab all the data from the file to be updated.
#
set data [readFile $updateFileName]

#
# NOTE: Process each match in the data and capture the file name, size, and
#       hash.
#
set count 0

foreach {dummy fileName fileSize fileHash} \
    [regexp -all -inline -nocase -- $pattern $data] {
  #
  # NOTE: Get the fully qualified file name based on the configured directory.
  #
  set fullFileName [file join $directory $fileName]

  #
  # NOTE: If the file does not exist, issue a warning and skip it.
  #
  if {![file exists $fullFileName]} then {
    puts stdout "WARNING: File \"$fullFileName\" does not exist, skipped."
    continue
  }

  #
  # NOTE: Replace the captured size and hash with ones calculated from the
  #       actual file name.  This will only replace the first instance of
  #       each (literal) match.  Since we are processing the matches in the
  #       exact order they appear in the data AND we are only replacing one
  #       literal instance per match AND the size sub-pattern is nothing like
  #       the hash sub-pattern, this should be 100% reliable.
  #
  incr count [regsub -nocase -- "***=$fileSize" $data [getFileSize \
      $fullFileName] data]

  incr count [regsub -nocase -- "***=$fileHash" $data [getFileHash \
      $fullFileName] data]
}

#
# NOTE: Write the [modified] data to the file to be updated.
#
if {$count > 0} then {
  writeFile $updateFileName $data
} else {
  puts stdout "WARNING: No changes, update of \"$updateFileName\" skipped."
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































Deleted Setup/vsSp.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
@ECHO OFF

::
:: vsSp.bat --
::
:: Visual Studio 2008/2010 Service Pack Detection Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET _ECHO=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 DUMMY2=%1

IF DEFINED DUMMY2 (
  GOTO usage
)

REM
REM NOTE: Build the command that we will use to query for Visual Studio 2008.
REM       Visual Studio 2008 is 32-bit only; therefore, when not running on an
REM       x86 platform, look in the WoW64 registry hive.
REM
IF "%PROCESSOR_ARCHITECTURE%" == "x86" (
  SET GET_SP_CMD=reg.exe QUERY "HKLM\SOFTWARE\Microsoft\DevDiv\VS\Servicing\9.0" /v SP
) ELSE (
  SET GET_SP_CMD=reg.exe QUERY "HKLM\SOFTWARE\Wow6432Node\Microsoft\DevDiv\VS\Servicing\9.0" /v SP
)

FOR /F "eol=; tokens=1,2,3*" %%I IN ('%GET_SP_CMD% 2^> NUL') DO (
  IF {%%I} == {SP} (
    IF {%%J} == {REG_DWORD} (
      %_AECHO% Found Visual Studio 2008 Service Pack "%%K".
      SET VS2008SP=%%K
    )
  )
)

REM
REM NOTE: Build the command that we will use to query for Visual Studio 2010.
REM       Visual Studio 2010 is 32-bit only; therefore, when not running on an
REM       x86 platform, look in the WoW64 registry hive.
REM
IF "%PROCESSOR_ARCHITECTURE%" == "x86" (
  SET GET_SP_CMD=reg.exe QUERY "HKLM\SOFTWARE\Microsoft\DevDiv\VS\Servicing\10.0" /v SP
) ELSE (
  SET GET_SP_CMD=reg.exe QUERY "HKLM\SOFTWARE\Wow6432Node\Microsoft\DevDiv\VS\Servicing\10.0" /v SP
)

FOR /F "eol=; tokens=1,2,3*" %%I IN ('%GET_SP_CMD% 2^> NUL') DO (
  IF {%%I} == {SP} (
    IF {%%J} == {REG_DWORD} (
      %_AECHO% Found Visual Studio 2010 Service Pack "%%K".
      SET VS2010SP=%%K
    )
  )
)

GOTO no_errors

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

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

:errors
  CALL :fn_SetErrorLevel
  ENDLOCAL
  GOTO end_of_file

:no_errors
  ENDLOCAL && (
    SET VS2008SP=%VS2008SP%
    SET VS2010SP=%VS2010SP%
  )
  CALL :fn_ResetErrorLevel
  GOTO end_of_file

:end_of_file
EXIT /B %ERRORLEVEL%
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































Deleted System.Data.SQLite.Linq/AssemblyInfo.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
/********************************************************
 * 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.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Runtime.ConstrainedExecution;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite for LINQ")]
[assembly: AssemblyDescription("ADO.NET Data Provider for SQLite")]
[assembly: AssemblyCompany("http://system.data.sqlite.org/")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      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.77.0")]
[assembly: AssemblyFileVersion("1.0.77.0")]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































Deleted System.Data.SQLite.Linq/Properties/Resources.Designer.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
/********************************************************
 * 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!
 ********************************************************/

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace System.Data.SQLite.Properties {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class Resources {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal Resources() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Data.SQLite.Properties.Resources", typeof(Resources).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to CREATE TEMP VIEW SCHEMACONSTRAINTCOLUMNS AS
        ///SELECT CONSTRAINT_CATALOG, NULL AS CONSTRAINT_SCHEMA, CONSTRAINT_NAME, TABLE_CATALOG, NULL AS TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME 
        ///FROM TEMP.SCHEMAINDEXCOLUMNS
        ///UNION
        ///SELECT CONSTRAINT_CATALOG, NULL, CONSTRAINT_NAME, TABLE_CATALOG, NULL, TABLE_NAME, FKEY_FROM_COLUMN
        ///FROM TEMP.SCHEMAFOREIGNKEYS;.
        /// </summary>
        internal static string SQL_CONSTRAINTCOLUMNS {
            get {
                return ResourceManager.GetString("SQL_CONSTRAINTCOLUMNS", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to CREATE TEMP VIEW SCHEMACONSTRAINTS AS
        ///SELECT INDEX_CATALOG AS CONSTRAINT_CATALOG, NULL AS CONSTRAINT_SCHEMA, INDEX_NAME AS CONSTRAINT_NAME, TABLE_CATALOG, NULL AS TABLE_SCHEMA, TABLE_NAME, &apos;PRIMARY KEY&apos; AS CONSTRAINT_TYPE, 0 AS IS_DEFERRABLE, 0 AS INITIALLY_DEFERRED, NULL AS CHECK_CLAUSE
        ///FROM TEMP.SCHEMAINDEXES WHERE PRIMARY_KEY = 1
        ///UNION
        ///SELECT INDEX_CATALOG, NULL, INDEX_NAME, TABLE_CATALOG, NULL, TABLE_NAME, &apos;UNIQUE&apos;, 0, 0, NULL 
        ///FROM TEMP.SCHEMAINDEXES WHERE PRIMARY_KEY = 0 AND [UNIQUE] = 1
        ///UNION
        /// [rest of string was truncated]&quot;;.
        /// </summary>
        internal static string SQL_CONSTRAINTS {
            get {
                return ResourceManager.GetString("SQL_CONSTRAINTS", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































Deleted System.Data.SQLite.Linq/Properties/Resources.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="SQL_CONSTRAINTCOLUMNS" xml:space="preserve">
    <value>CREATE TEMP VIEW SCHEMACONSTRAINTCOLUMNS AS
SELECT CONSTRAINT_CATALOG, NULL AS CONSTRAINT_SCHEMA, CONSTRAINT_NAME, TABLE_CATALOG, NULL AS TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME 
FROM TEMP.SCHEMAINDEXCOLUMNS
UNION
SELECT CONSTRAINT_CATALOG, NULL, CONSTRAINT_NAME, TABLE_CATALOG, NULL, TABLE_NAME, FKEY_FROM_COLUMN
FROM TEMP.SCHEMAFOREIGNKEYS;</value>
  </data>
  <data name="SQL_CONSTRAINTS" xml:space="preserve">
    <value>CREATE TEMP VIEW SCHEMACONSTRAINTS AS
SELECT INDEX_CATALOG AS CONSTRAINT_CATALOG, NULL AS CONSTRAINT_SCHEMA, INDEX_NAME AS CONSTRAINT_NAME, TABLE_CATALOG, NULL AS TABLE_SCHEMA, TABLE_NAME, 'PRIMARY KEY' AS CONSTRAINT_TYPE, 0 AS IS_DEFERRABLE, 0 AS INITIALLY_DEFERRED, NULL AS CHECK_CLAUSE
FROM TEMP.SCHEMAINDEXES WHERE PRIMARY_KEY = 1
UNION
SELECT INDEX_CATALOG, NULL, INDEX_NAME, TABLE_CATALOG, NULL, TABLE_NAME, 'UNIQUE', 0, 0, NULL 
FROM TEMP.SCHEMAINDEXES WHERE PRIMARY_KEY = 0 AND [UNIQUE] = 1
UNION
SELECT CONSTRAINT_CATALOG, NULL, CONSTRAINT_NAME, TABLE_CATALOG, NULL, TABLE_NAME, CONSTRAINT_TYPE, IS_DEFERRABLE, INITIALLY_DEFERRED, NULL 
FROM TEMP.SCHEMAFOREIGNKEYS;</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































Deleted System.Data.SQLite.Linq/Resources/Common.ConceptualSchemaDefinition.csdl.
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
<?xml version="1.0" encoding="utf-8"?>
<Schema xmlns="http://schemas.microsoft.com/ado/2006/04/edm" xmlns:edm="http://schemas.microsoft.com/ado/2006/04/edm" xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration" Namespace="Store" Alias="Self">

  <EntityContainer Name="SchemaInformation">

    <EntitySet Name="Tables" EntityType="Self.Table" />
    <EntitySet Name="TableColumns" EntityType="Self.Column" />
    <EntitySet Name="TableConstraints" EntityType="Self.Constraint" />
    <EntitySet Name="TableForeignKeys" EntityType="Self.ForeignKey" />
    
    <EntitySet Name="Views" EntityType="Self.View" />
    <EntitySet Name="ViewColumns" EntityType="Self.Column" />
    <EntitySet Name="ViewConstraints" EntityType="Self.Constraint" />
    <EntitySet Name="ViewForeignKeys" EntityType="Self.ForeignKey" />
    
    <EntitySet Name="Functions" EntityType="Self.Function" />
    <EntitySet Name="FunctionParameters" EntityType="Self.Parameter" />
    <EntitySet Name="Procedures" EntityType="Self.Procedure" />
    <EntitySet Name="ProcedureParameters" EntityType="Self.Parameter" />
 
    <AssociationSet Name="TableTableColumns" Association="Self.TableOrViewColumn" >
      <End Role="Parent" EntitySet="Tables"/>
      <End Role="Column" EntitySet="TableColumns"/>
    </AssociationSet>
    <AssociationSet Name="TableTableConstraints" Association="Self.TableOrViewConstraint" >
      <End Role="Parent" EntitySet="Tables"/>
      <End Role="Constraint" EntitySet="TableConstraints"/>
    </AssociationSet>
    <AssociationSet Name="TableConstraintColumns" Association="Self.TableOrViewConstraintColumn" >
      <End Role="Column" EntitySet="TableColumns"/>
      <End Role="Constraint" EntitySet="TableConstraints"/>
    </AssociationSet>
    <AssociationSet Name="TableConstraintForeignKeys" Association="Self.ConstraintForeignKey" >
      <End Role="ForeignKey" EntitySet="TableForeignKeys"/>
      <End Role="Constraint" EntitySet="TableConstraints"/>
    </AssociationSet>
    <AssociationSet Name="FromTableForeignKeyColumns" Association="Self.FromForeignKeyColumn" >
      <End Role="Column" EntitySet="TableColumns"/>
      <End Role="ForeignKey" EntitySet="TableForeignKeys"/>
    </AssociationSet>
    <AssociationSet Name="ToTableForeignKeyColumns" Association="Self.ToForeignKeyColumn" >
      <End Role="Column" EntitySet="TableColumns"/>
      <End Role="ForeignKey" EntitySet="TableForeignKeys"/>
    </AssociationSet>
    
    <AssociationSet Name="ViewViewColumns" Association="Self.TableOrViewColumn" >
      <End Role="Parent" EntitySet="Views"/>
      <End Role="Column" EntitySet="ViewColumns"/>
    </AssociationSet>
    <AssociationSet Name="ViewViewConstraints" Association="Self.TableOrViewConstraint" >
      <End Role="Parent" EntitySet="Views"/>
      <End Role="Constraint" EntitySet="ViewConstraints"/>
    </AssociationSet>
    <AssociationSet Name="ViewConstraintColumns" Association="Self.TableOrViewConstraintColumn" >
      <End Role="Column" EntitySet="ViewColumns"/>
      <End Role="Constraint" EntitySet="ViewConstraints"/>
    </AssociationSet>
    <AssociationSet Name="ViewConstraintForeignKeys" Association="Self.ConstraintForeignKey" >
      <End Role="ForeignKey" EntitySet="ViewForeignKeys"/>
      <End Role="Constraint" EntitySet="ViewConstraints"/>
    </AssociationSet>
    <AssociationSet Name="FromViewForeignKeyColumns" Association="Self.FromForeignKeyColumn" >
      <End Role="Column" EntitySet="ViewColumns"/>
      <End Role="ForeignKey" EntitySet="ViewForeignKeys"/>
    </AssociationSet>
    <AssociationSet Name="ToViewForeignKeyColumns" Association="Self.ToForeignKeyColumn" >
      <End Role="Column" EntitySet="ViewColumns"/>
      <End Role="ForeignKey" EntitySet="ViewForeignKeys"/>
    </AssociationSet>
    
    <AssociationSet Name="FunctionFunctionParameters" Association="Self.RoutineParameter" >
      <End Role="Routine" EntitySet="Functions"/>
      <End Role="Parameter" EntitySet="FunctionParameters"/>
    </AssociationSet>
    
    <AssociationSet Name="ProcedureProcedureParameters" Association="Self.RoutineParameter" >
      <End Role="Routine" EntitySet="Procedures"/>
      <End Role="Parameter" EntitySet="ProcedureParameters"/>
    </AssociationSet>

  </EntityContainer>

  <ComplexType Name="TypeSpecification">
    <Property Name="TypeName" Nullable="false" Type="String"  />
    <Property Name="MaxLength" Nullable="true" Type="Int32" />
    <Property Name="Precision" Nullable="true" Type="Int16" />
    <Property Name="DateTimePrecision" Nullable="true" Type="Int32" />
    <Property Name="Scale" Nullable="true" Type="Int32" />
    <Property Name="Collation" Nullable="false" Type="Self.Collation" />
    <Property Name="CharacterSet" Nullable="false" Type="Self.CharacterSet" />
    <Property Name="IsMultiSet" Nullable="false" Type="Boolean"/>
  </ComplexType>

  <ComplexType Name="Collation">
    <Property Name="CatalogName" Nullable="true" Type="String"  />
    <Property Name="SchemaName" Nullable="true" Type="String" />
    <Property Name="Name" Nullable="true" Type="String" />
  </ComplexType>

  <ComplexType Name="CharacterSet">
    <Property Name="CatalogName" Nullable="true" Type="String"  />
    <Property Name="SchemaName" Nullable="true" Type="String" />
    <Property Name="Name" Nullable="true" Type="String" />
  </ComplexType>

  <EntityType Name="TableOrView" Abstract="true">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="String"  />
    <Property Name="Name" Nullable="false" Type="String"  />
    <Property Name="CatalogName" Type="String"  />
    <Property Name="SchemaName" Type="String"  />
    <NavigationProperty Relationship="Self.TableOrViewColumn" Name="Columns" FromRole="Parent" ToRole="Column" />
    <NavigationProperty Relationship="Self.TableOrViewConstraint" Name="Constraints" FromRole="Parent" ToRole="Constraint" />
  </EntityType>

  <EntityType Name="Table" BaseType="Self.TableOrView">
  </EntityType>

  <EntityType Name="Column">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="String"  />
    <Property Name="Name" Nullable="false" Type="String" />
    <Property Name="Ordinal" Nullable="false" Type="Int32" />
    <Property Name="IsNullable" Nullable="false" Type="Boolean" />
    <Property Name="ColumnType" Nullable="false" Type="Self.TypeSpecification"/>
    <Property Name="IsIdentity" Nullable="false" Type="Boolean" />
    <Property Name="IsStoreGenerated" Nullable="false" Type="Boolean" />
    <Property Name="Default" Type="String" />
    <NavigationProperty Relationship="Self.TableOrViewColumn" Name="Parent" FromRole="Column" ToRole="Parent" />
  </EntityType>
  
  <EntityType Name="View" BaseType="Self.TableOrView">
    <Property Name="IsUpdatable" Nullable="false" Type="Boolean" />
    <Property Name="ViewDefinition" Nullable="true" Type="String"  />
  </EntityType>
  
  <EntityType Name="Routine" Abstract="true">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="String"  />
    <Property Name="CatalogName" Type="String"  />
    <Property Name="SchemaName" Type="String"  />
    <Property Name="Name" Nullable="false" Type="String"  />
    <NavigationProperty Relationship="Self.RoutineParameter" Name="Parameters" FromRole="Routine" ToRole="Parameter" />
  </EntityType>
  
  <EntityType Name="Parameter">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="String"  />
    <Property Name="Name" Nullable="false" Type="String"  />
    <Property Name="Ordinal" Nullable="false" Type="Int32" />
    <Property Name="ParameterType" Nullable="false" Type="Self.TypeSpecification"/>
    <Property Name="Mode" Type="String"  />
    <Property Name="Default" Type="String"  />
    <NavigationProperty Relationship="Self.RoutineParameter" Name="Routine" FromRole="Parameter" ToRole="Routine" />
  </EntityType>

  <EntityType Name="Function" BaseType="Self.Routine" Abstract="true">
    <Property Name="IsBuiltIn" Type="Boolean" />
    <Property Name="IsNiladic" Type="Boolean" />
  </EntityType>

  <EntityType Name="ScalarFunction" BaseType="Self.Function">
    <Property Name="ReturnType" Type="Self.TypeSpecification" Nullable="false"/>
    <Property Name="IsAggregate" Type="Boolean" />
  </EntityType>

  <EntityType Name="Procedure" BaseType="Self.Routine">
  </EntityType>

  <EntityType Name="Constraint" Abstract="true">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="String"  />
    <Property Name="Name" Nullable="false" Type="String"  />
    <Property Name="IsDeferrable" Nullable="false" Type="Boolean"  />
    <Property Name="IsInitiallyDeferred" Nullable="false" Type="Boolean"  />
    <NavigationProperty Relationship="Self.TableOrViewConstraint" Name="Parent" FromRole="Constraint" ToRole="Parent" />
  </EntityType>

  <EntityType Name="CheckConstraint" BaseType="Self.Constraint">
    <Property Name="Expression" Nullable="false" Type="String" />
  </EntityType>
  
  <EntityType Name="TableOrViewColumnConstraint" BaseType="Self.Constraint" Abstract="true">
    <NavigationProperty Relationship="Self.TableOrViewConstraintColumn" Name="Columns" FromRole="Constraint" ToRole="Column" />
  </EntityType>

  <EntityType Name="PrimaryKeyConstraint" BaseType="Self.TableOrViewColumnConstraint">
  </EntityType>

  <EntityType Name="UniqueConstraint" BaseType="Self.TableOrViewColumnConstraint">
  </EntityType>

  <EntityType Name="ForeignKeyConstraint" BaseType="Self.Constraint">
    <Property Name="UpdateRule" Nullable="false" Type="String"  />
    <Property Name="DeleteRule" Nullable="false" Type="String"  />
    <NavigationProperty Relationship="Self.ConstraintForeignKey" Name="ForeignKeys" FromRole="Constraint" ToRole="ForeignKey" />
  </EntityType>

  <EntityType Name="ForeignKey">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="String"  />
    <Property Name="Ordinal" Nullable="false" Type="Int32" />
    <NavigationProperty Relationship="Self.ConstraintForeignKey" Name="Constraint" FromRole="ForeignKey" ToRole="Constraint" />
    <NavigationProperty Relationship="Self.FromForeignKeyColumn" Name="FromColumn" FromRole="ForeignKey" ToRole="Column" />
    <NavigationProperty Relationship="Self.ToForeignKeyColumn" Name="ToColumn" FromRole="ForeignKey" ToRole="Column" />
  </EntityType>
  
  <Association Name="TableOrViewColumn">
    <End Type="Self.TableOrView" Role="Parent" Multiplicity="1" />
    <End Type="Self.Column" Role="Column" Multiplicity="*" />
  </Association>
  
  <Association Name="TableOrViewConstraint">
    <End Type="Self.TableOrView" Role="Parent" Multiplicity="1" />
    <End Type="Self.Constraint" Role="Constraint" Multiplicity="*" />
  </Association>

  <Association Name="TableOrViewConstraintColumn">
    <End Type="Self.TableOrViewColumnConstraint" Role="Constraint" Multiplicity="*" />
    <End Type="Self.Column" Role="Column" Multiplicity="*" />
  </Association>

  <Association Name="ConstraintForeignKey">
    <End Type="Self.ForeignKeyConstraint" Role="Constraint" Multiplicity="1" />
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
  </Association>

  <Association Name="ToForeignKeyColumn">
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
    <End Type="Self.Column" Role="Column" Multiplicity="1" />
  </Association>

  <Association Name="FromForeignKeyColumn">
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
    <End Type="Self.Column" Role="Column" Multiplicity="1" />
  </Association>
  
  <Association Name="RoutineParameter">
    <End Type="Self.Routine" Role="Routine" Multiplicity="1" />
    <End Type="Self.Parameter" Role="Parameter" Multiplicity="*" />
  </Association>

</Schema>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/Resources/Common.ProviderManifest.xsd.
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
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified"
		   xmlns:xs="http://www.w3.org/2001/XMLSchema"
		   targetNamespace="http://schemas.microsoft.com/ado/2006/04/edm/providermanifest"
		   xmlns:pm="http://schemas.microsoft.com/ado/2006/04/edm/providermanifest">

  <xs:element name="ProviderManifest">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Types" type="pm:TTypes" minOccurs="1" maxOccurs="1" />
        <xs:element name="Functions" type="pm:TFunctions" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="Namespace" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="TVersion">
    <xs:attribute name="Major" type="xs:int" use="required" />
    <xs:attribute name="Minor" type="xs:int" use="required" />
    <xs:attribute name="Build" type="xs:int" use="required" />
    <xs:attribute name="Revision" type="xs:int" use="required" />
  </xs:complexType>

  <xs:complexType name="TIntegerFacetDescription">
    <xs:attribute name="Minimum" type="xs:int" use="optional" />
    <xs:attribute name="Maximum" type="xs:int" use="optional" />
    <xs:attribute name="DefaultValue" type="xs:int" use="optional" />
    <xs:attribute name="Constant" type="xs:boolean" default="false" />
  </xs:complexType>

  <xs:complexType name="TBooleanFacetDescription">
    <xs:attribute name="DefaultValue" type="xs:boolean" use="optional" />
    <xs:attribute name="Constant" type="xs:boolean" default="true" />
  </xs:complexType>

  <xs:complexType name="TDateTimeFacetDescription">
    <xs:attribute name="Constant" type="xs:boolean" default="false" />
  </xs:complexType>

  <xs:complexType name="TFacetDescriptions">
    <xs:choice maxOccurs="unbounded">
      <xs:element name="Precision" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>
      <xs:element name="Scale" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>
      <xs:element name="MaxLength" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>
      <xs:element name="Unicode" minOccurs="0" maxOccurs="1" type="pm:TBooleanFacetDescription"/>
      <xs:element name="FixedLength" minOccurs="0" maxOccurs="1" type="pm:TBooleanFacetDescription"/>
    </xs:choice>
  </xs:complexType>

  <xs:complexType name="TType">
    <xs:sequence>
      <xs:element name="FacetDescriptions" type="pm:TFacetDescriptions" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="Name" type="xs:string" use="required"/>
    <xs:attribute name="PrimitiveTypeKind" type="pm:TPrimitiveTypeKind" use="required" />
  </xs:complexType>

  <xs:complexType name="TTypes">
    <xs:sequence>
      <xs:element name="Type" type="pm:TType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:attributeGroup name="TFacetAttribute">
    <xs:attribute name="Precision" type="xs:int" use="optional"/>
    <xs:attribute name="Scale" type="xs:int" use="optional"/>
    <xs:attribute name="MaxLength" type="xs:int" use="optional"/>
    <xs:attribute name="Unicode" type="xs:boolean" use="optional"/>
    <xs:attribute name="FixedLength" type="xs:boolean" use="optional"/>
  </xs:attributeGroup>

  <xs:complexType name="TFunctionParameter">
    <xs:attribute name="Name" type="xs:string" use="required" />
    <xs:attribute name="Type" type="xs:string" use="required" />
    <xs:attributeGroup ref="pm:TFacetAttribute" />
    <xs:attribute name="Mode" type="pm:TParameterDirection" use="required" />
  </xs:complexType>

  <xs:complexType name="TReturnType">
    <xs:attribute name="Type" type="xs:string" use="required" />
    <xs:attributeGroup ref="pm:TFacetAttribute" />
  </xs:complexType>

  <xs:complexType name="TFunction">
    <xs:choice minOccurs="0" maxOccurs ="unbounded">
      <xs:element name ="ReturnType" type="pm:TReturnType" minOccurs="0" maxOccurs="1" />
      <xs:element name="Parameter" type="pm:TFunctionParameter" minOccurs="0" maxOccurs="unbounded"/>
    </xs:choice>
    <xs:attribute name="Name" type="xs:string" use="required" />
    <xs:attribute name="Aggregate" type="xs:boolean" use="optional" />
    <xs:attribute name="BuiltIn" type="xs:boolean" use="optional" />
    <xs:attribute name="StoreFunctionName" type="xs:string" use="optional" />
    <xs:attribute name="NiladicFunction" type="xs:boolean" use="optional" />
    <xs:attribute name="ParameterTypeSemantics" type="pm:TParameterTypeSemantics" use="optional" default="AllowImplicitConversion" />
  </xs:complexType>

  <xs:complexType name="TFunctions">
    <xs:sequence>
      <xs:element name="Function" type="pm:TFunction" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="TPrimitiveTypeKind">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Binary"/>
      <xs:enumeration value="Boolean"/>
      <xs:enumeration value="Byte"/>
      <xs:enumeration value="Decimal"/>
      <xs:enumeration value="DateTime"/>
      <xs:enumeration value="Time"/>
      <xs:enumeration value="DateTimeOffset"/>        
      <xs:enumeration value="Double"/>
      <xs:enumeration value="Guid"/>
      <xs:enumeration value="Single"/>
      <xs:enumeration value="SByte"/>
      <xs:enumeration value="Int16"/>
      <xs:enumeration value="Int32"/>
      <xs:enumeration value="Int64"/>
      <xs:enumeration value="String"/>
    </xs:restriction>
  </xs:simpleType>


  <xs:simpleType name="TParameterDirection">
    <xs:restriction base="xs:string">
      <xs:enumeration value="In"/>
      <xs:enumeration value="Out"/>
      <xs:enumeration value="InOut"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="TParameterTypeSemantics">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ExactMatchOnly" />
      <xs:enumeration value="AllowImplicitPromotion" />
      <xs:enumeration value="AllowImplicitConversion" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































Deleted System.Data.SQLite.Linq/Resources/SQLiteProviderServices.ProviderManifest.xml.
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
<?xml version="1.0" encoding="utf-8"?>

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<!-- 
####################################################################################################################

BE AWARE THAT THE ORDER IN WHICH TYPES ARE DESCRIBED IN THE PROVIDER MANIFEST IS RELEVANT AND HAVE IMPACT IN LOOKUP
PROCESS

#################################################################################################################### 
-->
<ProviderManifest Namespace="SQLite" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/providermanifest">
  <Types>
    <Type Name="tinyint" PrimitiveTypeKind="Byte">
    </Type>
    <Type Name="smallint" PrimitiveTypeKind="Int16">
    </Type>
    <Type Name="int" PrimitiveTypeKind="Int32">
    </Type>
    <Type Name="integer" PrimitiveTypeKind="Int64">
    </Type>
    <Type Name="float" PrimitiveTypeKind="Double">
    </Type>
    <Type Name="real" PrimitiveTypeKind="Single">
    </Type>
    <Type Name="decimal" PrimitiveTypeKind="Decimal">
      <FacetDescriptions>
        <Precision Minimum="1" Maximum="53" DefaultValue="18" Constant="false" />
        <Scale Minimum="0" Maximum="53" DefaultValue="0" Constant="false" />
      </FacetDescriptions>
    </Type>
    <Type Name="blob" PrimitiveTypeKind="Binary">
      <FacetDescriptions>
        <MaxLength DefaultValue="2147483647" Constant="true" />
        <FixedLength DefaultValue="false" Constant="true" />
      </FacetDescriptions>
    </Type>
    <Type Name="bit" PrimitiveTypeKind="Boolean">
    </Type>
    <Type Name="datetime" PrimitiveTypeKind="DateTime">
      <FacetDescriptions>
        <Precision DefaultValue="3" Constant="true" />
      </FacetDescriptions>
    </Type>
    <Type Name="nvarchar" PrimitiveTypeKind="String">
      <FacetDescriptions>
        <MaxLength Minimum="1" Maximum="2147483647" DefaultValue="2147483647" Constant="false" />
        <Unicode DefaultValue="true" Constant="true" />
        <FixedLength DefaultValue="false" Constant="true" />
      </FacetDescriptions>
    </Type>
    <Type Name="varchar" PrimitiveTypeKind="String">
      <FacetDescriptions>
        <MaxLength Minimum="1" Maximum="2147483647" DefaultValue="2147483647" Constant="false" />
        <Unicode DefaultValue="false" Constant="true" />
        <FixedLength DefaultValue="false" Constant="true" />
      </FacetDescriptions>
    </Type>
    <Type Name="char" PrimitiveTypeKind="String">
      <FacetDescriptions>
        <MaxLength Minimum="1" Maximum="2147483647" DefaultValue="2147483647" Constant="false" />
        <Unicode DefaultValue="false" Constant="true" />
        <FixedLength DefaultValue="true" Constant="true" />
      </FacetDescriptions>
    </Type>
    <Type Name="nchar" PrimitiveTypeKind="String">
      <FacetDescriptions>
        <MaxLength Minimum="1" Maximum="2147483647" DefaultValue="2147483647" Constant="false" />
        <Unicode DefaultValue="true" Constant="true" />
        <FixedLength DefaultValue="true" Constant="true" />
      </FacetDescriptions>
    </Type>
    <Type Name="uniqueidentifier" PrimitiveTypeKind="Guid">
    </Type>
  </Types>
  <Functions>

    <!-- BEGIN AGGREGATES 
		http://www.sqlite.org/lang_aggfunc.html  -->
    <!-- AVG -->
    <Function Name="AVG" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Int32)" Mode="In" />
    </Function>
    <Function Name="AVG" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Int64)" Mode="In" />
    </Function>
    <Function Name="AVG" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Decimal)" Mode="In" />
    </Function>
    <Function Name="AVG" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Double)" Mode="In" />
    </Function>

    <!-- COUNT -->
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Boolean)" Mode="In" />
    </Function>
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Double)" Mode="In" />
    </Function>
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Decimal)" Mode="In" />
    </Function>
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(DateTime)" Mode="In" />
    </Function>
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(DateTimeOffset)" Mode="In" />
    </Function>
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Time)" Mode="In" />
    </Function>
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Guid)" Mode="In" />
    </Function>
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(String)" Mode="In" />
    </Function>
    <Function Name="COUNT" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Binary)" Mode="In" />
    </Function>




    <!-- MAX -->
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Byte" />
      <Parameter Name="arg" Type="Collection(Byte)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int16" />
      <Parameter Name="arg" Type="Collection(Int16)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Collection(Int32)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Int64)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Decimal" />
      <Parameter Name="arg" Type="Collection(Decimal)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Double)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Single" />
      <Parameter Name="arg" Type="Collection(Single)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="DateTime" />
      <Parameter Name="arg" Type="Collection(DateTime)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Time" />
      <Parameter Name="arg" Type="Collection(Time)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="DateTimeOffset" />
      <Parameter Name="arg" Type="Collection(DateTimeOffset)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="arg" Type="Collection(String)" Mode="In" />
    </Function>
    <Function Name="MAX" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Binary" />
      <Parameter Name="arg" Type="Collection(Binary)" Mode="In" />
    </Function>

    <!-- MIN -->
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Byte" />
      <Parameter Name="arg" Type="Collection(Byte)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int16" />
      <Parameter Name="arg" Type="Collection(Int16)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Collection(Int32)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Int64)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Decimal" />
      <Parameter Name="arg" Type="Collection(Decimal)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Double)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Single" />
      <Parameter Name="arg" Type="Collection(Single)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="DateTime" />
      <Parameter Name="arg" Type="Collection(DateTime)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Time" />
      <Parameter Name="arg" Type="Collection(Time)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="DateTimeOffset" />
      <Parameter Name="arg" Type="Collection(DateTimeOffset)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="arg" Type="Collection(String)" Mode="In" />
    </Function>
    <Function Name="MIN" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Binary" />
      <Parameter Name="arg" Type="Collection(Binary)" Mode="In" />
    </Function>

    <!-- SUM -->
    <Function Name="SUM" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Collection(Int32)" Mode="In" />
    </Function>
    <Function Name="SUM" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Int64)" Mode="In" />
    </Function>
    <Function Name="SUM" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Double)" Mode="In" />
    </Function>

    <!-- STDEV -->
    <Function Name="STDEV" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Double)" Mode="In" />
    </Function>

    <Function Name="STDEV" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Decimal)" Mode="In" />
    </Function>

    <!-- TOTAL -->
    <Function Name="TOTAL" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Collection(Int32)" Mode="In" />
    </Function>
    <Function Name="TOTAL" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Collection(Int64)" Mode="In" />
    </Function>
    <Function Name="TOTAL" Aggregate="true" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Collection(Double)" Mode="In" />
    </Function>

    <!-- END AGGREGATES ############################################# -->

    <!-- Begin Scalars http://www.sqlite.org/lang_corefunc.html -->

    <Function Name="ABS" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Int32" Mode="In" />
    </Function>
    <Function Name="ABS" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Int64" Mode="In" />
    </Function>
    <Function Name="ABS" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- CHARINDEX( strSearch, strTarget [, startLocation ] )
                strSearch: character expression
                strTarget: character expression
                startLocation: tinyint, smallint, int, bigint
                returns: int, bigint   
        -->
    <Function Name="CHARINDEX" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="strSearch" Type="String" Mode="In" />
      <Parameter Name="strTarget" Type="String" Mode="In" />
    </Function>
    <Function Name="CHARINDEX" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="strSearch" Type="Binary" Mode="In" />
      <Parameter Name="strTarget" Type="Binary" Mode="In" />
    </Function>
    <Function Name="CHARINDEX" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="strSearch" Type="String" Mode="In" />
      <Parameter Name="strTarget" Type="String" Mode="In" />
      <Parameter Name="startLocation" Type="Int32" Mode="In" />
    </Function>
    <Function Name="CHARINDEX" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="strSearch" Type="Binary" Mode="In" />
      <Parameter Name="strTarget" Type="Binary" Mode="In" />
      <Parameter Name="startLocation" Type="Int32" Mode="In" />
    </Function>
    <Function Name="CHARINDEX" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="strSearch" Type="String" Mode="In" />
      <Parameter Name="strTarget" Type="String" Mode="In" />
      <Parameter Name="startLocation" Type="Int64" Mode="In" />
    </Function>
    <Function Name="CHARINDEX" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="strSearch" Type="Binary" Mode="In" />
      <Parameter Name="strTarget" Type="Binary" Mode="In" />
      <Parameter Name="startLocation" Type="Int64" Mode="In" />
    </Function>

    <!-- DIFFERENCE( str1, str2 ) 
            str1: varchar
            str2: varchar
            returns: int   
        -->
    <Function Name="DIFFERENCE" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="str1" Type="String" Mode="In" />
      <Parameter Name="str2" Type="String" Mode="In" />
    </Function>

    <Function Name="HEX" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="arg" Type="Binary" Mode="In" />
    </Function>

    <!-- LEFT( str, count ) 
                str: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
                count: tinyint, smallint, int, bigint
                returns: varchar, nvarchar
        -->
    <Function Name="LEFTSTR" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
      <Parameter Name="count" Type="Int64" Mode="In" />
    </Function>

    <Function Name="LENGTH" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="string_expression" Type="String" Mode="In" />
    </Function>
    <Function Name="LENGTH" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="string_expression" Type="Binary" Mode="In" />
    </Function>

    <!-- LOWER( str ) 
            str: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
            returns: varchar, nvarchar   
        -->
    <Function Name="LOWER" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
    </Function>

    <!-- LTRIM( str ) 
            str: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
            returns: varchar, nvarchar
        -->
    <Function Name="LTRIM" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
    </Function>
    <Function Name="LTRIM" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
      <Parameter Name="to_remove" Type="String" Mode="In" />
    </Function>

    <!-- TODO: Min and Max Scalar functions -->

    <!-- QUOTE( character_string [,quote_character] ) 
                character_string: nchar, nvarchar, nvarchar(max)
                quote_character: nchar, char, varchar, nvarchar
                returns: nvarchar   
        -->
    <Function Name="QUOTE" BuiltIn="true">
      <ReturnType Type="String"  />
      <Parameter Name="character_string" Type="String" Mode="In" />
    </Function>
    <Function Name="QUOTE" BuiltIn="true">
      <ReturnType Type="String"  />
      <Parameter Name="character_string" Type="String"  Mode="In" />
      <Parameter Name="quote_character" Type="String"  Mode="In" />
    </Function>
    <!-- RAND( [seed] )
                seed: tinyint, smallint, int
                returns: float
        -->
    <Function Name="RANDOM" BuiltIn="true">
      <ReturnType Type="Int64" />
    </Function>
    <Function Name="RANDOMBLOB" BuiltIn="true">
      <Parameter Name="numBytes" Type="Int64" Mode="In" />
      <ReturnType Type="Binary" />
    </Function>

    <!-- REPLACE( strTarget, strSearch, strReplacement )
            strTarget: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
            strSearch: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
            strReplacement: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
            returns: varchar, nvarchar   
        -->
    <Function Name="REPLACE" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="strTarget" Type="String"  Mode="In" />
      <Parameter Name="strSearch" Type="String"  Mode="In" />
      <Parameter Name="strReplacement" Type="String"  Mode="In" />
    </Function>

    <!-- REPLICATE( strSource, count )
            strSource: varchar, nvarchar
            count: tinyint, smallint, int
            returns: varchar, nvarchar   
        -->
    <Function Name="REPLICATE" BuiltIn="true">
      <ReturnType Type="String"  />
      <Parameter Name="strTarget" Type="String" Mode="In" />
      <Parameter Name="count" Type="Int32" Mode="In" />
    </Function>

    <!-- REVERSE( arg ) 
            arg: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
            returns: varchar, nvarchar
        -->
    <Function Name="REVERSE" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="arg" Type="String" Mode="In" />
    </Function>

    <!-- RIGHT( atr, count ) 
                str: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
                count: tinyint, smallint, int, bigint
                returns: varchar, nvarchar
        -->
    <Function Name="RIGHTSTR" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
      <Parameter Name="count" Type="Int64" Mode="In" />
    </Function>

    <Function Name="RTRIM" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
    </Function>
    <Function Name="RTRIM" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
      <Parameter Name="to_remove" Type="String" Mode="In" />
    </Function>

    <!-- SOUNDEX( arg ) 
            arg: char, nchar, varchar, nvarchar, varchar(max), nvarchar(max)
            returns: varchar   
        -->
    <Function Name="SOUNDEX" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="arg" Type="String" Mode="In" />
    </Function>

    <Function Name="SUBSTR" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
      <Parameter Name="start" Type="Int64" Mode="In" />
      <Parameter Name="length" Type="Int64" Mode="In" />
    </Function>
    <Function Name="SUBSTR" BuiltIn="true">
      <ReturnType Type="Binary" />
      <Parameter Name="str" Type="Binary" Mode="In" />
      <Parameter Name="start" Type="Int64" Mode="In" />
      <Parameter Name="length" Type="Int64" Mode="In" />
    </Function>
    <Function Name="SUBSTR" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
      <Parameter Name="start" Type="Int64" Mode="In" />
    </Function>
    <Function Name="SUBSTR" BuiltIn="true">
      <ReturnType Type="Binary" />
      <Parameter Name="str" Type="Binary" Mode="In" />
      <Parameter Name="start" Type="Int64" Mode="In" />
    </Function>

    <Function Name="TRIM" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
    </Function>
    <Function Name="TRIM" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
      <Parameter Name="to_remove" Type="String" Mode="In" />
    </Function>

    <Function Name="UPPER" BuiltIn="true">
      <ReturnType Type="String" />
      <Parameter Name="str" Type="String" Mode="In" />
    </Function>

    <!-- BEGIN DATE FUNCTIONS ####################################### -->
    <!-- DATEADD 
                datepart: nvarchar
                number: tinyint, smallint, int, bigint, numeric, decimal, real, float
                date: smalldatetime, datetime, varchar, nvarchar, char, nchar
                returns: SMALLTIME, datetime   
        -->
    <Function Name="DATEADD" BuiltIn="true">
      <ReturnType Type="DateTime" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="number" Type="Double" Mode="In" />
      <Parameter Name="date" Type="DateTime" Mode="In" />
    </Function>
    <Function Name="DATEADD" BuiltIn="true">
      <ReturnType Type="Time" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="number" Type="Double" Mode="In" />
      <Parameter Name="time" Type="Time" Mode="In" />
    </Function>
    <Function Name="DATEADD" BuiltIn="true">
      <ReturnType Type="DateTime" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="number" Type="Double" Mode="In" />
      <Parameter Name="date" Type="String" Mode="In" />
    </Function>

    <!-- DATEDIFF( datepart, startdate, enddate )
                datepart: nvarchar
                startdate: smalldatetime, datetime, char, nchar, varchar, nvarchar
                enddate: smalldatetime, datetime, char, nchar, varchar, nvarchar
                returns: int   
        -->
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="DateTime" Mode="In" />
      <Parameter Name="enddate" Type="DateTime" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="DateTimeOffset" Mode="In" />
      <Parameter Name="enddate" Type="DateTimeOffset" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="Time" Mode="In" />
      <Parameter Name="enddate" Type="Time" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="String" Mode="In" />
      <Parameter Name="enddate" Type="DateTime" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="String" Mode="In" />
      <Parameter Name="enddate" Type="DateTimeOffset" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="String" Mode="In" />
      <Parameter Name="enddate" Type="Time" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="Time" Mode="In" />
      <Parameter Name="enddate" Type="String" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="DateTime" Mode="In" />
      <Parameter Name="enddate" Type="String" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="DateTimeOffset" Mode="In" />
      <Parameter Name="enddate" Type="String" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="String" Mode="In" />
      <Parameter Name="enddate" Type="String" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="Time" Mode="In" />
      <Parameter Name="enddate" Type="DateTime" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="Time" Mode="In" />
      <Parameter Name="enddate" Type="DateTimeOffset" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="DateTime" Mode="In" />
      <Parameter Name="enddate" Type="Time" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="DateTimeOffset" Mode="In" />
      <Parameter Name="enddate" Type="Time" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="DateTime" Mode="In" />
      <Parameter Name="enddate" Type="DateTimeOffset" Mode="In" />
    </Function>
    <Function Name="DATEDIFF" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="startdate" Type="DateTimeOffset" Mode="In" />
      <Parameter Name="enddate" Type="DateTime" Mode="In" />
    </Function>


    <!-- DATEPART( datepart, date )
                datepart: nvarchar
                date: smalldatetime, datetime, char, nchar, varchar, nvarchar
                returns: int   
        -->
    <Function Name="DATEPART" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="date" Type="DateTime" Mode="In" />
    </Function>
    <Function Name="DATEPART" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="date" Type="DateTimeOffset" Mode="In" />
    </Function>
    <Function Name="DATEPART" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="date" Type="String" Mode="In" />
    </Function>
    <Function Name="DATEPART" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="datepart" Type="String" Mode="In" />
      <Parameter Name="date" Type="Time" Mode="In" />
    </Function>
    <!-- DAY( date )
            date: smalldatetime, datetime
            returns: int   
        -->
    <Function Name="DAY" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="DateTime" Mode="In" />
    </Function>
    <Function Name="DAY" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="DateTimeOffset" Mode="In" />
    </Function>
    <Function Name="DAY" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="String" Mode="In" />
    </Function>

    <!-- GETDATE()
            returns: datetime   
        -->
    <Function Name="GETDATE" BuiltIn="true">
      <ReturnType Type="DateTime"/>
    </Function>

    <!-- GETUTCDATE()
         returns: datetime   
    -->
    <Function Name="GETUTCDATE" BuiltIn="true">
      <ReturnType Type="DateTime"/>
    </Function>

    <!-- MONTH( date )
                date: smalldatetime, datetime
                returns: int   
        -->
    <Function Name="MONTH" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="DateTime" Mode="In" />
    </Function>
    <Function Name="MONTH" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="DateTimeOffset" Mode="In" />
    </Function>
    <Function Name="MONTH" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="String" Mode="In" />
    </Function>

    <!-- YEAR( date )
            date: smalldatetime, datetime
            returns: int   
        -->
    <Function Name="YEAR" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="DateTime" Mode="In" />
    </Function>
    <Function Name="YEAR" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="DateTimeOffset" Mode="In" />
    </Function>
    <Function Name="YEAR" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="date" Type="String" Mode="In" />
    </Function>
    <!-- END DATE FUNCTIONS ######################################### -->

    <!-- NEWID() -->
    <Function Name="NEWID" BuiltIn="true">
      <ReturnType Type="Guid" />
    </Function>

    <!-- CURRENT_TIMESTAMP -->
    <Function Name="CURRENT_TIME" BuiltIn="true" NiladicFunction="true">
      <ReturnType Type="DateTime" />
    </Function>
    <Function Name="CURRENT_DATE" BuiltIn="true" NiladicFunction="true">
      <ReturnType Type="DateTime" />
    </Function>
    <Function Name="CURRENT_TIMESTAMP" BuiltIn="true" NiladicFunction="true">
      <ReturnType Type="DateTime" />
    </Function>

    <!-- ACOS( arg )
                arg: float
                returns: float   
        -->
    <Function Name="ACOS" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg1" Type="Double" Mode="In" />
    </Function>

    <!-- ASIN( arg )
                arg: float
                returns: float   
        -->
    <Function Name="ASIN" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- ATAN( arg )
                arg: float
                returns: float   
        -->
    <Function Name="ATAN" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- ATN2( arg1, arg2 )
                arg1: float
                arg2: float
                returns: float   
        -->
    <Function Name="ATN2" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg1" Type="Double" Mode="In" />
      <Parameter Name="arg2" Type="Double" Mode="In" />
    </Function>

    <!-- CEILING( arg )
                arg: smalldatetime, datetime
                returns: int   
        -->
    <Function Name="CEILING" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Int32" Mode="In" />
    </Function>
    <Function Name="CEILING" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Int64" Mode="In" />
    </Function>
    <Function Name="CEILING" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- COS( arg )
                arg: float
                returns: float   
        -->
    <Function Name="COS" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- COT( arg )
                arg: float
                returns: float   
        -->
    <Function Name="COT" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- DEGREES( arg )
                arg: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
                returns: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
        -->
    <Function Name="DEGREES" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg1" Type="Int32" Mode="In" />
    </Function>
    <Function Name="DEGREES" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg1" Type="Int64" Mode="In" />
    </Function>
    <Function Name="DEGREES" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg1" Type="Double" Mode="In" />
    </Function>
    <!-- EXP( arg )
                arg: float
                returns: float   
        -->
    <Function Name="EXP" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- FLOOR( arg )
                arg: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
                returns: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
        -->
    <Function Name="FLOOR" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Int32" Mode="In" />
    </Function>
    <Function Name="FLOOR" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Int64" Mode="In" />
    </Function>
    <Function Name="FLOOR" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- LOG( arg )
            arg: float
            returns: float   
     -->
    <Function Name="LOG" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- LOG10( arg )
                arg: float
                returns: float   
        -->
    <Function Name="LOG10" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>
    <!-- PI( )
                returns: float   
        -->
    <Function Name="PI" BuiltIn="true">
      <ReturnType Type="Double" />
    </Function>

    <!-- POWER( x, y )
                x: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
                y: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
                returns: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
        -->
    <Function Name="POWER" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="x" Type="Int32" Mode="In" />
      <Parameter Name="y" Type="Double" Mode="In" />
    </Function>
    <Function Name="POWER" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="x" Type="Int64" Mode="In" />
      <Parameter Name="y" Type="Double" Mode="In" />
    </Function>
    <Function Name="POWER" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="x" Type="Double" Mode="In" />
      <Parameter Name="y" Type="Double" Mode="In" />
    </Function>
    
    <!-- RADIANS( arg )
                arg: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
                returns: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
        -->
    <Function Name="RADIANS" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Int32" Mode="In" />
    </Function>
    <Function Name="RADIANS" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Int64" Mode="In" />
    </Function>
    <Function Name="RADIANS" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <Function Name="ROUND" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="numeric_expression" Type="Int32" Mode="In" />
      <Parameter Name="length" Type="Int32" Mode="In" />
    </Function>
    <Function Name="ROUND" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="numeric_expression" Type="Int64" Mode="In" />
      <Parameter Name="length" Type="Int32" Mode="In" />
    </Function>
    <Function Name="ROUND" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="numeric_expression" Type="Double" Mode="In" />
      <Parameter Name="length" Type="Int32" Mode="In" />
    </Function>
    <Function Name="ROUND" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="numeric_expression" Type="Int32" Mode="In" />
      <Parameter Name="length" Type="Int32" Mode="In" />
      <Parameter Name="function" Type="Int32" Mode="In" />
    </Function>
    <Function Name="ROUND" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="numeric_expression" Type="Int64" Mode="In" />
      <Parameter Name="length" Type="Int32" Mode="In" />
      <Parameter Name="function" Type="Int32" Mode="In" />
    </Function>
    <Function Name="ROUND" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="numeric_expression" Type="Double" Mode="In" />
      <Parameter Name="length" Type="Int32" Mode="In" />
      <Parameter Name="function" Type="Int32" Mode="In" />
    </Function>

    <!-- SIGN( arg )
            arg: tinyint, smallint, int, bigint, numeric, decimal, smallmoney, money, real, float
            returns: bigint, numeric, decimal, money, float
        -->
    <Function Name="SIGN" BuiltIn="true">
      <ReturnType Type="Int32" />
      <Parameter Name="arg" Type="Int32" Mode="In" />
    </Function>
    <Function Name="SIGN" BuiltIn="true">
      <ReturnType Type="Int64" />
      <Parameter Name="arg" Type="Int64" Mode="In" />
    </Function>
    <Function Name="SIGN" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- SIN( arg )
                arg: float
                returns: float   
        -->
    <Function Name="SIN" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- SQRT( arg )
                arg: float
                returns: float   
        -->
    <Function Name="SQRT" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>

    <!-- SQUARE( arg )
                arg: smalldatetime, datetime
                returns: int   
        -->
    <Function Name="SQUARE" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg1" Type="Double" Mode="In" />
    </Function>
    <!-- TAN( arg )
                arg: float
                returns: float   
        -->
    <Function Name="TAN" BuiltIn="true">
      <ReturnType Type="Double" />
      <Parameter Name="arg" Type="Double" Mode="In" />
    </Function>
    
    <!-- END SYSTEM FUNCTIONS ####################################### -->
  </Functions>
</ProviderManifest>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/Resources/SQLiteProviderServices.StoreSchemaDefinition.ssdl.
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
<?xml version="1.0" encoding="utf-8"?>
<Schema Namespace="EFSQLite" Provider="System.Data.SQLite" ProviderManifestToken="ISO8601" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
  <EntityContainer Name="Schema">
    <EntitySet Name="STables" EntityType="Self.Table">
      <DefiningQuery>
        SELECT
        '[' || TABLE_NAME || ']' COLLATE NOCASE [Id]
        ,   TABLE_CATALOG [CatalogName]
        ,   TABLE_SCHEMA [SchemaName]
        ,   TABLE_NAME    [Name]
        FROM
        TEMP.SCHEMATABLES
        WHERE
        TABLE_TYPE LIKE 'table'
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="STableColumns" EntityType="Self.TableColumn">
      <DefiningQuery>
        SELECT
        '[' || c.TABLE_NAME || ']' || '[' || c.COLUMN_NAME || ']' COLLATE NOCASE [Id]
        ,   '[' || c.TABLE_NAME || ']'  COLLATE NOCASE                     [ParentId]
        ,   c.COLUMN_NAME   [Name]
        ,   c.ORDINAL_POSITION [Ordinal]
        ,   c.IS_NULLABLE [IsNullable]
        ,   c.EDM_TYPE [TypeName]
        ,   c.CHARACTER_MAXIMUM_LENGTH [MaxLength]
        ,   c.NUMERIC_PRECISION [Precision]
        ,   c.DATETIME_PRECISION [DateTimePrecision]
        ,   c.NUMERIC_SCALE [Scale]
        ,   c.COLLATION_CATALOG [CollationCatalog]
        ,   c.COLLATION_SCHEMA [CollationSchema]
        ,   c.COLLATION_NAME [CollationName]
        ,   c.CHARACTER_SET_CATALOG [CharacterSetCatalog]
        ,   c.CHARACTER_SET_SCHEMA [CharacterSetSchema]
        ,   c.CHARACTER_SET_NAME [CharacterSetName]
        ,   0 as [IsMultiSet]
        ,   c.[AUTOINCREMENT] as [IsIdentity]
        ,   0 as [IsStoreGenerated]
        , c.COLUMN_DEFAULT as [Default]
        FROM
        TEMP.SCHEMACOLUMNS c
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SViews" EntityType="Self.View">
      <DefiningQuery>
        SELECT
        '[' || TABLE_NAME || ']'  COLLATE NOCASE [Id]
        ,   TABLE_CATALOG             [CatalogName]
        ,   TABLE_SCHEMA              [SchemaName]
        ,   TABLE_NAME                [Name]
        ,   VIEW_DEFINITION           [ViewDefinition]
        ,   IS_UPDATABLE              [IsUpdatable]
        FROM
        TEMP.SCHEMAVIEWS
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SViewColumns" EntityType="Self.ViewColumn">
      <DefiningQuery>
        SELECT
        '[' || c.VIEW_NAME || ']' || '[' || c.VIEW_COLUMN_NAME || ']' COLLATE NOCASE [Id]
        ,   '[' || c.VIEW_NAME || ']' COLLATE NOCASE                             [ParentId]
        ,   c.VIEW_COLUMN_NAME   [Name]
        ,   c.ORDINAL_POSITION [Ordinal]
        ,   c.IS_NULLABLE [IsNullable]
        ,   c.EDM_TYPE [TypeName]
        ,   c.CHARACTER_MAXIMUM_LENGTH [MaxLength]
        ,   c.NUMERIC_PRECISION [Precision]
        ,   c.DATETIME_PRECISION as [DateTimePrecision]
        ,   c.NUMERIC_SCALE [Scale]
        ,   c.COLLATION_CATALOG [CollationCatalog]
        ,   c.COLLATION_SCHEMA [CollationSchema]
        ,   c.COLLATION_NAME [CollationName]
        ,   c.CHARACTER_SET_CATALOG [CharacterSetCatalog]
        ,   c.CHARACTER_SET_SCHEMA [CharacterSetSchema]
        ,   c.CHARACTER_SET_NAME [CharacterSetName]
        ,   0 as [IsMultiSet]
        ,   c.[AUTOINCREMENT] as [IsIdentity]
        ,   0 as [IsStoreGenerated]
        ,   c.COLUMN_DEFAULT [Default]
        FROM
        TEMP.SCHEMAVIEWCOLUMNS c
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SFunctions" EntityType="Self.Function">
      <DefiningQuery>
        SELECT
        NULL [Id]
        , NULL         [CatalogName]
        , NULL         [SchemaName]
        , NULL         [Name]
        , NULL         [ReturnTypeName]
        , NULL [ReturnMaxLength]
        , NULL        [ReturnPrecision]
        , NULL [ReturnDateTimePrecision]
        , NULL            [ReturnScale]
        , NULL        [ReturnCollationCatalog]
        , NULL         [ReturnCollationSchema]
        , NULL           [ReturnCollationName]
        , NULL    [ReturnCharacterSetCatalog]
        , NULL     [ReturnCharacterSetSchema]
        , NULL       [ReturnCharacterSetName]
        , NULL as        [ReturnIsMultiSet]
        , NULL as [IsAggregate]
        , NULL as [IsBuiltIn]
        , NULL as [IsNiladic]
        WHERE 1=2
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SFunctionParameters" EntityType="Self.Parameter">
      <DefiningQuery>
        SELECT
        NULL [Id]
        , NULL [ParentId]
        , NULL [Name]
        , NULL [Ordinal]
        , NULL [TypeName]
        , NULL [MaxLength]
        , NULL [Precision]
        , NULL [DateTimePrecision]
        , NULL    [Scale]
        , NULL [CollationCatalog]
        , NULL [CollationSchema]
        , NULL [CollationName]
        , NULL [CharacterSetCatalog]
        , NULL [CharacterSetSchema]
        , NULL [CharacterSetName]
        , NULL [IsMultiSet]
        , NULL [Mode]
        , NULL [Default]
        WHERE 1=2
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SProcedures" EntityType="Self.Procedure">
      <DefiningQuery>
        SELECT
        NULL [Id]
        , NULL         [CatalogName]
        , NULL          [SchemaName]
        , NULL            [Name]
        WHERE 1=2
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SProcedureParameters" EntityType="Self.Parameter">
      <DefiningQuery>
        SELECT
        NULL [Id]
        , NULL [ParentId]
        , NULL [Name]
        , NULL [Ordinal]
        , NULL [TypeName]
        , NULL [MaxLength]
        , NULL [Precision]
        , NULL [DateTimePrecision]
        , NULL [Scale]
        , NULL [CollationCatalog]
        , NULL [CollationSchema]
        , NULL [CollationName]
        , NULL [CharacterSetCatalog]
        , NULL [CharacterSetSchema]
        , NULL [CharacterSetName]
        , NULL as [IsMultiSet]
        , NULL   [Mode]
        , NULL [Default]
        WHERE 1=2
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SConstraints" EntityType="Self.Constraint">
      <DefiningQuery>
        SELECT
        '[' || tc.CONSTRAINT_NAME || ']'  COLLATE NOCASE [Id]
        , '[' || tc.TABLE_NAME || ']'  COLLATE NOCASE [ParentId]
        , tc.CONSTRAINT_NAME [Name]
        , tc.CONSTRAINT_TYPE [ConstraintType]
        , tc.IS_DEFERRABLE [IsDeferrable]
        , tc.INITIALLY_DEFERRED [IsInitiallyDeferred]
        FROM
        TEMP.SCHEMACONSTRAINTS tc
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SCheckConstraints" EntityType="Self.CheckConstraint">
      <DefiningQuery>
        SELECT
        NULL [Id]
        , NULL [Expression]
        WHERE 1 = 2
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SConstraintColumns" EntityType="Self.ConstraintColumn">
      <DefiningQuery>
        SELECT
        '[' || CONSTRAINT_NAME || ']'  COLLATE NOCASE [ConstraintId]
        , '[' || TABLE_NAME || ']' || '[' || COLUMN_NAME    || ']'  COLLATE NOCASE [ColumnId]
        FROM
        TEMP.SCHEMACONSTRAINTCOLUMNS
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SForeignKeyConstraints" EntityType="Self.ForeignKeyConstraint">
      <DefiningQuery>
        SELECT DISTINCT
        '[' || rc.CONSTRAINT_NAME || ']'  COLLATE NOCASE [Id]
        , 'NO ACTION'  COLLATE NOCASE [UpdateRule]
        , 'NO ACTION'  COLLATE NOCASE [DeleteRule]
        FROM
        TEMP.SCHEMAFOREIGNKEYS rc
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SForeignKeys" EntityType="Self.ForeignKey">
      <DefiningQuery>
        SELECT
        '[' || FC.CONSTRAINT_NAME || ']' || '[' || FC.FKEY_FROM_ORDINAL_POSITION || ']' COLLATE NOCASE [Id]
        ,   '[' || FC.FKEY_TO_TABLE || ']' || '[' || FC.FKEY_TO_COLUMN || ']' COLLATE NOCASE [ToColumnId]
        ,   '[' || FC.TABLE_NAME || ']' || '[' || FC.FKEY_FROM_COLUMN || ']' COLLATE NOCASE [FromColumnId]
        ,   '[' || FC.CONSTRAINT_NAME || ']' COLLATE NOCASE [ConstraintId]
        ,   FC.FKEY_FROM_ORDINAL_POSITION [Ordinal]
        FROM
        TEMP.SCHEMAFOREIGNKEYS FC
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SViewConstraints" EntityType="Self.ViewConstraint">
      <DefiningQuery>
        SELECT
        NULL   [Id]
        , NULL [ParentId]
        , NULL [Name]
        , NULL [ConstraintType]
        , NULL [IsDeferrable]
        , NULL [IsInitiallyDeferred]
        , NULL [Expression]
        , NULL  [UpdateRule]
        , NULL  [DeleteRule]
        WHERE 1=2
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SViewConstraintColumns" EntityType="Self.ConstraintColumn">
      <DefiningQuery>
        SELECT
        NULL  [ConstraintId]
        , NULL [ColumnId]
        WHERE 1=2
      </DefiningQuery>
    </EntitySet>

    <EntitySet Name="SViewForeignKeys" EntityType="Self.ForeignKey">
      <DefiningQuery>
        SELECT
        NULL  [Id]
        ,  NULL [ToColumnId]
        ,  NULL [FromColumnId]
        ,  NULL  [ConstraintId]
        ,  0 [Ordinal]
        WHERE 1=2
      </DefiningQuery>
    </EntitySet>

    <AssociationSet Name="STableTableColumns" Association="Self.TableTableColumn" >
      <End Role="Parent" EntitySet="STables"/>
      <End Role="Column" EntitySet="STableColumns"/>
    </AssociationSet>
    <AssociationSet Name="STableConstraints" Association="Self.TableTableConstraint" >
      <End Role="Parent" EntitySet="STables"/>
      <End Role="Constraint" EntitySet="SConstraints"/>
    </AssociationSet>
    <AssociationSet Name="SConstraintConstraintColumns" Association="Self.ConstraintConstraintColumn" >
      <End Role="ConstraintColumn" EntitySet="SConstraintColumns"/>
      <End Role="Constraint" EntitySet="SConstraints"/>
    </AssociationSet>    
    <AssociationSet Name="SConstraintForeignKeys" Association="Self.ConstraintForeignKey" >
      <End Role="ForeignKey" EntitySet="SForeignKeys"/>
      <End Role="Constraint" EntitySet="SForeignKeyConstraints"/>
    </AssociationSet>
    <AssociationSet Name="SFromForeignKeyColumns" Association="Self.FromForeignKeyColumn" >
      <End Role="ForeignKey" EntitySet="SForeignKeys"/>
      <End Role="Column" EntitySet="STableColumns"/>
    </AssociationSet>
    <AssociationSet Name="SToForeignKeyColumns" Association="Self.ToForeignKeyColumn" >
      <End Role="ForeignKey" EntitySet="SForeignKeys"/>
      <End Role="Column" EntitySet="STableColumns"/>
    </AssociationSet>

    <AssociationSet Name="SViewViewColumns" Association="Self.ViewViewColumn" >
      <End Role="Parent" EntitySet="SViews"/>
      <End Role="Column" EntitySet="SViewColumns"/>
    </AssociationSet>
    <AssociationSet Name="SViewViewConstraints" Association="Self.ViewViewConstraint" >
      <End Role="Parent" EntitySet="SViews"/>
      <End Role="Constraint" EntitySet="SViewConstraints"/>
    </AssociationSet>
    <AssociationSet Name="SViewConstraintConstraintColumns" Association="Self.ViewConstraintConstraintColumn" >
      <End Role="ConstraintColumn" EntitySet="SViewConstraintColumns"/>
      <End Role="Constraint" EntitySet="SViewConstraints"/>
    </AssociationSet>
    <AssociationSet Name="SViewConstraintForeignKeys" Association="Self.ViewConstraintForeignKey" >
      <End Role="ForeignKey" EntitySet="SViewForeignKeys"/>
      <End Role="Constraint" EntitySet="SViewConstraints"/>
    </AssociationSet>
    <AssociationSet Name="SFromForeignKeyViewColumns" Association="Self.FromForeignKeyViewColumn" >
      <End Role="ForeignKey" EntitySet="SViewForeignKeys"/>
      <End Role="Column" EntitySet="SViewColumns"/>
    </AssociationSet>
    <AssociationSet Name="SToForeignKeyViewColumns" Association="Self.ToForeignKeyViewColumn" >
      <End Role="ForeignKey" EntitySet="SViewForeignKeys"/>
      <End Role="Column" EntitySet="SViewColumns"/>
    </AssociationSet>

    <AssociationSet Name="FunctionFunctionParameters" Association="Self.FunctionFunctionParameter">
      <End Role="Function" EntitySet="SFunctions"/>
      <End Role="Parameter" EntitySet="SFunctionParameters"/>
    </AssociationSet>
    <AssociationSet Name="ProcedureProcedureParameters" Association="Self.ProcedureProcedureParameter" >
      <End Role="Procedure" EntitySet="SProcedures"/>
      <End Role="Parameter" EntitySet="SProcedureParameters"/>
    </AssociationSet>

  </EntityContainer>

  <EntityType Name="Table">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar" />
    <Property Name="CatalogName" Type="nvarchar" />
    <Property Name="SchemaName" Type="nvarchar" />
    <Property Name="Name" Nullable="false" Type="nvarchar" />
  </EntityType>

  <EntityType Name="TableColumn" >
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar"/>
    <Property Name="ParentId" Nullable="false" Type="nvarchar"/>
    <Property Name="Name" Nullable="false" Type="nvarchar"/>
    <Property Name="Ordinal" Nullable="false" Type="int" />
    <Property Name="IsNullable" Nullable="false" Type="bit" />
    <Property Name="TypeName" Nullable="false" Type="nvarchar" />
    <Property Name="MaxLength" Type="int" />
    <Property Name="Precision" Type="int" />
    <Property Name="DateTimePrecision" Type="int" />
    <Property Name="Scale" Type="int" />
    <Property Name="CollationCatalog" Type="nvarchar" />
    <Property Name="CollationSchema" Type="nvarchar" />
    <Property Name="CollationName" Type="nvarchar" />
    <Property Name="CharacterSetCatalog" Type="nvarchar" />
    <Property Name="CharacterSetSchema" Type="nvarchar" />
    <Property Name="CharacterSetName" Type="nvarchar" />
    <Property Name="IsMultiSet" Nullable="false" Type="bit" />
    <Property Name="IsIdentity" Nullable="false" Type="bit" />
    <Property Name="IsStoreGenerated" Nullable="false" Type="bit" />
    <Property Name="Default" Nullable="true" Type="nvarchar"/>
  </EntityType>

  <EntityType Name="View">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar" />
    <Property Name="CatalogName" Type="nvarchar" />
    <Property Name="SchemaName" Type="nvarchar" />
    <Property Name="Name" Nullable="false" Type="nvarchar" />
    <Property Name="ViewDefinition" Nullable="true" Type="nvarchar" />
    <Property Name="IsUpdatable" Nullable="false" Type="bit" />
  </EntityType>

  <EntityType Name="ViewColumn">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar"/>
    <Property Name="ParentId" Nullable="false" Type="nvarchar"/>
    <Property Name="Name" Nullable="false" Type="nvarchar"/>
    <Property Name="Ordinal" Nullable="false" Type="int" />
    <Property Name="IsNullable" Nullable="false" Type="bit" />
    <Property Name="TypeName" Nullable="false" Type="nvarchar" />
    <Property Name="MaxLength" Type="int" />
    <Property Name="Precision" Type="int" />
    <Property Name="DateTimePrecision" Type="int" />
    <Property Name="Scale" Type="int" />
    <Property Name="CollationCatalog" Type="nvarchar" />
    <Property Name="CollationSchema" Type="nvarchar" />
    <Property Name="CollationName" Type="nvarchar" />
    <Property Name="CharacterSetCatalog" Type="nvarchar" />
    <Property Name="CharacterSetSchema" Type="nvarchar" />
    <Property Name="CharacterSetName" Type="nvarchar" />
    <Property Name="IsMultiSet" Nullable="false" Type="bit" />
    <Property Name="IsIdentity" Nullable="false" Type="bit" />
    <Property Name="IsStoreGenerated" Nullable="false" Type="bit" />
    <Property Name="Default" Nullable="true" Type="nvarchar"/>
  </EntityType>

  <EntityType Name="Function">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar"/>
    <Property Name="CatalogName" Type="nvarchar"/>
    <Property Name="SchemaName" Type="nvarchar"/>
    <Property Name="Name" Nullable="false" Type="nvarchar"/>
    <Property Name="ReturnTypeName" Type="nvarchar" />
    <Property Name="ReturnMaxLength" Type="int" />
    <Property Name="ReturnPrecision" Type="int" />
    <Property Name="ReturnDateTimePrecision" Type="int" />
    <Property Name="ReturnScale" Type="int" />
    <Property Name="ReturnCollationCatalog" Type="nvarchar" />
    <Property Name="ReturnCollationSchema" Type="nvarchar" />
    <Property Name="ReturnCollationName" Type="nvarchar" />
    <Property Name="ReturnCharacterSetCatalog" Type="nvarchar" />
    <Property Name="ReturnCharacterSetSchema" Type="nvarchar" />
    <Property Name="ReturnCharacterSetName" Type="nvarchar" />
    <Property Name="ReturnIsMultiSet" Nullable="false" Type="bit" />
    <Property Name="IsAggregate" Type="bit" />
    <Property Name="IsBuiltIn" Type="bit" />
    <Property Name="IsNiladic" Type="bit" />
  </EntityType>

  <EntityType Name="Procedure">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar"/>
    <Property Name="CatalogName" Type="nvarchar"/>
    <Property Name="SchemaName" Type="nvarchar"/>
    <Property Name="Name" Nullable="false" Type="nvarchar"/>
  </EntityType>

  <EntityType Name="Parameter">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar"/>
    <Property Name="ParentId" Nullable="false" Type="nvarchar"/>
    <Property Name="Name" Nullable="false" Type="nvarchar" />
    <Property Name="Ordinal" Nullable="false" Type="int"/>
    <Property Name="TypeName" Nullable="false" Type="nvarchar" />
    <Property Name="MaxLength" Nullable="true" Type="int" />
    <Property Name="Precision" Nullable="true" Type="int" />
    <Property Name="DateTimePrecision" Type="int" />
    <Property Name="Scale" Nullable="true" Type="int" />
    <Property Name="CollationCatalog" Type="nvarchar" />
    <Property Name="CollationSchema" Type="nvarchar" />
    <Property Name="CollationName" Type="nvarchar" />
    <Property Name="CharacterSetCatalog" Type="nvarchar" />
    <Property Name="CharacterSetSchema" Type="nvarchar" />
    <Property Name="CharacterSetName" Type="nvarchar" />
    <Property Name="IsMultiSet" Nullable="false" Type="bit" />
    <Property Name="Mode" Type="nvarchar" />
    <Property Name="Default" Type="nvarchar" />
  </EntityType>

  <EntityType Name="Constraint">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar" />
    <Property Name="ParentId" Nullable="false" Type="nvarchar" />
    <Property Name="Name" Nullable="false" Type="nvarchar" />
    <Property Name="IsDeferrable" Nullable="false" Type="bit" />
    <Property Name="IsInitiallyDeferred" Nullable="false" Type="bit" />
    <Property Name="ConstraintType" Nullable="false" Type="nvarchar" />
  </EntityType>

  <EntityType Name="CheckConstraint">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar" />
    <Property Name="Expression" Nullable="true" Type="nvarchar" />
  </EntityType>
  
  <EntityType Name="ConstraintColumn">
    <Key>
      <PropertyRef Name="ConstraintId" />
      <PropertyRef Name="ColumnId" />
    </Key>
    <Property Name="ConstraintId" Nullable="false" Type="nvarchar" />
    <Property Name="ColumnId" Nullable="false" Type="nvarchar" />
  </EntityType>

  <EntityType Name="ForeignKeyConstraint">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar" />
    <Property Name="UpdateRule" Nullable="false" Type="nvarchar" />
    <Property Name="DeleteRule" Nullable="false" Type="nvarchar" />
  </EntityType>

  <EntityType Name="ForeignKey">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar" />
    <Property Name="Ordinal" Nullable="false" Type="int" />
    <Property Name="ConstraintId" Nullable="false" Type="nvarchar" />
    <Property Name="FromColumnId" Nullable="false" Type="nvarchar" />
    <Property Name="ToColumnId" Nullable="false" Type="nvarchar" />
  </EntityType>

  <EntityType Name="ViewConstraint">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Nullable="false" Type="nvarchar" />
    <Property Name="ParentId" Nullable="false" Type="nvarchar" />
    <Property Name="Name" Nullable="false" Type="nvarchar" />
    <Property Name="IsDeferrable" Nullable="false" Type="bit" />
    <Property Name="IsInitiallyDeferred" Nullable="false" Type="bit" />
    <Property Name="ConstraintType" Nullable="false" Type="nvarchar" />
    <Property Name="Expression" Nullable="true" Type="nvarchar" />
    <Property Name="UpdateRule" Nullable="true" Type="nvarchar" />
    <Property Name="DeleteRule" Nullable="true" Type="nvarchar" />
  </EntityType>

  <Association Name="TableTableConstraint">
    <End Type="Self.Table" Role="Parent" Multiplicity="1" />
    <End Type="Self.Constraint" Role="Constraint" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Parent">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="Constraint">
        <PropertyRef Name="ParentId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ConstraintConstraintColumn">
    <End Type="Self.Constraint" Role="Constraint" Multiplicity="1" />
    <End Type="Self.ConstraintColumn" Role="ConstraintColumn" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Constraint">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="ConstraintColumn">
        <PropertyRef Name="ConstraintId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ConstraintForeignKey">
    <End Type="Self.ForeignKeyConstraint" Role="Constraint" Multiplicity="1" />
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Constraint">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="ForeignKey">
        <PropertyRef Name="ConstraintId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="FromForeignKeyColumn">
    <End Type="Self.TableColumn" Role="Column" Multiplicity="1" />
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Column">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="ForeignKey">
        <PropertyRef Name="FromColumnId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ToForeignKeyColumn">
    <End Type="Self.TableColumn" Role="Column" Multiplicity="1" />
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Column">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="ForeignKey">
        <PropertyRef Name="ToColumnId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="TableTableColumn">
    <End Type="Self.Table" Role="Parent" Multiplicity="1" />
    <End Type="Self.TableColumn" Role="Column" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Parent">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="Column">
        <PropertyRef Name="ParentId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ViewViewColumn">
    <End Type="Self.View" Role="Parent" Multiplicity="1" />
    <End Type="Self.ViewColumn" Role="Column" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Parent">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="Column">
        <PropertyRef Name="ParentId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="FunctionFunctionParameter">
    <End Type="Self.Function" Role="Function" Multiplicity="1" />
    <End Type="Self.Parameter" Role="Parameter" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Function">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="Parameter">
        <PropertyRef Name="ParentId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ProcedureProcedureParameter">
    <End Type="Self.Procedure" Role="Procedure" Multiplicity="1" />
    <End Type="Self.Parameter" Role="Parameter" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Procedure">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="Parameter">
        <PropertyRef Name="ParentId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ViewViewConstraint">
    <End Type="Self.View" Role="Parent" Multiplicity="1" />
    <End Type="Self.ViewConstraint" Role="Constraint" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Parent">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="Constraint">
        <PropertyRef Name="ParentId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ViewConstraintConstraintColumn">
    <End Type="Self.ViewConstraint" Role="Constraint" Multiplicity="1" />
    <End Type="Self.ConstraintColumn" Role="ConstraintColumn" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Constraint">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="ConstraintColumn">
        <PropertyRef Name="ConstraintId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ViewConstraintForeignKey">
    <End Type="Self.ViewConstraint" Role="Constraint" Multiplicity="1" />
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Constraint">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="ForeignKey">
        <PropertyRef Name="ConstraintId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="FromForeignKeyViewColumn">
    <End Type="Self.ViewColumn" Role="Column" Multiplicity="1" />
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Column">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="ForeignKey">
        <PropertyRef Name="FromColumnId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

  <Association Name="ToForeignKeyViewColumn">
    <End Type="Self.ViewColumn" Role="Column" Multiplicity="1" />
    <End Type="Self.ForeignKey" Role="ForeignKey" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="Column">
        <PropertyRef Name="Id" />
      </Principal>
      <Dependent Role="ForeignKey">
        <PropertyRef Name="ToColumnId" />
      </Dependent>
    </ReferentialConstraint>
  </Association>

</Schema>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/Resources/SQLiteProviderServices.StoreSchemaMapping.msl.
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
<?xml version="1.0" encoding="utf-8"?>
<Mapping xmlns:cs="urn:schemas-microsoft-com:windows:storage:mapping:CS" Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
  <cs:EntityContainerMapping StorageEntityContainer="Schema" CdmEntityContainer="SchemaInformation">

    <cs:EntitySetMapping Name="Tables" StoreEntitySet="STables" TypeName="Store.Table">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="CatalogName" ColumnName="CatalogName" />
      <cs:ScalarProperty Name="SchemaName" ColumnName="SchemaName" />
      <cs:ScalarProperty Name="Name" ColumnName="Name" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="TableColumns" StoreEntitySet="STableColumns" TypeName="Store.Column">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="Name" ColumnName="Name" />
      <cs:ScalarProperty Name="Ordinal" ColumnName="Ordinal" />
      <cs:ScalarProperty Name="IsNullable" ColumnName="IsNullable" />
      <cs:ComplexProperty Name="ColumnType">
        <cs:ScalarProperty Name="TypeName" ColumnName="TypeName" />
        <cs:ScalarProperty Name="MaxLength" ColumnName="MaxLength" />
        <cs:ScalarProperty Name="DateTimePrecision" ColumnName="DateTimePrecision" />
        <cs:ScalarProperty Name="Precision" ColumnName="Precision" />
        <cs:ScalarProperty Name="Scale" ColumnName="Scale" />
        <cs:ComplexProperty Name="Collation">
          <cs:ScalarProperty Name="CatalogName" ColumnName="CollationCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="CollationSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="CollationName" />
        </cs:ComplexProperty>
        <cs:ComplexProperty Name="CharacterSet">
          <cs:ScalarProperty Name="CatalogName" ColumnName="CharacterSetCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="CharacterSetSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="CharacterSetName" />
        </cs:ComplexProperty>
        <cs:ScalarProperty Name="IsMultiSet" ColumnName="IsMultiSet" />
      </cs:ComplexProperty>
      <cs:ScalarProperty Name="IsIdentity" ColumnName="IsIdentity" />
      <cs:ScalarProperty Name="IsStoreGenerated" ColumnName="IsStoreGenerated" />
      <cs:ScalarProperty Name="Default" ColumnName="Default" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="Views" StoreEntitySet="SViews" TypeName="Store.View">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="CatalogName" ColumnName="CatalogName" />
      <cs:ScalarProperty Name="SchemaName" ColumnName="SchemaName" />
      <cs:ScalarProperty Name="Name" ColumnName="Name" />
      <cs:ScalarProperty Name="ViewDefinition" ColumnName="ViewDefinition" />
      <cs:ScalarProperty Name="IsUpdatable" ColumnName="IsUpdatable" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="ViewColumns" StoreEntitySet="SViewColumns" TypeName="Store.Column">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="Name" ColumnName="Name" />
      <cs:ScalarProperty Name="Ordinal" ColumnName="Ordinal" />
      <cs:ScalarProperty Name="IsNullable" ColumnName="IsNullable" />
      <cs:ComplexProperty Name="ColumnType">
        <cs:ScalarProperty Name="TypeName" ColumnName="TypeName" />
        <cs:ScalarProperty Name="MaxLength" ColumnName="MaxLength" />
        <cs:ScalarProperty Name="Precision" ColumnName="Precision" />
        <cs:ScalarProperty Name="DateTimePrecision" ColumnName="DateTimePrecision" />
        <cs:ScalarProperty Name="Scale" ColumnName="Scale" />
        <cs:ComplexProperty Name="Collation">
          <cs:ScalarProperty Name="CatalogName" ColumnName="CollationCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="CollationSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="CollationName" />
        </cs:ComplexProperty>
        <cs:ComplexProperty Name="CharacterSet">
          <cs:ScalarProperty Name="CatalogName" ColumnName="CharacterSetCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="CharacterSetSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="CharacterSetName" />
        </cs:ComplexProperty>
        <cs:ScalarProperty Name="IsMultiSet" ColumnName="IsMultiSet" />
      </cs:ComplexProperty>
      <cs:ScalarProperty Name="IsIdentity" ColumnName="IsIdentity" />
      <cs:ScalarProperty Name="IsStoreGenerated" ColumnName="IsStoreGenerated" />
      <cs:ScalarProperty Name="Default" ColumnName="Default" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="Functions" TypeName="Store.ScalarFunction" StoreEntitySet="SFunctions">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="CatalogName" ColumnName="CatalogName" />
      <cs:ScalarProperty Name="SchemaName" ColumnName="SchemaName" />
      <cs:ScalarProperty Name="Name" ColumnName="Name" />
      <cs:ComplexProperty Name="ReturnType">
        <cs:ScalarProperty Name="TypeName" ColumnName="ReturnTypeName" />
        <cs:ScalarProperty Name="MaxLength" ColumnName="ReturnMaxLength" />
        <cs:ScalarProperty Name="Precision" ColumnName="ReturnPrecision" />
        <cs:ScalarProperty Name="DateTimePrecision" ColumnName="ReturnDateTimePrecision" />
        <cs:ScalarProperty Name="Scale" ColumnName="ReturnScale" />
        <cs:ComplexProperty Name="Collation">
          <cs:ScalarProperty Name="CatalogName" ColumnName="ReturnCollationCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="ReturnCollationSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="ReturnCollationName" />
        </cs:ComplexProperty>
        <cs:ComplexProperty Name="CharacterSet">
          <cs:ScalarProperty Name="CatalogName" ColumnName="ReturnCharacterSetCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="ReturnCharacterSetSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="ReturnCharacterSetName" />
        </cs:ComplexProperty>
        <cs:ScalarProperty Name="IsMultiSet" ColumnName="ReturnIsMultiSet" />
      </cs:ComplexProperty>
      <cs:ScalarProperty Name="IsAggregate" ColumnName="IsAggregate" />
      <cs:ScalarProperty Name="IsBuiltIn" ColumnName="IsBuiltIn" />
      <cs:ScalarProperty Name="IsNiladic" ColumnName="IsNiladic" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="FunctionParameters" TypeName="Store.Parameter" StoreEntitySet="SFunctionParameters">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="Name" ColumnName="Name" />
      <cs:ScalarProperty Name="Ordinal" ColumnName="Ordinal" />
      <cs:ComplexProperty Name="ParameterType">
        <cs:ScalarProperty Name="TypeName" ColumnName="TypeName" />
        <cs:ScalarProperty Name="MaxLength" ColumnName="MaxLength" />
        <cs:ScalarProperty Name="DateTimePrecision" ColumnName="DateTimePrecision" />
        <cs:ScalarProperty Name="Precision" ColumnName="Precision" />
        <cs:ScalarProperty Name="Scale" ColumnName="Scale" />
        <cs:ComplexProperty Name="Collation">
          <cs:ScalarProperty Name="CatalogName" ColumnName="CollationCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="CollationSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="CollationName" />
        </cs:ComplexProperty>
        <cs:ComplexProperty Name="CharacterSet">
          <cs:ScalarProperty Name="CatalogName" ColumnName="CharacterSetCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="CharacterSetSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="CharacterSetName" />
        </cs:ComplexProperty>
        <cs:ScalarProperty Name="IsMultiSet" ColumnName="IsMultiSet" />
      </cs:ComplexProperty>
      <cs:ScalarProperty Name="Mode" ColumnName="Mode" />
      <cs:ScalarProperty Name="Default" ColumnName="Default" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="Procedures" TypeName="Store.Procedure" StoreEntitySet="SProcedures">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="CatalogName" ColumnName="CatalogName" />
      <cs:ScalarProperty Name="SchemaName" ColumnName="SchemaName" />
      <cs:ScalarProperty Name="Name" ColumnName="Name" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="ProcedureParameters" TypeName="Store.Parameter" StoreEntitySet="SProcedureParameters">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="Name" ColumnName="Name" />
      <cs:ScalarProperty Name="Ordinal" ColumnName="Ordinal" />
      <cs:ComplexProperty Name="ParameterType">
        <cs:ScalarProperty Name="TypeName" ColumnName="TypeName" />
        <cs:ScalarProperty Name="MaxLength" ColumnName="MaxLength" />
        <cs:ScalarProperty Name="DateTimePrecision" ColumnName="DateTimePrecision" />
        <cs:ScalarProperty Name="Precision" ColumnName="Precision" />
        <cs:ScalarProperty Name="Scale" ColumnName="Scale" />
        <cs:ComplexProperty Name="Collation">
          <cs:ScalarProperty Name="CatalogName" ColumnName="CollationCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="CollationSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="CollationName" />
        </cs:ComplexProperty>
        <cs:ComplexProperty Name="CharacterSet">
          <cs:ScalarProperty Name="CatalogName" ColumnName="CharacterSetCatalog" />
          <cs:ScalarProperty Name="SchemaName" ColumnName="CharacterSetSchema" />
          <cs:ScalarProperty Name="Name" ColumnName="CharacterSetName" />
        </cs:ComplexProperty>
        <cs:ScalarProperty Name="IsMultiSet" ColumnName="IsMultiSet" />
      </cs:ComplexProperty>
      <cs:ScalarProperty Name="Mode" ColumnName="Mode" />
      <cs:ScalarProperty Name="Default" ColumnName="Default" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="TableConstraints" >
      <cs:EntityTypeMapping TypeName="IsTypeOf(Store.Constraint)">
        <cs:MappingFragment StoreEntitySet="SConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:ScalarProperty Name="Name" ColumnName="Name" />
          <cs:ScalarProperty Name="IsDeferrable" ColumnName="IsDeferrable" />
          <cs:ScalarProperty Name="IsInitiallyDeferred" ColumnName="IsInitiallyDeferred" />
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
      <cs:EntityTypeMapping TypeName="Store.UniqueConstraint">
          <cs:MappingFragment StoreEntitySet="SConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:Condition ColumnName="ConstraintType" Value="UNIQUE"/>
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
      <cs:EntityTypeMapping TypeName="Store.CheckConstraint">
        <cs:MappingFragment StoreEntitySet="SConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:Condition ColumnName="ConstraintType" Value="CHECK"/>
        </cs:MappingFragment>
        <cs:MappingFragment StoreEntitySet="SCheckConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:ScalarProperty Name="Expression" ColumnName="Expression" />
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
      <cs:EntityTypeMapping TypeName="Store.PrimaryKeyConstraint">
        <cs:MappingFragment StoreEntitySet="SConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:Condition ColumnName="ConstraintType" Value="PRIMARY KEY"/>
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
      <cs:EntityTypeMapping TypeName="Store.ForeignKeyConstraint">
        <cs:MappingFragment StoreEntitySet="SConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:Condition ColumnName="ConstraintType" Value="FOREIGN KEY"/>
        </cs:MappingFragment>
        <cs:MappingFragment StoreEntitySet="SForeignKeyConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:ScalarProperty Name="UpdateRule" ColumnName="UpdateRule" />
          <cs:ScalarProperty Name="DeleteRule" ColumnName="DeleteRule" />
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="ViewConstraints" >
      <cs:EntityTypeMapping TypeName="Store.UniqueConstraint" >
        <cs:MappingFragment StoreEntitySet="SViewConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:ScalarProperty Name="Name" ColumnName="Name" />
          <cs:ScalarProperty Name="IsDeferrable" ColumnName="IsDeferrable" />
          <cs:ScalarProperty Name="IsInitiallyDeferred" ColumnName="IsInitiallyDeferred" />
          <cs:Condition ColumnName="ConstraintType" Value="UNIQUE"/>
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
      <cs:EntityTypeMapping TypeName="Store.CheckConstraint" >
        <cs:MappingFragment StoreEntitySet="SViewConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:ScalarProperty Name="Name" ColumnName="Name" />
          <cs:ScalarProperty Name="IsDeferrable" ColumnName="IsDeferrable" />
          <cs:ScalarProperty Name="IsInitiallyDeferred" ColumnName="IsInitiallyDeferred" />
          <cs:ScalarProperty Name="Expression" ColumnName="Expression" />
          <cs:Condition ColumnName="ConstraintType" Value="CHECK"/>
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
      <cs:EntityTypeMapping TypeName="Store.PrimaryKeyConstraint" >
        <cs:MappingFragment StoreEntitySet="SViewConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:ScalarProperty Name="Name" ColumnName="Name" />
          <cs:ScalarProperty Name="IsDeferrable" ColumnName="IsDeferrable" />
          <cs:ScalarProperty Name="IsInitiallyDeferred" ColumnName="IsInitiallyDeferred" />
          <cs:Condition ColumnName="ConstraintType" Value="PRIMARY KEY"/>
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
      <cs:EntityTypeMapping TypeName="Store.ForeignKeyConstraint" >
        <cs:MappingFragment StoreEntitySet="SViewConstraints">
          <cs:ScalarProperty Name="Id" ColumnName="Id" />
          <cs:ScalarProperty Name="Name" ColumnName="Name" />
          <cs:ScalarProperty Name="IsDeferrable" ColumnName="IsDeferrable" />
          <cs:ScalarProperty Name="IsInitiallyDeferred" ColumnName="IsInitiallyDeferred" />
          <cs:ScalarProperty Name="UpdateRule" ColumnName="UpdateRule" />
          <cs:ScalarProperty Name="DeleteRule" ColumnName="DeleteRule" />
          <cs:Condition ColumnName="ConstraintType" Value="FOREIGN KEY"/>
        </cs:MappingFragment>
      </cs:EntityTypeMapping>
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="TableForeignKeys" StoreEntitySet="SForeignKeys" TypeName="Store.ForeignKey">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="Ordinal" ColumnName="Ordinal" />
    </cs:EntitySetMapping>

    <cs:EntitySetMapping Name="ViewForeignKeys" StoreEntitySet="SViewForeignKeys" TypeName="Store.ForeignKey">
      <cs:ScalarProperty Name="Id" ColumnName="Id" />
      <cs:ScalarProperty Name="Ordinal" ColumnName="Ordinal" />
    </cs:EntitySetMapping>
    
    <cs:AssociationSetMapping Name="TableTableColumns" StoreEntitySet="STableColumns" TypeName="Store.TableOrViewColumn">
      <cs:EndProperty Name="Parent">
        <cs:ScalarProperty Name="Id" ColumnName="ParentId" />
      </cs:EndProperty>
      <cs:EndProperty Name="Column">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="ViewViewColumns" StoreEntitySet="SViewColumns" TypeName="Store.TableOrViewColumn">
      <cs:EndProperty Name="Parent">
        <cs:ScalarProperty Name="Id" ColumnName="ParentId" />
      </cs:EndProperty>
      <cs:EndProperty Name="Column">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="TableTableConstraints" StoreEntitySet="SConstraints" TypeName="Store.TableOrViewConstraint">
      <cs:EndProperty Name="Parent">
        <cs:ScalarProperty Name="Id" ColumnName="ParentId" />
      </cs:EndProperty>
      <cs:EndProperty Name="Constraint">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="TableConstraintColumns" StoreEntitySet="SConstraintColumns" TypeName="Store.TableOrViewConstraintColumn">
      <cs:EndProperty Name="Constraint">
        <cs:ScalarProperty Name="Id" ColumnName="ConstraintId" />
      </cs:EndProperty>
      <cs:EndProperty Name="Column">
        <cs:ScalarProperty Name="Id" ColumnName="ColumnId" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="TableConstraintForeignKeys" StoreEntitySet="SForeignKeys" TypeName="Store.ConstraintForeignKey">
      <cs:EndProperty Name="Constraint">
        <cs:ScalarProperty Name="Id" ColumnName="ConstraintId" />
      </cs:EndProperty>
      <cs:EndProperty Name="ForeignKey">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="ToTableForeignKeyColumns" StoreEntitySet="SForeignKeys" TypeName="Store.ToForeignKeyColumn">
      <cs:EndProperty Name="ForeignKey">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
      <cs:EndProperty Name="Column">
        <cs:ScalarProperty Name="Id" ColumnName="ToColumnId" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="FromTableForeignKeyColumns" StoreEntitySet="SForeignKeys" TypeName="Store.FromForeignKeyColumn">
      <cs:EndProperty Name="ForeignKey">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
      <cs:EndProperty Name="Column">
        <cs:ScalarProperty Name="Id" ColumnName="FromColumnId" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="ViewViewConstraints" StoreEntitySet="SViewConstraints" TypeName="Store.TableOrViewConstraint">
      <cs:EndProperty Name="Parent">
        <cs:ScalarProperty Name="Id" ColumnName="ParentId" />
      </cs:EndProperty>
      <cs:EndProperty Name="Constraint">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="ViewConstraintColumns" StoreEntitySet="SViewConstraintColumns" TypeName="Store.TableOrViewConstraintColumn">
      <cs:EndProperty Name="Constraint">
        <cs:ScalarProperty Name="Id" ColumnName="ConstraintId" />
      </cs:EndProperty>
      <cs:EndProperty Name="Column">
        <cs:ScalarProperty Name="Id" ColumnName="ColumnId" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="ViewConstraintForeignKeys" StoreEntitySet="SViewForeignKeys" TypeName="Store.ConstraintForeignKey">
      <cs:EndProperty Name="Constraint">
        <cs:ScalarProperty Name="Id" ColumnName="ConstraintId" />
      </cs:EndProperty>
      <cs:EndProperty Name="ForeignKey">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="ToViewForeignKeyColumns" StoreEntitySet="SViewForeignKeys" TypeName="Store.ToForeignKeyColumn">
      <cs:EndProperty Name="ForeignKey">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
      <cs:EndProperty Name="Column">
        <cs:ScalarProperty Name="Id" ColumnName="ToColumnId" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="FromViewForeignKeyColumns" StoreEntitySet="SViewForeignKeys" TypeName="Store.FromForeignKeyColumn">
      <cs:EndProperty Name="ForeignKey">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
      <cs:EndProperty Name="Column">
        <cs:ScalarProperty Name="Id" ColumnName="FromColumnId" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="FunctionFunctionParameters" StoreEntitySet="SFunctionParameters" TypeName="Store.RoutineParameter">
      <cs:EndProperty Name="Routine">
        <cs:ScalarProperty Name="Id" ColumnName="ParentId" />
      </cs:EndProperty>
      <cs:EndProperty Name="Parameter">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

    <cs:AssociationSetMapping Name="ProcedureProcedureParameters" StoreEntitySet="SProcedureParameters" TypeName="Store.RoutineParameter">
      <cs:EndProperty Name="Routine">
        <cs:ScalarProperty Name="Id" ColumnName="ParentId" />
      </cs:EndProperty>
      <cs:EndProperty Name="Parameter">
        <cs:ScalarProperty Name="Id" ColumnName="Id" />
      </cs:EndProperty>
    </cs:AssociationSetMapping>

  </cs:EntityContainerMapping>

</Mapping>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/Resources/System.Data.Resources.CSDLSchema.xsd.
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
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration" xmlns:edm="http://schemas.microsoft.com/ado/2006/04/edm" targetNamespace="http://schemas.microsoft.com/ado/2006/04/edm">
  <xs:annotation>
    <xs:documentation xml:lang="en">
            Common Data Model Schema Definition Language.
            Copyright (c) Microsoft Corp. All rights reserved.
        </xs:documentation>
  </xs:annotation>
  <xs:import namespace="http://schemas.microsoft.com/ado/2006/04/codegeneration" schemaLocation="System.Data.Resources.CodeGenerationSchema.xsd" />
  <xs:element name="Schema" type="edm:TSchema" />
  <xs:complexType name="TSchema">
    <xs:sequence>
      <xs:group ref="edm:GSchemaBodyElements" minOccurs="0" maxOccurs="unbounded" />
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="Namespace" type="edm:TNamespaceName" use="required" />
    <xs:attribute name="Alias" type="edm:TSimpleIdentifier" use="optional" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:group name="GSchemaBodyElements">
    <xs:choice>
      <xs:element name="Using" type="edm:TUsing" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="Association" type="edm:TAssociation" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="ComplexType" type="edm:TComplexType" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="EntityType" type="edm:TEntityType" minOccurs="0" maxOccurs="unbounded" />
      <xs:element ref="edm:EntityContainer" minOccurs="1" maxOccurs="1" />
    </xs:choice>
  </xs:group>
  <!-- EDM SimpleType instances for use by EDM Instance documents-->
  <xs:simpleType name="EDMSimpleType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Binary" />
      <xs:enumeration value="Boolean" />
      <xs:enumeration value="Byte" />
      <xs:enumeration value="DateTime" />
      <xs:enumeration value="DateTimeOffset" />
      <xs:enumeration value="Time" />
      <xs:enumeration value="Decimal" />
      <xs:enumeration value="Double" />
      <xs:enumeration value="Single" />
      <xs:enumeration value="Guid" />
      <xs:enumeration value="Int16" />
      <xs:enumeration value="Int32" />
      <xs:enumeration value="Int64" />
      <xs:enumeration value="String" />
      <xs:enumeration value="SByte" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="TMax">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Max" />
    </xs:restriction>
  </xs:simpleType>
  <!-- Facets for Primitive types -->
  <xs:simpleType name="TMaxLengthFacet">
    <xs:union memberTypes="edm:TMax xs:nonNegativeInteger  " />
  </xs:simpleType>
  <xs:simpleType name="TIsFixedLengthFacet">
    <xs:restriction base="xs:boolean" />
  </xs:simpleType>
  <xs:simpleType name="TPrecisionFacet">
    <xs:restriction base="xs:nonNegativeInteger" />
  </xs:simpleType>
  <xs:simpleType name="TScaleFacet">
    <xs:restriction base="xs:nonNegativeInteger" />
  </xs:simpleType>
  <xs:simpleType name="TIsUnicodeFacet">
    <xs:restriction base="xs:boolean" />
  </xs:simpleType>
  <xs:simpleType name="TCollationFacet">
    <xs:restriction base="xs:string" />
  </xs:simpleType>
  <!--
        types at all levels
    -->
  <xs:complexType name="TDocumentation">
    <xs:annotation>
      <xs:documentation>The Documentation element is used to provide documentation of comments on the contents of the XML file.  It is valid under Schema, Type, Index and Relationship elements.</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="Summary" type="edm:TText" minOccurs="0" maxOccurs="1" />
      <xs:element name="LongDescription" type="edm:TText" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:anyAttribute processContents="lax" namespace="##other" />
  </xs:complexType>
  <xs:complexType name="TText" mixed="true">
    <xs:sequence>
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:anyAttribute processContents="lax" namespace="##other" />
  </xs:complexType>
  <xs:complexType name="TXmlOrText" mixed="true">
    <xs:annotation>
      <xs:documentation>This type allows pretty much any content</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:any namespace="##any" processContents="skip" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:anyAttribute processContents="skip" namespace="##any" />
  </xs:complexType>
  <!-- 
        types of the top level elements 
    -->
  <xs:complexType name="TUsing">
    <xs:sequence>
      <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name="Namespace" type="edm:TNamespaceName" use="required" />
    <xs:attribute name="Alias" type="edm:TSimpleIdentifier" use="required" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TAssociation">
    <xs:sequence>
      <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
      <xs:element name="End" type="edm:TAssociationEnd" minOccurs="2" maxOccurs="2" />
      <xs:element name="ReferentialConstraint" type="edm:TConstraint" minOccurs="0" maxOccurs="1" />
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
    <!--<xs:attribute name="Identifying" type="xs:boolean" use="optional" default="false" />-->
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TComplexType">
    <xs:sequence>
      <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
      <xs:element name="Property" type="edm:TComplexTypeProperty" minOccurs="0" maxOccurs="unbounded" />
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attributeGroup ref="edm:TTypeAttributes" />
    <xs:attribute ref="cg:TypeAccess" use="optional" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TConstraint">
    <xs:sequence>
      <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
      <xs:element name="Principal" type="edm:TReferentialConstraintRoleElement" minOccurs="1" maxOccurs="1" />
      <xs:element name="Dependent" type="edm:TReferentialConstraintRoleElement" minOccurs="1" maxOccurs="1" />
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TReferentialConstraintRoleElement">
    <xs:sequence>
      <xs:element name="PropertyRef" type="edm:TPropertyRef" minOccurs="1" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="Role" type="edm:TSimpleIdentifier" use="required" />
  </xs:complexType>
  <xs:complexType name="TNavigationProperty">
    <xs:sequence>
      <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
    <xs:attribute name="Relationship" type="edm:TQualifiedName" use="required" />
    <xs:attribute name="ToRole" type="edm:TSimpleIdentifier" use="required" />
    <xs:attribute name="FromRole" type="edm:TSimpleIdentifier" use="required" />
    <xs:attribute ref="cg:GetterAccess" use="optional" />
    <xs:attribute ref="cg:SetterAccess" use="optional" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TEntityType">
    <xs:sequence>
      <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
      <xs:element name="Key" type="edm:TEntityKeyElement" minOccurs="0" maxOccurs="1" />
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Property" type="edm:TEntityProperty" minOccurs="0" maxOccurs="unbounded" />
        <xs:element name="NavigationProperty" type="edm:TNavigationProperty" minOccurs="0" maxOccurs="unbounded" />
      </xs:choice>
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attributeGroup ref="edm:TDerivableTypeAttributes" />
    <xs:attribute ref="cg:TypeAccess" use="optional" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TEntityKeyElement">
    <xs:sequence>
      <xs:element name="PropertyRef" type="edm:TPropertyRef" minOccurs="1" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="TPropertyRef">
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
  </xs:complexType>
  <xs:group name="GEmptyElementExtensibility">
    <xs:sequence>
      <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:group>
  <!-- 
        base types  
    -->
  <xs:complexType name="TAssociationEnd">
    <xs:sequence>
      <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
      <xs:group ref="edm:TOperations" minOccurs="0" maxOccurs="unbounded" />
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="Type" type="edm:TQualifiedName" use="required" />
    <xs:attribute name="Role" type="edm:TSimpleIdentifier" use="optional" />
    <xs:attribute name="Multiplicity" type="edm:TMultiplicity" use="required" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:group name="TOperations">
    <xs:choice>
      <xs:element name="OnDelete" type="edm:TOnAction" maxOccurs="1" minOccurs="0" />
    </xs:choice>
  </xs:group>
  <xs:complexType name="TOnAction">
    <xs:sequence>
      <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name="Action" type="edm:TAction" use="required" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TEntityProperty">
    <xs:sequence>
      <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attributeGroup ref="edm:TCommonPropertyAttributes" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TComplexTypeProperty">
    <xs:sequence>
      <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attributeGroup ref="edm:TCommonPropertyAttributes" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:complexType name="TFunctionImportParameter">
    <xs:sequence>
      <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attributeGroup ref="edm:TFunctionImportParameterAttributes" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  <xs:attributeGroup name="TCommonPropertyAttributes">
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
    <xs:attribute name="Type" type="edm:TPropertyType" use="required" />
    <xs:attribute name="Nullable" type="xs:boolean" default="true" use="optional" />
    <xs:attribute name="DefaultValue" type="xs:string" use="optional" />
    <!-- Start Facets -->
    <xs:attribute name="MaxLength" type="edm:TMaxLengthFacet" use="optional" />
    <xs:attribute name="FixedLength" type="edm:TIsFixedLengthFacet" use="optional" />
    <xs:attribute name="Precision" type="edm:TPrecisionFacet" use="optional" />
    <xs:attribute name="Scale" type="edm:TScaleFacet" use="optional" />
    <xs:attribute name="Unicode" type="edm:TIsUnicodeFacet" use="optional" />
    <xs:attribute name="Collation" type="edm:TCollationFacet" use="optional" />
    <!--End Facets -->
    <xs:attribute name="ConcurrencyMode" type="edm:TConcurrencyMode" use="optional" />
    <xs:attribute ref="cg:SetterAccess" use="optional" />
    <xs:attribute ref="cg:GetterAccess" use="optional" />
  </xs:attributeGroup>
  <xs:attributeGroup name="TFunctionImportParameterAttributes">
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
    <xs:attribute name="Type" type="edm:TPropertyType" use="required" />
    <xs:attribute name="Mode" type="edm:TParameterMode" use="optional" />
    <xs:attribute name="MaxLength" type="edm:TMaxLengthFacet" use="optional" />
    <xs:attribute name="Precision" type="edm:TPrecisionFacet" use="optional" />
    <xs:attribute name="Scale" type="edm:TScaleFacet" use="optional" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:attributeGroup>
  <xs:attributeGroup name="TFunctionImportAttributes">
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
    <xs:attribute name="ReturnType" type="edm:TFunctionType" use="optional" />
    <xs:attribute name="EntitySet" type="edm:TSimpleIdentifier" use="optional" />
    <xs:attribute ref="cg:MethodAccess" use="optional" />
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:attributeGroup>
  <xs:attributeGroup name="TTypeAttributes">
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
    <!-- not in wave 4 -->
    <!--<xs:attribute name="FriendSchemas" type="TNameList" use="optional" />-->
    <!--<xs:attribute name="Visibility" type="TVisibility" use="optional" />-->
  </xs:attributeGroup>
  <xs:attributeGroup name="TDerivableTypeAttributes">
    <xs:attributeGroup ref="edm:TTypeAttributes" />
    <xs:attribute name="BaseType" type="edm:TQualifiedName" use="optional" />
    <xs:attribute name="Abstract" type="xs:boolean" use="optional" default="false" />
  </xs:attributeGroup>
  <xs:attributeGroup name="TEntitySetAttributes">
    <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
    <xs:attribute name="EntityType" type="edm:TQualifiedName" use="required" />
    <xs:attribute ref="cg:GetterAccess" use="optional" />
  </xs:attributeGroup>
  <xs:element name="EntityContainer">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="FunctionImport">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
                <xs:element name="Parameter" type="edm:TFunctionImportParameter" minOccurs="0" maxOccurs="unbounded" />
              </xs:sequence>
              <xs:attributeGroup ref="edm:TFunctionImportAttributes" />
            </xs:complexType>
          </xs:element>
          <xs:element name="EntitySet">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
              </xs:sequence>
              <xs:attributeGroup ref="edm:TEntitySetAttributes" />
              <xs:anyAttribute processContents="lax" namespace="##other" />
            </xs:complexType>
          </xs:element>
          <xs:element name="AssociationSet">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
                <xs:element name="End" minOccurs="0" maxOccurs="2">
                  <!-- 1. The number of Ends has to match with ones defined in AssociationType 
                                         2. Value for attribute Name should match the defined ones and EntitySet should be of the 
                                            defined Entity Type in AssociationType 
                                    -->
                  <xs:complexType>
                    <xs:sequence>
                      <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1" />
                    </xs:sequence>
                    <xs:attribute name="Role" type="edm:TSimpleIdentifier" use="optional" />
                    <xs:attribute name="EntitySet" type="edm:TSimpleIdentifier" use="required" />
                  </xs:complexType>
                </xs:element>
                <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
              </xs:sequence>
              <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
              <xs:attribute name="Association" type="edm:TQualifiedName" use="required" />
              <xs:anyAttribute namespace="##other" processContents="lax" />
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
      <xs:attribute name="Extends" type ="edm:TSimpleIdentifier" use="optional" />
    </xs:complexType>
  </xs:element>
  <!-- 
    general  (more or less) purpose simple types 
    -->
  <xs:simpleType name="TParameterMode">
    <xs:restriction base="xs:token">
      <xs:enumeration value="In" />
      <xs:enumeration value="Out" />
      <xs:enumeration value="InOut" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="TNamespaceName">
    <xs:restriction base="edm:TQualifiedName">
      <xs:maxLength value="512" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="TQualifiedName">
    <xs:restriction base="xs:string">
      <!-- The below pattern represents the allowed identifiers in ECMA specification plus the '.' for namespace qualification  -->
      <xs:pattern value="[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}(\.[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}){0,}" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="TSimpleIdentifier">
    <xs:restriction base="xs:string">
      <xs:maxLength value="480" />
      <!-- The below pattern represents the allowed identifiers in ECMA specification -->
      <xs:pattern value="[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="TPropertyType">
    <xs:union memberTypes="edm:EDMSimpleType edm:TQualifiedName  ">
      <xs:simpleType>
        <xs:restriction base="xs:token">
          <!-- The below pattern represents the allowed identifiers in ECMA specification plus the '.' for namespace qualification  -->
          <xs:pattern value="[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}(\.[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}){0,}" />
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
  <xs:simpleType name="TFunctionType">
    <xs:union memberTypes="edm:TQualifiedName    ">
      <xs:simpleType>
        <xs:restriction base="xs:token">
          <xs:pattern value="Collection\([^ \t]{1,}(\.[^ \t]{1,}){0,}\)" />
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
  <xs:simpleType name="TAction">
    <xs:restriction base="xs:token">
      <xs:enumeration value="Cascade" />
      <xs:enumeration value="None" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="TMultiplicity">
    <xs:restriction base="xs:token">
      <xs:enumeration value="0..1" />
      <xs:enumeration value="1" />
      <xs:enumeration value="*" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="TConcurrencyMode">
    <xs:restriction base="xs:token">
      <xs:enumeration value="None" />
      <xs:enumeration value="Fixed" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/Resources/System.Data.Resources.CSMSL.xsd.
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
<?xml version="1.0"?>
<!-- XSD for CS( CDM <-> Storage ) space mapping. -->
<xs:schema xmlns:tns="urn:schemas-microsoft-com:windows:storage:mapping:CS" 
           attributeFormDefault="unqualified" 
           elementFormDefault="qualified" 
           targetNamespace="urn:schemas-microsoft-com:windows:storage:mapping:CS" 
           xmlns:csmsl="urn:schemas-microsoft-com:windows:storage:mapping:CS" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:annotation>
    <xs:documentation xml:lang="en">
      Common Data Model Schema Definition Language.
      Copyright (c) Microsoft Corp. All rights reserved.
    </xs:documentation>
  </xs:annotation>
  
  <!-- Root Level element for CS Mapping -->
  <xs:element name="Mapping" type="csmsl:TMapping"/>

  <!-- Type of Root level mapping elements-->
  <xs:complexType name="TMapping">
    <!-- Top level Mapping element can have Alias elements followed by 
         EntityContainer Mapping element-->
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Alias" type="csmsl:TAlias"/>
      <!-- For now we will allow only one EntityContainerMapping to be mapped per MSL File.-->
      <xs:element name="EntityContainerMapping" type="csmsl:TEntityContainerMapping"/>
    </xs:sequence>
    <!-- Space represents the space that the mapping occurs. For CS Mapping
         it always has to be "C-S"-->
    <xs:attribute name="Space" type="csmsl:TSpace" use="required" fixed="C-S" />
  </xs:complexType>

  <!-- Type for QueryView Element -->
  <xs:complexType name="TQueryView">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute name="TypeName" type="xs:string" use="optional" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>




  <!-- Type for Alias Element-->
  <xs:complexType name="TAlias">
    <xs:attribute name="Key" type="csmsl:TSimpleIdentifier" use="required" />
    <xs:attribute name="Value" type="xs:string" use="required" />
  </xs:complexType>

  <!-- Type for EntityContainerMapping Element-->
  <xs:complexType name="TEntityContainerMapping">
    <xs:sequence>
      <xs:choice maxOccurs="unbounded">
        <xs:element minOccurs="0" name="EntitySetMapping" type="csmsl:TEntitySetMapping"/>
        <xs:element minOccurs="0" name="AssociationSetMapping" type="csmsl:TAssociationSetMapping"/>
        <xs:element minOccurs="0" name="FunctionImportMapping" type="csmsl:TFunctionImportMapping"/>
      </xs:choice>
    </xs:sequence>
    <xs:attribute name="CdmEntityContainer" type="csmsl:TSimpleIdentifier" use="required" />
    <xs:attribute name="StorageEntityContainer" type="xs:string" use="required" />
  </xs:complexType>

  <!-- Type for FunctionImport Mapping element -->
  <xs:complexType name="TFunctionImportMapping">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="ResultMapping" type="csmsl:TFunctionImportMappingResultMapping"/>
    </xs:sequence>
    <xs:attribute name="FunctionName" type="xs:string" use="required"/>
    <xs:attribute name="FunctionImportName" type="csmsl:TSimpleIdentifier" use="required"/>
  </xs:complexType>
  
  <!-- Type for FunctionImport/ResultMapping element -->
  <xs:complexType name="TFunctionImportMappingResultMapping">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="EntityTypeMapping" type="csmsl:TFunctionImportEntityTypeMapping"/>
    </xs:sequence>    
  </xs:complexType>

  <!-- Type for EntitySet Mapping element-->
  <xs:complexType name="TEntitySetMapping">
    <xs:choice>
      <xs:choice>
        <xs:sequence>
          <xs:element name="QueryView" type="csmsl:TQueryView" minOccurs="0" maxOccurs="unbounded"/>
    
          <xs:element name="EntityTypeMapping" type="csmsl:TEntityTypeMapping" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:sequence>
          <xs:element name="MappingFragment" type="csmsl:TMappingFragment" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
      </xs:choice>
      <xs:group ref="csmsl:TPropertyGroup"/>
    </xs:choice>
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required" />
    <xs:attribute name="TypeName" type="xs:string" use="optional" />
    <xs:attribute name="StoreEntitySet" type="xs:string" use="optional" />
  </xs:complexType>

  <!-- Type for AssociationSetMapping element-->
  <xs:complexType name="TAssociationSetMapping">
    <xs:sequence>
      <xs:element name="QueryView" type="xs:string" minOccurs="0" maxOccurs="1"/>          
      <xs:element name="EndProperty" type="csmsl:TEndProperty" minOccurs="0" maxOccurs="2"/>
      <xs:element name="Condition" type="csmsl:TCondition" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="ModificationFunctionMapping" type="csmsl:TAssociationSetModificationFunctionMapping" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required" />
    <xs:attribute name="TypeName" type="csmsl:TQualifiedName" use="optional" />
    <xs:attribute name="StoreEntitySet" type="xs:string" use="optional" />
  </xs:complexType>

  <!-- Type for EntityTypeMapping element-->
  <xs:complexType name="TEntityTypeMapping">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="MappingFragment" type="csmsl:TMappingFragment"/>
      <xs:element minOccurs="0" maxOccurs="1" name="ModificationFunctionMapping" type="csmsl:TEntityTypeModificationFunctionMapping"/>
    </xs:sequence>
    <xs:attribute name="TypeName" type="xs:string" use="required" />
  </xs:complexType>
  
  <!-- Type for FunctionImport EntityTypeMapping element-->
  <xs:complexType name="TFunctionImportEntityTypeMapping">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Condition" type="csmsl:TFunctionImportCondition"/>
    </xs:sequence>
    <xs:attribute name="TypeName" type="xs:string" use="required" />
  </xs:complexType>

  <!-- Type for MappingFragment Element-->
  <xs:complexType name="TMappingFragment">
    <xs:group ref="csmsl:TPropertyGroup" minOccurs="1" maxOccurs="1"/>
    <xs:attribute name="StoreEntitySet" type="xs:string" use="required" />
  </xs:complexType>

  <!-- Type for EntityTypeMapping/ModificationFunctionMapping element -->
  <xs:complexType name="TEntityTypeModificationFunctionMapping">
    <xs:all>
      <xs:element minOccurs="1" maxOccurs="1" name="DeleteFunction" type="csmsl:TEntityTypeModificationFunction"/>
      <xs:element minOccurs="1" maxOccurs="1" name="InsertFunction" type="csmsl:TEntityTypeModificationFunctionWithResult"/>
      <xs:element minOccurs="1" maxOccurs="1" name="UpdateFunction" type="csmsl:TEntityTypeModificationFunctionWithResult"/>
    </xs:all>
  </xs:complexType>
  
  <!-- Type for AssociationSetMapping/ModificationFunctionMapping element -->
  <xs:complexType name="TAssociationSetModificationFunctionMapping">
    <xs:all>
      <xs:element minOccurs="1" maxOccurs="1" name="DeleteFunction" type="csmsl:TAssociationSetModificationFunction"/>
      <xs:element minOccurs="1" maxOccurs="1" name="InsertFunction" type="csmsl:TAssociationSetModificationFunction"/>
    </xs:all>
  </xs:complexType>

  <!-- Type for entity type DeleteFunction -->
  <xs:complexType name="TEntityTypeModificationFunction">
    <xs:group ref="csmsl:TEntityTypeFunctionMappingPropertyGroup" minOccurs="1" maxOccurs="1"/>
    <xs:attribute name="FunctionName" type="xs:string" use="required"/>
    <xs:attribute name="RowsAffectedParameter" type="xs:string" use="optional"/>
  </xs:complexType>

  <!-- Extensions to modification function for entity type InsertFunction and UpdateFunction -->
  <xs:complexType name="TEntityTypeModificationFunctionWithResult">
    <xs:complexContent>
      <xs:extension base="csmsl:TEntityTypeModificationFunction">
        <xs:group ref="csmsl:TResultBindingGroup" minOccurs="1" maxOccurs="1"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <!-- Type for association set DeleteFunction and InsertFunction -->
  <xs:complexType name="TAssociationSetModificationFunction">
    <xs:group ref="csmsl:TAssociationSetFunctionMappingPropertyGroup" minOccurs="1" maxOccurs="1"/>
    <xs:attribute name="FunctionName" type="xs:string" use="required"/>
    <xs:attribute name="RowsAffectedParameter" type="xs:string" use="optional"/>
  </xs:complexType>

  <!-- Grouping for entity type function mappings -->
  <xs:group name="TEntityTypeFunctionMappingPropertyGroup">
    <xs:sequence>
      <xs:choice maxOccurs="unbounded">
        <xs:element minOccurs="0" name="ScalarProperty" type="csmsl:TFunctionMappingScalarProperty"/>
        <xs:element minOccurs="0" name="AssociationEnd" type="csmsl:TFunctionMappingAssociationEnd"/>
        <xs:element minOccurs="0" name="ComplexProperty" type="csmsl:TFunctionMappingComplexProperty"/>
      </xs:choice>
    </xs:sequence>
  </xs:group>

  <!-- Grouping for entity type function mappings -->
  <xs:group name="TAssociationSetFunctionMappingPropertyGroup">
    <xs:sequence>
      <xs:choice maxOccurs="unbounded">
        <xs:element minOccurs="1" name="EndProperty" type="csmsl:TFunctionMappingEndProperty"/>
      </xs:choice>
    </xs:sequence>
  </xs:group>

  <!-- Type for function mapping end property -->
  <xs:complexType name="TFunctionMappingEndProperty">
    <xs:group ref="csmsl:TFunctionMappingAssociationEndPropertyGroup" minOccurs="1" maxOccurs="1"/>
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required"/>
  </xs:complexType>

  <!-- Type for function mapping scalar property -->
  <xs:complexType name="TFunctionMappingScalarProperty">
    <xs:attribute name="ParameterName" type="xs:string" use="required"/>
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required"/>
    <xs:attribute name="Version" type="csmsl:TVersion" use="optional"/>
  </xs:complexType>

  <!-- Type for function mapping result binding -->
  <xs:complexType name="TResultBinding">
    <xs:attribute name="ColumnName" type="xs:string" use="required"/>
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required"/>
  </xs:complexType>

  <!-- Type for function mapping association end -->
  <xs:complexType name="TFunctionMappingAssociationEnd">
    <xs:group ref="csmsl:TFunctionMappingAssociationEndPropertyGroup" minOccurs="1" maxOccurs="1"/>
    <xs:attribute name="AssociationSet" type="csmsl:TSimpleIdentifier" use="required"/>
    <xs:attribute name="From" type="csmsl:TSimpleIdentifier" use="required"/>
    <xs:attribute name="To" type="csmsl:TSimpleIdentifier" use="required"/>
  </xs:complexType>

  <!-- Grouping for property bindings in function mapping end property -->
  <xs:group name="TFunctionMappingAssociationEndPropertyGroup">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="ScalarProperty" type="csmsl:TFunctionMappingScalarProperty"/>
    </xs:sequence>
  </xs:group>

  <!-- Type for function mapping complex property -->
  <xs:complexType name="TFunctionMappingComplexProperty">
    <xs:group ref="csmsl:TFunctionMappingComplexPropertyPropertyGroup" minOccurs="1" maxOccurs="1"/>
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required"/>
    <xs:attribute name="TypeName" type="xs:string" use="required"/>
  </xs:complexType>  

  <!-- Grouping for result bindings in function mappings -->
  <xs:group name="TResultBindingGroup">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="ResultBinding" type="csmsl:TResultBinding"/>
    </xs:sequence>
  </xs:group>

  <!-- Grouping for property bindings in function mapping association end -->
  <xs:group name="TFunctionMappingComplexPropertyPropertyGroup">
    <xs:sequence>
      <xs:choice maxOccurs="unbounded">
        <xs:element minOccurs="0" name="ScalarProperty" type="csmsl:TFunctionMappingScalarProperty"/>
        <xs:element minOccurs="0" name="ComplexProperty" type="csmsl:TFunctionMappingComplexProperty"/>
      </xs:choice>
    </xs:sequence>
  </xs:group>

  <!-- Grouping these elements so that they can be reused
       These elements represent the property group
       that can either directly reside unser EntitySet, EntityType
       or MappingFragment-->
  <xs:group name="TPropertyGroup">
    <xs:sequence>
      <xs:choice maxOccurs="unbounded">
        <xs:element minOccurs="0" name="ComplexProperty" type="csmsl:TComplexProperty"/>
        <xs:element minOccurs="0" name="ScalarProperty" type="csmsl:TScalarProperty"/>
        <xs:element minOccurs="0" name="Condition" type="csmsl:TCondition"/>
      </xs:choice>
    </xs:sequence>
  </xs:group>

  <!-- Type for Condition Element-->
  <xs:complexType name="TCondition">
    <xs:attribute name="Value" type="xs:string" use="optional" />
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="optional" />
    <xs:attribute name="ColumnName" type="xs:string" use="optional" />
    <xs:attribute name="IsNull" type="xs:boolean" use="optional" />
  </xs:complexType>

  <!-- Type for FunctionImport Condition element-->
  <xs:complexType name="TFunctionImportCondition">
    <xs:attribute name="Value" type="xs:string" use="optional" />
    <xs:attribute name="ColumnName" type="xs:string" use="required" />
    <xs:attribute name="IsNull" type="xs:boolean" use="optional" />
  </xs:complexType>

  <!-- Type for End Property Elements in Association Maps -->
  <xs:complexType name="TEndProperty">
    <xs:sequence>
      <xs:element maxOccurs="unbounded" name="ScalarProperty" type="csmsl:TScalarProperty"/>
    </xs:sequence>
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required" />
  </xs:complexType>

  <!-- Type for Complex Property Map elements-->
  <xs:complexType name="TComplexProperty">
    <xs:sequence>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="ScalarProperty" type="csmsl:TScalarProperty"/>
        <xs:element name="ComplexProperty" type="csmsl:TComplexProperty"/>
        <xs:element name="ComplexTypeMapping" type="csmsl:TComplexTypeMapping"/>
        <xs:element name="Condition" type="csmsl:TCondition"/>
      </xs:choice>
    </xs:sequence>
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required" />
    <xs:attribute name="TypeName" type="xs:string" use="optional" />
    <xs:attribute name="IsPartial" type="xs:boolean" use="optional" />
  </xs:complexType>

  <!-- Type for Complex Type mapping element-->
  <xs:complexType name="TComplexTypeMapping">
    <xs:sequence>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="ScalarProperty" type="csmsl:TScalarProperty"/>
        <xs:element name="ComplexProperty" type="csmsl:TComplexProperty"/>
        <xs:element name="Condition" type="csmsl:TCondition"/>
      </xs:choice>
    </xs:sequence>
    <xs:attribute name="TypeName" type="xs:string" use="optional" />
    <xs:attribute name="IsPartial" type="xs:boolean" use="optional" />
  </xs:complexType>
  
  <!-- Type for ScalarProperty Element-->
  <xs:complexType name="TScalarProperty">
    <xs:attribute name="Name" type="csmsl:TSimpleIdentifier" use="required" />
    <xs:attribute name="ColumnName" type="xs:string" use="required" />
  </xs:complexType>

  <!--Definition for SimpleIdentifier
      This is the same definition that is being used in the CSDL XSD
      -->
  <xs:simpleType name="TSimpleIdentifier">
    <xs:restriction base="xs:token">
        <!-- The below pattern represents the allowed identifiers in ECMA specification -->
        <xs:pattern value="[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}"/>
    </xs:restriction>
  </xs:simpleType>


  <!--Definition for QualifiedName. QualifiedName is SimpleIdentifiers with '.'
      allowed. This is the same definition that is being used in the CSDL XSD
      -->
  <xs:simpleType name="TQualifiedName">
    <xs:restriction base="xs:token">
        <!-- The below pattern represents the allowed identifiers in ECMA specification plus the '.' for namespace qualification  -->
         <xs:pattern value="[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}(\.[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}){0,}"/>
    </xs:restriction>
  </xs:simpleType>

  <!--Definition for Version, which can 'original' or 'current' as its value-->
  <xs:simpleType name="TVersion">
    <xs:restriction base="xs:token">
      <xs:enumeration value="Original"/>
      <xs:enumeration value="Current"/>
    </xs:restriction>
  </xs:simpleType>

  <!-- Type fopr Space or Type Attribute -->
  <xs:simpleType name="TSpace">
    <xs:restriction base="xs:token">
      <xs:enumeration value="C-S" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/Resources/System.Data.Resources.CodeGenerationSchema.xsd.
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
<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema id="CodeGenerationSchema" 
                  targetNamespace="http://schemas.microsoft.com/ado/2006/04/codegeneration"
                  elementFormDefault="unqualified"
                  xmlns="http://schemas.microsoft.com/ado/2006/04/codegeneration"
                  xmlns:xs="http://www.w3.org/2001/XMLSchema">


    <xs:attribute name="SetterAccess" type="TAccess"/>
    <xs:attribute name="GetterAccess" type="TAccess"/>
    <xs:attribute name="TypeAccess" type="TPublicOrInternalAccess"/>
    <xs:attribute name="MethodAccess" type="TAccess"/>
  
    <xs:simpleType name="TAccess">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Public" />
            <xs:enumeration value="Internal" />
			      <xs:enumeration value="Protected" />
            <xs:enumeration value="Private" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="TPublicOrInternalAccess">
        <xs:restriction base="TAccess">
            <xs:enumeration value="Public" />
            <xs:enumeration value="Internal" />
        </xs:restriction>
    </xs:simpleType>

</xs:schema>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































Deleted System.Data.SQLite.Linq/Resources/System.Data.Resources.EntityStoreSchemaGenerator.xsd.
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
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" attributeFormDefault="unqualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:source="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
           targetNamespace="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator">
    <xs:annotation>
        <xs:documentation xml:lang="en">
            Common Data Model Schema Definition Language.
            Copyright (c) Microsoft Corp. All rights reserved.
        </xs:documentation>
    </xs:annotation>


  <xs:attribute name="Type" type="source:TSourceType"/>
  <xs:attribute name="Schema" type="xs:string"/>
  <xs:attribute name="Name" type="xs:string"/>

    <xs:simpleType name="TSourceType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Tables" />
            <xs:enumeration value="Views" />
        </xs:restriction>
    </xs:simpleType>

</xs:schema>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































Deleted System.Data.SQLite.Linq/Resources/System.Data.Resources.SSDLSchema.xsd.
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
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" attributeFormDefault="unqualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:edm="http://schemas.microsoft.com/ado/2006/04/edm/ssdl"
           xmlns:gen="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" 
           targetNamespace="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
    <xs:annotation>
        <xs:documentation xml:lang="en">
            Common Data Model Schema Definition Language.
            Copyright (c) Microsoft Corp. All rights reserved.
        </xs:documentation>
    </xs:annotation>
  <xs:import namespace="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" schemaLocation="System.Data.Resources.EntityStoreSchemaGenerator.xsd" />
  <xs:element name="Schema" type="edm:TSchema"/>
    <xs:complexType name="TSchema">
        <xs:sequence>
            <xs:group ref="edm:GSchemaBodyElements" minOccurs="0" maxOccurs="unbounded"/>
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="Namespace" type="edm:TQualifiedName" use="required" />
        <xs:attribute name="Alias" type="edm:TSimpleIdentifier" use="optional" />
        <xs:attribute name="Provider" type="edm:TSimpleIdentifier" use="required" />
        <xs:attribute name="ProviderManifestToken" type="edm:TSimpleIdentifier" use="required" />      
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:group name="GSchemaBodyElements">
        <xs:choice>
            <xs:element name="Association" type="edm:TAssociation" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="EntityType" type="edm:TEntityType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="edm:EntityContainer" minOccurs="1" maxOccurs="1"/>
            <xs:element name="Function" type="edm:TFunction" minOccurs="0" maxOccurs="unbounded" />
        </xs:choice>
    </xs:group>

    <xs:simpleType name="TMax">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Max"/>
        </xs:restriction>
    </xs:simpleType>

    <!-- Facets for Primitive types -->
    <xs:simpleType name="TMaxLengthFacet">
        <xs:union memberTypes="edm:TMax xs:nonNegativeInteger"/>
    </xs:simpleType>

    <xs:simpleType name="TIsFixedLengthFacet">
        <xs:restriction base="xs:boolean"/>
    </xs:simpleType>

    <xs:simpleType name="TKindFacet">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Utc"/>
            <xs:enumeration value="Local"/>
            <xs:enumeration value="Unspecified"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="TPrecisionFacet">
        <xs:restriction base="xs:nonNegativeInteger"/>
    </xs:simpleType>

    <xs:simpleType name="TScaleFacet">
        <xs:restriction base="xs:nonNegativeInteger"/>
    </xs:simpleType>

    <xs:simpleType name="TIsUnicodeFacet">
        <xs:restriction base="xs:boolean"/>
    </xs:simpleType>

    <xs:simpleType name="TCollationFacet">
        <xs:restriction base="xs:string"/>
    </xs:simpleType>

    <!-- 
        types of the top level elements 
    -->
   <xs:complexType name="TDocumentation">
    <xs:annotation>
      <xs:documentation>The Documentation element is used to provide documentation of comments on the contents of the XML file. It is valid under Schema, Type, Index and Relationship elements.
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="Summary" type="edm:TText" minOccurs="0" maxOccurs="1" />
      <xs:element name="LongDescription" type="edm:TText" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:anyAttribute processContents="lax" namespace="##other" />
  </xs:complexType>

  <xs:complexType name="TText" mixed="true">
    <xs:sequence>
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:anyAttribute processContents="lax" namespace="##other" />
  </xs:complexType>


    <xs:complexType name="TUsing">
        <xs:sequence>
            <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:attribute name="Namespace" type="edm:TQualifiedName" use="required" />
        <xs:attribute name="Alias" type="edm:TSimpleIdentifier" use="required" />
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:complexType name="TAssociation">
        <xs:sequence>
            <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
            <xs:element name="End" type="edm:TAssociationEnd" minOccurs="2" maxOccurs="2"/>
            <xs:element name="ReferentialConstraint" type="edm:TConstraint" minOccurs="0" maxOccurs="1" />
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
        <!--<xs:attribute name="Identifying" type="xs:boolean" use="optional" default="false" />-->
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:complexType name="TConstraint">
        <xs:sequence>
            <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
            <xs:element name="Principal" type="edm:TReferentialConstraintRoleElement" minOccurs="1" maxOccurs="1" />
            <xs:element name="Dependent" type="edm:TReferentialConstraintRoleElement" minOccurs="1" maxOccurs="1" />
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="TNavigationProperty">
        <xs:sequence>
            <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
        <xs:attribute name="Relationship" type="edm:TQualifiedName" use ="required" />
        <xs:attribute name="ToRole" type="edm:TSimpleIdentifier" use="required" />
        <xs:attribute name="FromRole" type="edm:TSimpleIdentifier" use="required" />
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:complexType name="TReferentialConstraintRoleElement">
        <xs:sequence>
            <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
            <xs:element name="PropertyRef" type="edm:TPropertyRef" minOccurs="1" maxOccurs="unbounded" />
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="Role" type="edm:TSimpleIdentifier" use="required" />
        <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="TEntityType">
        <xs:sequence>
            <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
            <xs:element name="Key" type="edm:TEntityKeyElement" minOccurs="0" maxOccurs="1"/>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="Property" type="edm:TEntityProperty" minOccurs="0" maxOccurs="unbounded" />
                <xs:element name="NavigationProperty" type="edm:TNavigationProperty" minOccurs="0" maxOccurs="unbounded"/>
            </xs:choice>
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
        <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name ="TEntityKeyElement">
        <xs:sequence>
            <xs:element name="PropertyRef" type="edm:TPropertyRef" minOccurs="1" maxOccurs="unbounded" />
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="TPropertyRef">
        <xs:sequence>
            <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1" />
        </xs:sequence>
        <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:group name="GEmptyElementExtensibility">
        <xs:sequence>
            <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:group>

    <!-- 
        base types  
    -->
    <xs:complexType name="TAssociationEnd">
        <xs:sequence>
            <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
            <xs:group ref="edm:TOperations" minOccurs="0" maxOccurs="unbounded" />
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="Type" type="edm:TQualifiedName" use="required" />
        <xs:attribute name="Role" type="edm:TSimpleIdentifier" use="optional" />
        <xs:attribute name="Multiplicity" type="edm:TMultiplicity" use="required" />
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:group name="TOperations">
        <xs:choice>
            <xs:element name="OnDelete" type="edm:TOnAction" maxOccurs="1" minOccurs="0" />
        </xs:choice>
    </xs:group>

    <xs:complexType name="TOnAction">
        <xs:sequence>
            <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:attribute name="Action" type="edm:TAction" use="required" />
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:complexType name="TEntityProperty">
        <xs:sequence>
            <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:attributeGroup ref="edm:TCommonPropertyAttributes"/>
        <xs:attribute name="StoreGeneratedPattern" type="edm:TStoreGeneratedPattern" use="optional" />
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:attributeGroup name="TCommonPropertyAttributes">
        <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
        <xs:attribute name="Type" type="edm:TPropertyType" use="required" />
        <xs:attribute name="Nullable" type="xs:boolean" default="true" use="optional" />
        <xs:attribute name="DefaultValue" type="xs:string" use="optional" />

        <!-- Start Facets -->
        <xs:attribute name="MaxLength" type="edm:TMaxLengthFacet" use="optional" />
        <xs:attribute name="FixedLength" type="edm:TIsFixedLengthFacet" use="optional" />
        <xs:attribute name="Precision" type="edm:TPrecisionFacet" use="optional" />
        <xs:attribute name="Scale" type="edm:TScaleFacet" use="optional" />
        <xs:attribute name="Unicode" type="edm:TIsUnicodeFacet" use="optional" />
        <xs:attribute name="Collation" type="edm:TCollationFacet" use="optional" />
        <!--End Facets -->
    </xs:attributeGroup>

    <xs:attributeGroup name="TEntitySetAttributes">
        <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
        <xs:attribute name="EntityType" type="edm:TQualifiedName" use="required" />
        <xs:attribute name="Schema" type="edm:TSimpleIdentifier" use="optional" />
        <xs:attribute name="Table" type="edm:TSimpleIdentifier" use="optional" />

    </xs:attributeGroup>

    <xs:element name="EntityContainer">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="EntitySet">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
                                <xs:element name="DefiningQuery" type="edm:TCommandText" minOccurs="0" maxOccurs="1"/>
                                <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
                            </xs:sequence>
                            <xs:attributeGroup ref="edm:TEntitySetAttributes"/>
                          <xs:attribute ref="gen:Type" use="optional"/>
                          <xs:attribute ref="gen:Schema" use="optional"/>
                          <xs:attribute ref="gen:Name" use="optional"/>
                          <xs:anyAttribute processContents="lax" namespace="##other" />
                        </xs:complexType>
                    </xs:element>

                    <xs:element name="AssociationSet">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
                                <xs:element name="End" minOccurs="0" maxOccurs="2">
                                    <!-- 1. The number of Ends has to match with ones defined in AssociationType 
                                         2. Value for attribute Name should match the defined ones and EntitySet should be of the 
                                            defined Entity Type in AssociationType 
                                    -->
                                    <xs:complexType>
                                        <xs:sequence>
                                            <xs:group ref="edm:GEmptyElementExtensibility" minOccurs="0" maxOccurs="1"/>
                                        </xs:sequence>
                                        <xs:attribute name="Role" type="edm:TSimpleIdentifier" use="optional" />
                                        <xs:attribute name="EntitySet" type="edm:TSimpleIdentifier" use="required" />
                                    </xs:complexType>
                                </xs:element>
                                <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
                            </xs:sequence>
                            <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
                            <xs:attribute name="Association" type="edm:TQualifiedName" use="required" />
                            <xs:anyAttribute namespace="##other" processContents="lax" />
                        </xs:complexType>
                    </xs:element>
                </xs:choice>
            </xs:sequence>
            <xs:attribute name="Name" type="edm:TSimpleIdentifier" use="required" />
        </xs:complexType>
    </xs:element>

    <xs:complexType name="TFunction">
        <xs:sequence>
            <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
            <xs:element name="CommandText" type="edm:TCommandText" minOccurs="0" maxOccurs="1" />
            <xs:element name="Parameter" type="edm:TParameter" minOccurs="0" maxOccurs="unbounded" />
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="Name" type="xs:string" use="required" />
        <xs:attribute name="ReturnType" type="edm:TFunctionType" use="optional" />
        <xs:attribute name="Aggregate" type="xs:boolean" use="optional" />
        <xs:attribute name="BuiltIn" type="xs:boolean" use="optional" />
        <xs:attribute name="StoreFunctionName" type="xs:string" use="optional" />
        <xs:attribute name="NiladicFunction" type="xs:boolean" use="optional" />
        <xs:attribute name="IsComposable" type="xs:boolean" use="optional" default="true" />
        <xs:attribute name="ParameterTypeSemantics" type="edm:TParameterTypeSemantics" use="optional" default="AllowImplicitConversion" />
        <xs:attribute name="Schema" type="edm:TSimpleIdentifier" use="optional" />
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:complexType name="TParameter">
        <xs:sequence>
            <xs:element name="Documentation" type="edm:TDocumentation" minOccurs="0" maxOccurs="1" />
            <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="Name" type="xs:string" use="required" />
        <xs:attribute name="Type" type="edm:TFunctionType" use="required" />
        <xs:attribute name="Mode" type="edm:TParameterMode" use="optional" />
        <!-- Start Facets -->
        <xs:attribute name="MaxLength" type="edm:TMaxLengthFacet" use="optional" />
        <xs:attribute name="Precision" type="edm:TPrecisionFacet" use="optional" />
        <xs:attribute name="Scale" type="edm:TScaleFacet" use="optional" />
        <!--End Facets -->
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <!-- 
    general (more or less) purpose simple types 
    -->

  <xs:simpleType name="TCommandText">
    <xs:restriction base="xs:string">
      <xs:whiteSpace value="preserve"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="TQualifiedName">
        <xs:restriction base="xs:string"/>
    </xs:simpleType>

    <xs:simpleType name="TSimpleIdentifier">
        <xs:restriction base="xs:string"/>
    </xs:simpleType>

    <xs:simpleType name="TPropertyType">
        <xs:union memberTypes="edm:TQualifiedName">
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <!-- The below pattern represents the allowed identifiers in ECMA specification plus the '.' for namespace qualification -->
                    <xs:pattern value="[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}(\.[\p{L}\p{Nl}][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]{0,}){0,}" />
                </xs:restriction>
            </xs:simpleType>
        </xs:union>
    </xs:simpleType>

    <xs:simpleType name="TAction">
        <xs:restriction base="xs:token">
            <xs:enumeration value="Cascade" />
            <xs:enumeration value="Restrict" />
            <xs:enumeration value="None" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="TMultiplicity">
    <xs:restriction base="xs:token">
      <xs:enumeration value="0..1" />
      <xs:enumeration value="1" />
      <xs:enumeration value="*" />
    </xs:restriction>
  </xs:simpleType>

    <xs:simpleType name="TStoreGeneratedPattern">
        <xs:restriction base="xs:token">
            <xs:enumeration value="None" />
            <xs:enumeration value="Identity" />
            <xs:enumeration value="Computed" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="TParameterMode">
        <xs:restriction base="xs:token">
            <xs:enumeration value="In" />
            <xs:enumeration value="Out" />
            <xs:enumeration value="InOut" />
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="TFunctionType">
        <xs:union memberTypes="edm:TQualifiedName ">
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <xs:pattern value="Collection\([^ \t]{1,}(\.[^ \t]{1,}){0,}\)" />
                </xs:restriction>
            </xs:simpleType>
        </xs:union>
    </xs:simpleType>
    <xs:simpleType name="TParameterTypeSemantics">
        <xs:restriction base="xs:token">
            <xs:enumeration value="ExactMatchOnly" />
            <xs:enumeration value="AllowImplicitPromotion" />
            <xs:enumeration value="AllowImplicitConversion" />
        </xs:restriction>
    </xs:simpleType>


</xs:schema>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/DmlSqlGenerator.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
//---------------------------------------------------------------------
// <copyright file="DmlSqlGenerator.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Globalization;
  using System.Text;
  using System.Data;
  using System.Data.Common;
  using System.Data.Metadata.Edm;
  using System.Data.Common.CommandTrees;

    /// <summary>
  /// Class generating SQL for a DML command tree.
  /// </summary>
  internal static class DmlSqlGenerator
  {
    private static readonly int s_commandTextBuilderInitialCapacity = 256;

    internal static string GenerateUpdateSql(DbUpdateCommandTree tree, out List<DbParameter> parameters)
    {
      StringBuilder commandText = new StringBuilder(s_commandTextBuilderInitialCapacity);
      ExpressionTranslator translator = new ExpressionTranslator(commandText, tree, null != tree.Returning, "UpdateFunction");

      // update [schemaName].[tableName]
      commandText.Append("UPDATE ");
      tree.Target.Expression.Accept(translator);
      commandText.AppendLine();

      // set c1 = ..., c2 = ..., ...
      bool first = true;
      commandText.Append("SET ");
      foreach (DbSetClause setClause in tree.SetClauses)
      {
        if (first) { first = false; }
        else { commandText.Append(", "); }
        setClause.Property.Accept(translator);
        commandText.Append(" = ");
        setClause.Value.Accept(translator);
      }

      if (first)
      {
        // If first is still true, it indicates there were no set
        // clauses. Introduce a fake set clause so that:
        // - we acquire the appropriate locks
        // - server-gen columns (e.g. timestamp) get recomputed
        //
        // We use the following pattern:
        //
        //  update Foo
        //  set @i = 0
        //  where ...
        DbParameter parameter = translator.CreateParameter(default(Int32), DbType.Int32);
        commandText.Append(parameter.ParameterName);
        commandText.Append(" = 0");
      }
      commandText.AppendLine();

      // where c1 = ..., c2 = ...
      commandText.Append("WHERE ");
      tree.Predicate.Accept(translator);
      commandText.AppendLine();

      // generate returning sql
      GenerateReturningSql(commandText, tree, translator, tree.Returning);

      parameters = translator.Parameters;
      return commandText.ToString();
    }

    internal static string GenerateDeleteSql(DbDeleteCommandTree tree, out List<DbParameter> parameters)
    {
      StringBuilder commandText = new StringBuilder(s_commandTextBuilderInitialCapacity);
      ExpressionTranslator translator = new ExpressionTranslator(commandText, tree, false, "DeleteFunction");

      // delete [schemaName].[tableName]
      commandText.Append("DELETE FROM ");
      tree.Target.Expression.Accept(translator);
      commandText.AppendLine();

      // where c1 = ... AND c2 = ...
      commandText.Append("WHERE ");
      tree.Predicate.Accept(translator);

      parameters = translator.Parameters;

      commandText.AppendLine(";");
      return commandText.ToString();
    }

    internal static string GenerateInsertSql(DbInsertCommandTree tree, out List<DbParameter> parameters)
    {
      StringBuilder commandText = new StringBuilder(s_commandTextBuilderInitialCapacity);
      ExpressionTranslator translator = new ExpressionTranslator(commandText, tree, null != tree.Returning, "InsertFunction");

      // insert [schemaName].[tableName]
      commandText.Append("INSERT INTO ");
      tree.Target.Expression.Accept(translator);

      if (tree.SetClauses.Count > 0)
      {
        // (c1, c2, c3, ...)
        commandText.Append("(");
        bool first = true;
        foreach (DbSetClause setClause in tree.SetClauses)
        {
          if (first) { first = false; }
          else { commandText.Append(", "); }
          setClause.Property.Accept(translator);
        }
        commandText.AppendLine(")");

        // values c1, c2, ...
        first = true;
        commandText.Append(" VALUES (");
        foreach (DbSetClause setClause in tree.SetClauses)
        {
          if (first) { first = false; }
          else { commandText.Append(", "); }
          setClause.Value.Accept(translator);

          translator.RegisterMemberValue(setClause.Property, setClause.Value);
        }
        commandText.AppendLine(");");
      }
      else // No columns specified.  Insert an empty row containing default values by inserting null into the rowid
      {
        commandText.AppendLine(" DEFAULT VALUES;");
      }

      // generate returning sql
      GenerateReturningSql(commandText, tree, translator, tree.Returning);

      parameters = translator.Parameters;
      return commandText.ToString();
    }

    // Generates T-SQL describing a member
    // Requires: member must belong to an entity type (a safe requirement for DML
    // SQL gen, where we only access table columns)
    private static string GenerateMemberTSql(EdmMember member)
    {
      return SqlGenerator.QuoteIdentifier(member.Name);
    }

    /// <summary>
    /// Generates SQL fragment returning server-generated values.
    /// Requires: translator knows about member values so that we can figure out
    /// how to construct the key predicate.
    /// <code>
    /// Sample SQL:
    ///     
    ///     select IdentityValue
    ///     from dbo.MyTable
    ///     where @@ROWCOUNT > 0 and IdentityValue = scope_identity()
    /// 
    /// or
    /// 
    ///     select TimestamptValue
    ///     from dbo.MyTable
    ///     where @@ROWCOUNT > 0 and Id = 1
    /// 
    /// Note that we filter on rowcount to ensure no rows are returned if no rows were modified.
    /// </code>
    /// </summary>
    /// <param name="commandText">Builder containing command text</param>
    /// <param name="tree">Modification command tree</param>
    /// <param name="translator">Translator used to produce DML SQL statement
    /// for the tree</param>
    /// <param name="returning">Returning expression. If null, the method returns
    /// immediately without producing a SELECT statement.</param>
    private static void GenerateReturningSql(StringBuilder commandText, DbModificationCommandTree tree,
        ExpressionTranslator translator, DbExpression returning)
    {
      // Nothing to do if there is no Returning expression
      if (null == returning) { return; }

      // select
      commandText.Append("SELECT ");
      returning.Accept(translator);
      commandText.AppendLine();

      // from
      commandText.Append("FROM ");
      tree.Target.Expression.Accept(translator);
      commandText.AppendLine();

      // where
      commandText.Append("WHERE last_rows_affected() > 0");
      EntitySetBase table = ((DbScanExpression)tree.Target.Expression).Target;
      bool identity = false;
      foreach (EdmMember keyMember in table.ElementType.KeyMembers)
      {
        commandText.Append(" AND ");
        commandText.Append(GenerateMemberTSql(keyMember));
        commandText.Append(" = ");

        // retrieve member value sql. the translator remembers member values
        // as it constructs the DML statement (which precedes the "returning"
        // SQL)
        DbParameter value;
        if (translator.MemberValues.TryGetValue(keyMember, out value))
        {
          commandText.Append(value.ParameterName);
        }
        else
        {
          // if no value is registered for the key member, it means it is an identity
          // which can be retrieved using the scope_identity() function
          if (identity)
          {
            // there can be only one server generated key
            throw new NotSupportedException(string.Format("Server generated keys are only supported for identity columns. More than one key column is marked as server generated in table '{0}'.", table.Name));
          }
          commandText.AppendLine("last_insert_rowid();");
          identity = true;
        }
      }
    }

    /// <summary>
    /// Lightweight expression translator for DML expression trees, which have constrained
    /// scope and support.
    /// </summary>
    private class ExpressionTranslator : DbExpressionVisitor
    {
      /// <summary>
      /// Initialize a new expression translator populating the given string builder
      /// with command text. Command text builder and command tree must not be null.
      /// </summary>
      /// <param name="commandText">Command text with which to populate commands</param>
      /// <param name="commandTree">Command tree generating SQL</param>
      /// <param name="preserveMemberValues">Indicates whether the translator should preserve
      /// member values while compiling t-SQL (only needed for server generation)</param>
      /// <param name="kind"></param>
      internal ExpressionTranslator(StringBuilder commandText, DbModificationCommandTree commandTree,
          bool preserveMemberValues, string kind)
      {
        Debug.Assert(null != commandText);
        Debug.Assert(null != commandTree);
        _kind = kind;
        _commandText = commandText;
        _commandTree = commandTree;
        _parameters = new List<DbParameter>();
        _memberValues = preserveMemberValues ? new Dictionary<EdmMember, DbParameter>() :
            null;
      }

      private readonly StringBuilder _commandText;
      private readonly DbModificationCommandTree _commandTree;
      private readonly List<DbParameter> _parameters;
      private readonly Dictionary<EdmMember, DbParameter> _memberValues;
      private int parameterNameCount = 0;
      private string _kind;

      internal List<DbParameter> Parameters { get { return _parameters; } }
      internal Dictionary<EdmMember, DbParameter> MemberValues { get { return _memberValues; } }

      // generate parameter (name based on parameter ordinal)
      internal SQLiteParameter CreateParameter(object value, TypeUsage type)
      {
        PrimitiveTypeKind primitiveType = MetadataHelpers.GetPrimitiveTypeKind(type);
        DbType dbType = MetadataHelpers.GetDbType(primitiveType);
        return CreateParameter(value, dbType);
      }

      // Creates a new parameter for a value in this expression translator
      internal SQLiteParameter CreateParameter(object value, DbType dbType)
      {
        string parameterName = string.Concat("@p", parameterNameCount.ToString(CultureInfo.InvariantCulture));
        parameterNameCount++;
        SQLiteParameter parameter = new SQLiteParameter(parameterName, value);
        parameter.DbType = dbType;
        _parameters.Add(parameter);
        return parameter;
      }

      #region Basics

      public override void Visit(DbApplyExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");

        VisitExpressionBindingPre(expression.Input);
        if (expression.Apply != null)
        {
          VisitExpression(expression.Apply.Expression);
        }
        VisitExpressionBindingPost(expression.Input);
      }

      public override void Visit(DbArithmeticExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionList(expression.Arguments);
      }

      public override void Visit(DbCaseExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionList(expression.When);
        VisitExpressionList(expression.Then);
        VisitExpression(expression.Else);
      }

      public override void Visit(DbCastExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbCrossJoinExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        foreach (DbExpressionBinding binding in expression.Inputs)
        {
          VisitExpressionBindingPre(binding);
        }
        foreach (DbExpressionBinding binding2 in expression.Inputs)
        {
          VisitExpressionBindingPost(binding2);
        }
      }

      public override void Visit(DbDerefExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbDistinctExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbElementExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbEntityRefExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbExceptExpression expression)
      {
        VisitBinary(expression);
      }

      protected virtual void VisitBinary(DbBinaryExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        this.VisitExpression(expression.Left);
        this.VisitExpression(expression.Right);
      }

      public override void Visit(DbExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        throw new NotSupportedException("DbExpression");
      }

      public override void Visit(DbFilterExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionBindingPre(expression.Input);
        VisitExpression(expression.Predicate);
        VisitExpressionBindingPost(expression.Input);
      }

      public override void Visit(DbFunctionExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionList(expression.Arguments);
        //if (expression.IsLambda)
        //{
        //  VisitLambdaFunctionPre(expression.Function, expression.LambdaBody);
        //  VisitExpression(expression.LambdaBody);
        //  VisitLambdaFunctionPost(expression.Function, expression.LambdaBody);
        //}
      }

      public override void Visit(DbGroupByExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitGroupExpressionBindingPre(expression.Input);
        VisitExpressionList(expression.Keys);
        VisitGroupExpressionBindingMid(expression.Input);
        VisitAggregateList(expression.Aggregates);
        VisitGroupExpressionBindingPost(expression.Input);
      }

      public override void Visit(DbIntersectExpression expression)
      {
        VisitBinary(expression);
      }

      public override void Visit(DbIsEmptyExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbIsOfExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbJoinExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionBindingPre(expression.Left);
        VisitExpressionBindingPre(expression.Right);
        VisitExpression(expression.JoinCondition);
        VisitExpressionBindingPost(expression.Left);
        VisitExpressionBindingPost(expression.Right);
      }

      public override void Visit(DbLikeExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpression(expression.Argument);
        VisitExpression(expression.Pattern);
        VisitExpression(expression.Escape);
      }

      public override void Visit(DbLimitExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpression(expression.Argument);
        VisitExpression(expression.Limit);
      }

      public override void Visit(DbOfTypeExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbParameterReferenceExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
      }

      public override void Visit(DbProjectExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionBindingPre(expression.Input);
        VisitExpression(expression.Projection);
        VisitExpressionBindingPost(expression.Input);
      }

      public override void Visit(DbQuantifierExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionBindingPre(expression.Input);
        VisitExpression(expression.Predicate);
        VisitExpressionBindingPost(expression.Input);
      }

      public override void Visit(DbRefExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbRefKeyExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbRelationshipNavigationExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpression(expression.NavigationSource);
      }

      public override void Visit(DbSkipExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionBindingPre(expression.Input);
        foreach (DbSortClause clause in expression.SortOrder)
        {
          VisitExpression(clause.Expression);
        }
        VisitExpressionBindingPost(expression.Input);
        VisitExpression(expression.Count);
      }

      public override void Visit(DbSortExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpressionBindingPre(expression.Input);
        for (int i = 0; i < expression.SortOrder.Count; i++)
        {
          VisitExpression(expression.SortOrder[i].Expression);
        }
        VisitExpressionBindingPost(expression.Input);
      }

      public override void Visit(DbTreatExpression expression)
      {
        VisitUnaryExpression(expression);
      }

      public override void Visit(DbUnionAllExpression expression)
      {
        VisitBinary(expression);
      }

      public override void Visit(DbVariableReferenceExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
      }

      public virtual void VisitAggregate(DbAggregate aggregate)
      {
        if (aggregate == null) throw new ArgumentException("aggregate");
        VisitExpressionList(aggregate.Arguments);
      }

      public virtual void VisitAggregateList(IList<DbAggregate> aggregates)
      {
        if (aggregates == null) throw new ArgumentException("aggregates");
        for (int i = 0; i < aggregates.Count; i++)
        {
          VisitAggregate(aggregates[i]);
        }
      }

      public virtual void VisitExpression(DbExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        expression.Accept(this);
      }

      protected virtual void VisitExpressionBindingPost(DbExpressionBinding binding)
      {
      }

      protected virtual void VisitExpressionBindingPre(DbExpressionBinding binding)
      {
        if (binding == null) throw new ArgumentException("binding");
        VisitExpression(binding.Expression);
      }

      public virtual void VisitExpressionList(IList<DbExpression> expressionList)
      {
        if (expressionList == null) throw new ArgumentException("expressionList");
        for (int i = 0; i < expressionList.Count; i++)
        {
          VisitExpression(expressionList[i]);
        }
      }

      protected virtual void VisitGroupExpressionBindingMid(DbGroupExpressionBinding binding)
      {
      }

      protected virtual void VisitGroupExpressionBindingPost(DbGroupExpressionBinding binding)
      {
      }

      protected virtual void VisitGroupExpressionBindingPre(DbGroupExpressionBinding binding)
      {
        if (binding == null) throw new ArgumentException("binding");
        VisitExpression(binding.Expression);
      }

      protected virtual void VisitLambdaFunctionPost(EdmFunction function, DbExpression body)
      {
      }

      protected virtual void VisitLambdaFunctionPre(EdmFunction function, DbExpression body)
      {
        if (function == null) throw new ArgumentException("function");
        if (body == null) throw new ArgumentException("body");
      }

      //internal virtual void VisitRelatedEntityReference(DbRelatedEntityRef relatedEntityRef)
      //{
      //  VisitExpression(relatedEntityRef.TargetEntityReference);
      //}

      //internal virtual void VisitRelatedEntityReferenceList(IList<DbRelatedEntityRef> relatedEntityReferences)
      //{
      //  for (int i = 0; i < relatedEntityReferences.Count; i++)
      //  {
      //    VisitRelatedEntityReference(relatedEntityReferences[i]);
      //  }
      //}

      protected virtual void VisitUnaryExpression(DbUnaryExpression expression)
      {
        if (expression == null) throw new ArgumentException("expression");
        VisitExpression(expression.Argument);
      }
      #endregion

      public override void Visit(DbAndExpression expression)
      {
        VisitBinary(expression, " AND ");
      }

      public override void Visit(DbOrExpression expression)
      {
        VisitBinary(expression, " OR ");
      }

      public override void Visit(DbComparisonExpression expression)
      {
        Debug.Assert(expression.ExpressionKind == DbExpressionKind.Equals,
            "only equals comparison expressions are produced in DML command trees in V1");

        VisitBinary(expression, " = ");

        RegisterMemberValue(expression.Left, expression.Right);
      }

      /// <summary>
      /// Call this method to register a property value pair so the translator "remembers"
      /// the values for members of the row being modified. These values can then be used
      /// to form a predicate for server-generation (based on the key of the row)
      /// </summary>
      /// <param name="propertyExpression">DbExpression containing the column reference (property expression).</param>
      /// <param name="value">DbExpression containing the value of the column.</param>
      internal void RegisterMemberValue(DbExpression propertyExpression, DbExpression value)
      {
        if (null != _memberValues)
        {
          // register the value for this property
          Debug.Assert(propertyExpression.ExpressionKind == DbExpressionKind.Property,
              "DML predicates and setters must be of the form property = value");

          // get name of left property 
          EdmMember property = ((DbPropertyExpression)propertyExpression).Property;

          // don't track null values
          if (value.ExpressionKind != DbExpressionKind.Null)
          {
            Debug.Assert(value.ExpressionKind == DbExpressionKind.Constant,
                "value must either constant or null");
            // retrieve the last parameter added (which describes the parameter)
            _memberValues[property] = _parameters[_parameters.Count - 1];
          }
        }
      }

      public override void Visit(DbIsNullExpression expression)
      {
        expression.Argument.Accept(this);
        _commandText.Append(" IS NULL");
      }

      public override void Visit(DbNotExpression expression)
      {
        _commandText.Append("NOT (");
        expression.Accept(this);
        _commandText.Append(")");
      }

      public override void Visit(DbConstantExpression expression)
      {
        SQLiteParameter parameter = CreateParameter(expression.Value, expression.ResultType);
        _commandText.Append(parameter.ParameterName);
      }

      public override void Visit(DbScanExpression expression)
      {
        string definingQuery = MetadataHelpers.TryGetValueForMetadataProperty<string>(expression.Target, "DefiningQuery");
        if (definingQuery != null)
        {
          throw new NotSupportedException(String.Format("Unable to update the EntitySet '{0}' because it has a DefiningQuery and no <{1}> element exists in the <ModificationFunctionMapping> element to support the current operation.", expression.Target.Name, _kind));
        }
        _commandText.Append(SqlGenerator.GetTargetTSql(expression.Target));
      }

      public override void Visit(DbPropertyExpression expression)
      {
        _commandText.Append(GenerateMemberTSql(expression.Property));
      }

      public override void Visit(DbNullExpression expression)
      {
        _commandText.Append("NULL");
      }

      public override void Visit(DbNewInstanceExpression expression)
      {
        // assumes all arguments are self-describing (no need to use aliases
        // because no renames are ever used in the projection)
        bool first = true;
        foreach (DbExpression argument in expression.Arguments)
        {
          if (first) { first = false; }
          else { _commandText.Append(", "); }
          argument.Accept(this);
        }
      }

      private void VisitBinary(DbBinaryExpression expression, string separator)
      {
        _commandText.Append("(");
        expression.Left.Accept(this);
        _commandText.Append(separator);
        expression.Right.Accept(this);
        _commandText.Append(")");
      }
    }
  }
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/ISqlFragment.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
//---------------------------------------------------------------------
// <copyright file="ISqlFragment.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System.Data.Common.CommandTrees;

  /// <summary>
  /// Represents the sql fragment for any node in the query tree.
  /// </summary>
  /// <remarks>
  /// The nodes in a query tree produce various kinds of sql
  /// <list type="bullet">
  /// <item>A select statement.</item>
  /// <item>A reference to an extent. (symbol)</item>
  /// <item>A raw string.</item>
  /// </list>
  /// We have this interface to allow for a common return type for the methods
  /// in the expression visitor <see cref="DbExpressionVisitor{T}"/>
  /// 
  /// At the end of translation, the sql fragments are converted into real strings.
  /// </remarks>
  internal interface ISqlFragment
  {
    /// <summary>
    /// Write the string represented by this fragment into the stream.
    /// </summary>
    /// <param name="writer">The stream that collects the strings.</param>
    /// <param name="sqlGenerator">Context information used for renaming.
    /// The global lists are used to generated new names without collisions.</param>
    void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator);
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































Deleted System.Data.SQLite.Linq/SQL Generation/InternalBase.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
/********************************************************
 * 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.Text;

#if !NET_20
using System.Runtime;
#endif

namespace System.Data.SQLite
{
	internal abstract class InternalBase
	{
		// Methods
#if !NET_20
		[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
		protected InternalBase()
		{
		}

		internal abstract void ToCompactString(StringBuilder builder);
		internal virtual string ToFullString()
		{
			StringBuilder builder = new StringBuilder();
			this.ToFullString(builder);
			return builder.ToString();
		}

#if !NET_20
		[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
		internal virtual void ToFullString(StringBuilder builder)
		{
			this.ToCompactString(builder);
		}

		public override string ToString()
		{
			StringBuilder builder = new StringBuilder();
			this.ToCompactString(builder);
			return builder.ToString();
		}
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































Deleted System.Data.SQLite.Linq/SQL Generation/JoinSymbol.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
//---------------------------------------------------------------------
// <copyright file="JoinSymbol.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Data.Metadata.Edm;
  using System.Data.Common.CommandTrees;

  /// <summary>
  /// A Join symbol is a special kind of Symbol.
  /// It has to carry additional information
  /// <list type="bullet">
  /// <item>ColumnList for the list of columns in the select clause if this
  /// symbol represents a sql select statement.  This is set by <see cref="SqlGenerator.AddDefaultColumns"/>. </item>
  /// <item>ExtentList is the list of extents in the select clause.</item>
  /// <item>FlattenedExtentList - if the Join has multiple extents flattened at the 
  /// top level, we need this information to ensure that extent aliases are renamed
  /// correctly in <see cref="SqlSelectStatement.WriteSql"/></item>
  /// <item>NameToExtent has all the extents in ExtentList as a dictionary.
  /// This is used by <see cref="SqlGenerator.Visit(DbPropertyExpression)"/> to flatten
  /// record accesses.</item>
  /// <item>IsNestedJoin - is used to determine whether a JoinSymbol is an 
  /// ordinary join symbol, or one that has a corresponding SqlSelectStatement.</item>
  /// </list>
  /// 
  /// All the lists are set exactly once, and then used for lookups/enumerated.
  /// </summary>
  internal sealed class JoinSymbol : Symbol
  {
    private List<Symbol> columnList;
    internal List<Symbol> ColumnList
    {
      get
      {
        if (null == columnList)
        {
          columnList = new List<Symbol>();
        }
        return columnList;
      }
      set { columnList = value; }
    }

    private List<Symbol> extentList;
    internal List<Symbol> ExtentList
    {
      get { return extentList; }
    }

    private List<Symbol> flattenedExtentList;
    internal List<Symbol> FlattenedExtentList
    {
      get
      {
        if (null == flattenedExtentList)
        {
          flattenedExtentList = new List<Symbol>();
        }
        return flattenedExtentList;
      }
      set { flattenedExtentList = value; }
    }

    private Dictionary<string, Symbol> nameToExtent;
    internal Dictionary<string, Symbol> NameToExtent
    {
      get { return nameToExtent; }
    }

    private bool isNestedJoin;
    internal bool IsNestedJoin
    {
      get { return isNestedJoin; }
      set { isNestedJoin = value; }
    }

    public JoinSymbol(string name, TypeUsage type, List<Symbol> extents)
      : base(name, type)
    {
      extentList = new List<Symbol>(extents.Count);
      nameToExtent = new Dictionary<string, Symbol>(extents.Count, StringComparer.OrdinalIgnoreCase);
      foreach (Symbol symbol in extents)
      {
        this.nameToExtent[symbol.Name] = symbol;
        this.ExtentList.Add(symbol);
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/KeyToListMap.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
/********************************************************
 * 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.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections;

#if !NET_20
using System.Runtime;
#endif

namespace System.Data.SQLite
{
	internal class KeyToListMap<TKey, TValue> : InternalBase
	{
		// Fields
		private Dictionary<TKey, List<TValue>> m_map;

		// Methods
		internal KeyToListMap(IEqualityComparer<TKey> comparer)
		{
			this.m_map = new Dictionary<TKey, List<TValue>>(comparer);
		}

		internal void Add(TKey key, TValue value)
		{
			List<TValue> list;
			if (!this.m_map.TryGetValue(key, out list))
			{
				list = new List<TValue>();
				this.m_map[key] = list;
			}
			list.Add(value);
		}

		internal void AddRange(TKey key, IEnumerable<TValue> values)
		{
			foreach (TValue local in values)
			{
				this.Add(key, local);
			}
		}

		internal bool ContainsKey(TKey key)
		{
			return this.m_map.ContainsKey(key);
		}

		internal IEnumerable<TValue> EnumerateValues(TKey key)
		{
			List<TValue> values;
			if (m_map.TryGetValue(key, out values))
			{
				foreach (TValue value in values) { yield return value; }
			}
		}

		internal ReadOnlyCollection<TValue> ListForKey(TKey key)
		{
			return new ReadOnlyCollection<TValue>(this.m_map[key]);
		}

		internal bool RemoveKey(TKey key)
		{
			return this.m_map.Remove(key);
		}

		internal override void ToCompactString(StringBuilder builder)
		{
			foreach (TKey local in this.Keys)
			{
				StringUtil.FormatStringBuilder(builder, "{0}", new object[] { local });
				builder.Append(": ");
				IEnumerable<TValue> list = this.ListForKey(local);
				StringUtil.ToSeparatedString(builder, list, ",", "null");
				builder.Append("; ");
			}
		}

		internal bool TryGetListForKey(TKey key, out ReadOnlyCollection<TValue> valueCollection)
		{
			List<TValue> list;
			valueCollection = null;
			if (this.m_map.TryGetValue(key, out list))
			{
				valueCollection = new ReadOnlyCollection<TValue>(list);
				return true;
			}
			return false;
		}

		// Properties
		internal IEnumerable<TValue> AllValues
		{
			get
			{
				foreach (TKey key in Keys)
				{
					foreach (TValue value in ListForKey(key))
					{
						yield return value;
					}
				}
			}
		}

		internal IEnumerable<TKey> Keys
		{
			get
			{
				return this.m_map.Keys;
			}
		}

		internal IEnumerable<KeyValuePair<TKey, List<TValue>>> KeyValuePairs
		{
#if !NET_20
			[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
			get
			{
				return this.m_map;
			}
		}
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/License.txt.
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
Microsoft Public License (Ms-PL)

This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.

1. Definitions

The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.

A "contribution" is the original software, or any additions or changes to the software.

A "contributor" is any person that distributes its contribution under this license.

"Licensed patents" are a contributor's patent claims that read directly on its contribution.

2. Grant of Rights

(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.

(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.

3. Conditions and Limitations

(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.

(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.

(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.

(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.

(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. 
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































Deleted System.Data.SQLite.Linq/SQL Generation/MetadataHelpers.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
//---------------------------------------------------------------------
// <copyright file="MetadataHelpers.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Collections.Generic;
  using System.Data.Metadata.Edm;
  using System.Diagnostics;

  /// <summary>
  /// A set of static helpers for type metadata
  /// </summary>
  static class MetadataHelpers
  {
    #region Type Helpers

    /// <summary>
    /// Cast the EdmType of the given type usage to the given TEdmType
    /// </summary>
    /// <typeparam name="TEdmType"></typeparam>
    /// <param name="typeUsage"></param>
    /// <returns></returns>
    internal static TEdmType GetEdmType<TEdmType>(TypeUsage typeUsage)
        where TEdmType : EdmType
    {
      return (TEdmType)typeUsage.EdmType;
    }

    /// <summary>
    /// Gets the TypeUsage of the elment if the given type is a collection type
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    internal static TypeUsage GetElementTypeUsage(TypeUsage type)
    {
      if (MetadataHelpers.IsCollectionType(type))
      {
        return ((CollectionType)type.EdmType).TypeUsage;
      }
      return null;
    }

    /// <summary>
    /// Retrieves the properties of in the EdmType underlying the input type usage, 
    ///  if that EdmType is a structured type (EntityType, RowType). 
    /// </summary>
    /// <param name="typeUsage"></param>
    /// <returns></returns>
    internal static IList<EdmProperty> GetProperties(TypeUsage typeUsage)
    {
      return MetadataHelpers.GetProperties(typeUsage.EdmType);
    }

    /// <summary>
    /// Retrieves the properties of the given EdmType, if it is
    ///  a structured type (EntityType, RowType). 
    /// </summary>
    /// <param name="edmType"></param>
    /// <returns></returns>
    internal static IList<EdmProperty> GetProperties(EdmType edmType)
    {
      switch (edmType.BuiltInTypeKind)
      {
        case BuiltInTypeKind.ComplexType:
          return ((ComplexType)edmType).Properties;
        case BuiltInTypeKind.EntityType:
          return ((EntityType)edmType).Properties;
        case BuiltInTypeKind.RowType:
          return ((RowType)edmType).Properties;
        default:
          return new List<EdmProperty>();
      }
    }

    /// <summary>
    /// Is the given type usage over a collection type
    /// </summary>
    /// <param name="typeUsage"></param>
    /// <returns></returns>
    internal static bool IsCollectionType(TypeUsage typeUsage)
    {
      return MetadataHelpers.IsCollectionType(typeUsage.EdmType);
    }

    /// <summary>
    /// Is the given type a collection type
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    internal static bool IsCollectionType(EdmType type)
    {
      return (BuiltInTypeKind.CollectionType == type.BuiltInTypeKind);
    }

    /// <summary>
    /// Is the given type usage over a primitive type
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    internal static bool IsPrimitiveType(TypeUsage type)
    {
      return MetadataHelpers.IsPrimitiveType(type.EdmType);
    }

    /// <summary>
    /// Is the given type a primitive type
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    internal static bool IsPrimitiveType(EdmType type)
    {
      return (BuiltInTypeKind.PrimitiveType == type.BuiltInTypeKind);
    }

    /// <summary>
    /// Is the given type usage over a row type
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    internal static bool IsRowType(TypeUsage type)
    {
      return MetadataHelpers.IsRowType(type.EdmType);
    }

    /// <summary>
    /// Is the given type a row type
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    internal static bool IsRowType(EdmType type)
    {
      return (BuiltInTypeKind.RowType == type.BuiltInTypeKind);
    }

    /// <summary>
    /// Gets the type of the given type usage if it is a primitive type
    /// </summary>
    /// <param name="type"></param>
    /// <param name="typeKind"></param>
    /// <returns></returns>
    internal static bool TryGetPrimitiveTypeKind(TypeUsage type, out PrimitiveTypeKind typeKind)
    {
      if (type != null && type.EdmType != null && type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
      {
        typeKind = ((PrimitiveType)type.EdmType).PrimitiveTypeKind;
        return true;
      }

      typeKind = default(PrimitiveTypeKind);
      return false;
    }

    internal static PrimitiveTypeKind GetPrimitiveTypeKind(TypeUsage type)
    {
      PrimitiveTypeKind returnValue;
      if (!MetadataHelpers.TryGetPrimitiveTypeKind(type, out returnValue))
      {
        Debug.Assert(false, "Cannot create parameter of non-primitive type");
        throw new NotSupportedException("Cannot create parameter of non-primitive type");
      }
      return returnValue;
    }

    /// <summary>
    /// Gets the value for the metadata property with the given name
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="item"></param>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    internal static T TryGetValueForMetadataProperty<T>(MetadataItem item, string propertyName)
    {
      MetadataProperty property;
      if (!item.MetadataProperties.TryGetValue(propertyName, true, out property))
      {
        return default(T);
      }

      return (T)property.Value;
    }

    internal static bool IsPrimitiveType(TypeUsage type, PrimitiveTypeKind primitiveType)
    {
      PrimitiveTypeKind typeKind;
      if (TryGetPrimitiveTypeKind(type, out typeKind))
      {
        return (typeKind == primitiveType);
      }
      return false;
    }

    internal static DbType GetDbType(PrimitiveTypeKind primitiveType)
    {
      switch (primitiveType)
      {
        case PrimitiveTypeKind.Binary: return DbType.Binary;
        case PrimitiveTypeKind.Boolean: return DbType.Boolean;
        case PrimitiveTypeKind.Byte: return DbType.Byte;
        case PrimitiveTypeKind.DateTime: return DbType.DateTime;
        case PrimitiveTypeKind.Decimal: return DbType.Decimal;
        case PrimitiveTypeKind.Double: return DbType.Double;
        case PrimitiveTypeKind.Single: return DbType.Single;
        case PrimitiveTypeKind.Guid: return DbType.Guid;
        case PrimitiveTypeKind.Int16: return DbType.Int16;
        case PrimitiveTypeKind.Int32: return DbType.Int32;
        case PrimitiveTypeKind.Int64: return DbType.Int64;
        //case PrimitiveTypeKind.Money: return DbType.Decimal;
        case PrimitiveTypeKind.SByte: return DbType.SByte;
        case PrimitiveTypeKind.String: return DbType.String;
        //case PrimitiveTypeKind.UInt16: return DbType.UInt16;
        //case PrimitiveTypeKind.UInt32: return DbType.UInt32;
        //case PrimitiveTypeKind.UInt64: return DbType.UInt64;
        //case PrimitiveTypeKind.Xml: return DbType.Xml;
        default:
          Debug.Fail("unknown PrimitiveTypeKind" + primitiveType.ToString());
          throw new InvalidOperationException(string.Format("Unknown PrimitiveTypeKind {0}", primitiveType));
      }
    }

    #endregion

    #region Facet Support
    internal static readonly int UnicodeStringMaxMaxLength = Int32.MaxValue;
    internal static readonly int AsciiStringMaxMaxLength = Int32.MaxValue;
    internal static readonly int BinaryMaxMaxLength = Int32.MaxValue;

    #region Facet Names
    /// <summary>
    /// Name of the MaxLength Facet
    /// </summary>
    public static readonly string MaxLengthFacetName = "MaxLength";

    /// <summary>
    /// Name of the Unicode Facet
    /// </summary>
    public static readonly string UnicodeFacetName = "Unicode";

    /// <summary>
    /// Name of the FixedLength Facet
    /// </summary>
    public static readonly string FixedLengthFacetName = "FixedLength";

    /// <summary>
    /// Name of the PreserveSeconds Facet
    /// </summary>
    public static readonly string PreserveSecondsFacetName = "PreserveSeconds";

    /// <summary>
    /// Name of the Precision Facet
    /// </summary>
    public static readonly string PrecisionFacetName = "Precision";

    /// <summary>
    /// Name of the Scale Facet
    /// </summary>
    public static readonly string ScaleFacetName = "Scale";

    /// <summary>
    /// Name of the DefaultValue Facet
    /// </summary>
    public static readonly string DefaultValueFacetName = "DefaultValue";

    /// <summary>
    /// Name of the Nullable Facet
    /// </summary>
    internal const string NullableFacetName = "Nullable";
    #endregion

    #region Facet Retreival Helpers

    /// <summary>
    /// Get the value specified on the given type usage for the given facet name.
    /// If the faces does not have a value specifid or that value is null returns
    /// the default value for that facet.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="type"></param>
    /// <param name="facetName"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    internal static T GetFacetValueOrDefault<T>(TypeUsage type, string facetName, T defaultValue)
    {
      //Get the value for the facet, if any
      Facet facet;
      if (type.Facets.TryGetValue(facetName, false, out facet) && facet.Value != null && !facet.IsUnbounded)
      {
        return (T)facet.Value;
      }
      else
      {
        return defaultValue;
      }
    }

    internal static bool IsFacetValueConstant(TypeUsage type, string facetName)
    {
      return MetadataHelpers.GetFacet(((PrimitiveType)type.EdmType).FacetDescriptions, facetName).IsConstant;
    }

    private static FacetDescription GetFacet(IEnumerable<FacetDescription> facetCollection, string facetName)
    {
      foreach (FacetDescription facetDescription in facetCollection)
      {
        if (facetDescription.FacetName == facetName)
        {
          return facetDescription;
        }
      }

      return null;
    }

    /// <summary>
    /// Given a facet name and an EdmType, tries to get that facet's description.
    /// </summary>
    /// <param name="edmType"></param>
    /// <param name="facetName"></param>
    /// <param name="facetDescription"></param>
    /// <returns></returns>
    internal static bool TryGetTypeFacetDescriptionByName(EdmType edmType, string facetName, out FacetDescription facetDescription)
    {
      facetDescription = null;
      if (MetadataHelpers.IsPrimitiveType(edmType))
      {
        PrimitiveType primitiveType = (PrimitiveType)edmType;
        foreach (FacetDescription fd in primitiveType.FacetDescriptions)
        {
          if (facetName.Equals(fd.FacetName, StringComparison.OrdinalIgnoreCase))
          {
            facetDescription = fd;
            return true;
          }
        }
      }
      return false;
    }

    internal static bool IsNullable(TypeUsage type)
    {
      Facet nullableFacet;
      if (type.Facets.TryGetValue(NullableFacetName, false, out nullableFacet))
      {
        return (bool)nullableFacet.Value;
      }
      return false;
    }

    internal static bool TryGetMaxLength(TypeUsage type, out int maxLength)
    {
      if (!IsPrimitiveType(type, PrimitiveTypeKind.String) &&
          !IsPrimitiveType(type, PrimitiveTypeKind.Binary))
      {
        maxLength = 0;
        return false;
      }

      // Binary and String FixedLength facets share the same name
      return TryGetIntFacetValue(type, MaxLengthFacetName, out maxLength);
    }

    internal static bool TryGetIntFacetValue(TypeUsage type, string facetName, out int intValue)
    {
      intValue = 0;
      Facet intFacet;

      if (type.Facets.TryGetValue(facetName, false, out intFacet) && intFacet.Value != null && !intFacet.IsUnbounded)
      {
        intValue = (int)intFacet.Value;
        return true;
      }

      return false;
    }

    internal static bool TryGetIsFixedLength(TypeUsage type, out bool isFixedLength)
    {
      if (!IsPrimitiveType(type, PrimitiveTypeKind.String) &&
          !IsPrimitiveType(type, PrimitiveTypeKind.Binary))
      {
        isFixedLength = false;
        return false;
      }

      // Binary and String MaxLength facets share the same name
      return TryGetBooleanFacetValue(type, FixedLengthFacetName, out isFixedLength);
    }

    internal static bool TryGetBooleanFacetValue(TypeUsage type, string facetName, out bool boolValue)
    {
      boolValue = false;
      Facet boolFacet;
      if (type.Facets.TryGetValue(facetName, false, out boolFacet) && boolFacet.Value != null)
      {
        boolValue = (bool)boolFacet.Value;
        return true;
      }

      return false;
    }

    internal static bool TryGetIsUnicode(TypeUsage type, out bool isUnicode)
    {
      if (!IsPrimitiveType(type, PrimitiveTypeKind.String))
      {
        isUnicode = false;
        return false;
      }

      return TryGetBooleanFacetValue(type, UnicodeFacetName, out isUnicode);
    }

    #endregion

    #endregion

    internal static bool IsCanonicalFunction(EdmFunction function)
    {
      return (function.NamespaceName == "Edm");
    }

    internal static bool IsStoreFunction(EdmFunction function)
    {
      return !IsCanonicalFunction(function);
    }

    // Returns ParameterDirection corresponding to given ParameterMode
    internal static ParameterDirection ParameterModeToParameterDirection(ParameterMode mode)
    {
      switch (mode)
      {
        case ParameterMode.In:
          return ParameterDirection.Input;

        case ParameterMode.InOut:
          return ParameterDirection.InputOutput;

        case ParameterMode.Out:
          return ParameterDirection.Output;

        case ParameterMode.ReturnValue:
          return ParameterDirection.ReturnValue;

        default:
          Debug.Fail("unrecognized mode " + mode.ToString());
          return default(ParameterDirection);
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/SkipClause.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
//---------------------------------------------------------------------
// <copyright file="SkipClause.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

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

    /// <summary>
    /// SkipClause represents the a SKIP expression in a SqlSelectStatement.
    /// It has a count property, which indicates how many rows should be skipped.
    /// </summary>
    class SkipClause : ISqlFragment
    {
        ISqlFragment skipCount;

        /// <summary>
        /// How many rows should be skipped.
        /// </summary>
        internal ISqlFragment SkipCount
        {
            get { return skipCount; }
        }

        /// <summary>
        /// Creates a SkipClause with the given skipCount.
        /// </summary>
        /// <param name="skipCount"></param>
        internal SkipClause(ISqlFragment skipCount)
        {
            this.skipCount = skipCount;
        }

        /// <summary>
        /// Creates a SkipClause with the given skipCount.
        /// </summary>
        /// <param name="skipCount"></param>
        internal SkipClause(int skipCount)
        {
            SqlBuilder sqlBuilder = new SqlBuilder();
            sqlBuilder.Append(skipCount.ToString(CultureInfo.InvariantCulture));
            this.skipCount = sqlBuilder;
        }

        #region ISqlFragment Members
        /// <summary>
        /// Write out the SKIP part of sql select statement 
        /// It basically writes OFFSET (X).
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="sqlGenerator"></param>
        public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator)
        {
            writer.Write(" OFFSET ");
            this.SkipCount.WriteSql(writer, sqlGenerator);
        }
        #endregion
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































Deleted System.Data.SQLite.Linq/SQL Generation/SqlBuilder.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
//---------------------------------------------------------------------
// <copyright file="SqlBuilder.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Data.Common.CommandTrees;

  /// <summary>
  /// This class is like StringBuilder.  While traversing the tree for the first time, 
  /// we do not know all the strings that need to be appended e.g. things that need to be
  /// renamed, nested select statements etc.  So, we use a builder that can collect
  /// all kinds of sql fragments.
  /// </summary>
  internal sealed class SqlBuilder : ISqlFragment
  {
    private List<object> _sqlFragments;
    private List<object> sqlFragments
    {
      get
      {
        if (null == _sqlFragments)
        {
          _sqlFragments = new List<object>();
        }
        return _sqlFragments;
      }
    }


    /// <summary>
    /// Add an object to the list - we do not verify that it is a proper sql fragment
    /// since this is an internal method.
    /// </summary>
    /// <param name="s"></param>
    public void Append(object s)
    {
      Debug.Assert(s != null);
      sqlFragments.Add(s);
    }

    /// <summary>
    /// This is to pretty print the SQL.  The writer <see cref="SqlWriter.Write"/>
    /// needs to know about new lines so that it can add the right amount of 
    /// indentation at the beginning of lines.
    /// </summary>
    public void AppendLine()
    {
      sqlFragments.Add("\r\n");
    }

    /// <summary>
    /// Whether the builder is empty.  This is used by the <see cref="SqlGenerator.Visit(DbProjectExpression)"/>
    /// to determine whether a sql statement can be reused.
    /// </summary>
    public bool IsEmpty
    {
      get { return ((null == _sqlFragments) || (0 == _sqlFragments.Count)); }
    }

    #region ISqlFragment Members

    /// <summary>
    /// We delegate the writing of the fragment to the appropriate type.
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="sqlGenerator"></param>
    public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator)
    {
      if (null != _sqlFragments)
      {
        foreach (object o in _sqlFragments)
        {
          string str = (o as String);
          if (null != str)
          {
            writer.Write(str);
          }
          else
          {
            ISqlFragment sqlFragment = (o as ISqlFragment);
            if (null != sqlFragment)
            {
              sqlFragment.WriteSql(writer, sqlGenerator);
            }
            else
            {
              throw new InvalidOperationException();
            }
          }
        }
      }
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/SqlChecker.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Data.Common.CommandTrees;

    internal class SqlChecker : DbExpressionVisitor<bool>
  {
#if false
    private static Type sql8rewriter;

    static SqlChecker()
    {
        string version =
#if NET_20
            "3.5.0.0";
#else
            "4.0.0.0";
#endif

        sql8rewriter = Type.GetType(String.Format("System.Data.SqlClient.SqlGen.Sql8ExpressionRewriter, System.Data.Entity, Version={0}, Culture=neutral, PublicKeyToken=b77a5c561934e089", version), false);
    }
#endif

    private SqlChecker()
    {
    }

#if false
    /// <summary>
    /// SQLite doesn't support things like SKIP and a few other things.  
    /// So determine if the query has to be rewritten
    /// </summary>
    /// <remarks>
    /// Microsoft went to all the trouble of making things like SKIP work 
    /// on Sql Server 2000 by doing a rewrite of the commandtree.
    /// However, all that fancy stuff is hidden from us.  Thanks to 
    /// reflection however, we can go ahead and use the Sql 2000 rewriter code
    /// they made.
    /// </remarks>
    /// <param name="tree">The tree to inspect for a rewrite</param>
    /// <returns>Returns a new query tree if it needs rewriting</returns>
    internal static DbQueryCommandTree Rewrite(DbQueryCommandTree tree)
    {
      SqlChecker visitor = new SqlChecker();
      if (tree.Query.Accept<bool>(visitor))
      {
        tree = sql8rewriter.InvokeMember("Rewrite", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static, null, null, new object[] { tree }) as DbQueryCommandTree;
      }      
      return tree;
    }
#endif

    public override bool Visit(DbAndExpression expression)
    {
      return VisitBinaryExpression(expression);
    }

    public override bool Visit(DbApplyExpression expression)
    {
      throw new NotSupportedException("apply expression");
    }

    public override bool Visit(DbArithmeticExpression expression)
    {
      return VisitExpressionList(expression.Arguments);
    }

    public override bool Visit(DbCaseExpression expression)
    {
      bool flag1 = VisitExpressionList(expression.When);
      bool flag2 = VisitExpressionList(expression.Then);
      bool flag3 = VisitExpression(expression.Else);

      return (flag1 || flag2 || flag3);
    }

    public override bool Visit(DbCastExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbComparisonExpression expression)
    {
      return VisitBinaryExpression(expression);
    }

    public override bool Visit(DbConstantExpression expression)
    {
      return false;
    }

    public override bool Visit(DbCrossJoinExpression expression)
    {
      return VisitExpressionBindingList(expression.Inputs);
    }

    public override bool Visit(DbDerefExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbDistinctExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbElementExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbEntityRefExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbExceptExpression expression)
    {
      bool flag1 = VisitExpression(expression.Left);
      bool flag2 = VisitExpression(expression.Right);
      return (flag1 || flag2);
    }

    public override bool Visit(DbExpression expression)
    {
      throw new NotSupportedException(expression.GetType().FullName);
    }

    public override bool Visit(DbFilterExpression expression)
    {
      bool flag1 = VisitExpressionBinding(expression.Input);
      bool flag2 = VisitExpression(expression.Predicate);

      return (flag1 || flag2);
    }

    public override bool Visit(DbFunctionExpression expression)
    {
      return VisitExpressionList(expression.Arguments);
    }

    public override bool Visit(DbGroupByExpression expression)
    {
      bool flag1 = VisitExpression(expression.Input.Expression);
      bool flag2 = VisitExpressionList(expression.Keys);
      bool flag3 = VisitAggregateList(expression.Aggregates);

      return (flag1 || flag2 || flag3);
    }

    public override bool Visit(DbIntersectExpression expression)
    {
      bool flag1 = VisitExpression(expression.Left);
      bool flag2 = VisitExpression(expression.Right);
      return (flag1 || flag2);
    }

    public override bool Visit(DbIsEmptyExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbIsNullExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbIsOfExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbJoinExpression expression)
    {
      bool flag1 = VisitExpressionBinding(expression.Left);
      bool flag2 = VisitExpressionBinding(expression.Right);
      bool flag3 = VisitExpression(expression.JoinCondition);
      return (flag1 || flag2 || flag3);
    }

    public override bool Visit(DbLikeExpression expression)
    {
      bool flag1 = VisitExpression(expression.Argument);
      bool flag2 = VisitExpression(expression.Pattern);
      bool flag3 = VisitExpression(expression.Escape);
      return (flag1 || flag2 || flag3);
    }

    public override bool Visit(DbLimitExpression expression)
    {
      return VisitExpression(expression.Argument);
    }

    public override bool Visit(DbNewInstanceExpression expression)
    {
      return VisitExpressionList(expression.Arguments);
    }

    public override bool Visit(DbNotExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbNullExpression expression)
    {
      return false;
    }

    public override bool Visit(DbOfTypeExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbOrExpression expression)
    {
      return VisitBinaryExpression(expression);
    }

    public override bool Visit(DbParameterReferenceExpression expression)
    {
      return false;
    }

    public override bool Visit(DbProjectExpression expression)
    {
      bool flag1 = VisitExpressionBinding(expression.Input);
      bool flag2 = VisitExpression(expression.Projection);
      return (flag1 || flag2);
    }

    public override bool Visit(DbPropertyExpression expression)
    {
      return VisitExpression(expression.Instance);
    }

    public override bool Visit(DbQuantifierExpression expression)
    {
      bool flag1 = VisitExpressionBinding(expression.Input);
      bool flag2 = VisitExpression(expression.Predicate);
      return (flag1 || flag2);
    }

    public override bool Visit(DbRefExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbRefKeyExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbRelationshipNavigationExpression expression)
    {
      return VisitExpression(expression.NavigationSource);
    }

    public override bool Visit(DbScanExpression expression)
    {
      return false;
    }

    public override bool Visit(DbSkipExpression expression)
    {
      VisitExpressionBinding(expression.Input);
      VisitSortClauseList(expression.SortOrder);
      VisitExpression(expression.Count);
      return true;
    }

    public override bool Visit(DbSortExpression expression)
    {
      bool flag1 = VisitExpressionBinding(expression.Input);
      bool flag2 = VisitSortClauseList(expression.SortOrder);
      return (flag1 || flag2);
    }

    public override bool Visit(DbTreatExpression expression)
    {
      return VisitUnaryExpression(expression);
    }

    public override bool Visit(DbUnionAllExpression expression)
    {
      return VisitBinaryExpression(expression);
    }

    public override bool Visit(DbVariableReferenceExpression expression)
    {
      return false;
    }

    private bool VisitAggregate(DbAggregate aggregate)
    {
      return VisitExpressionList(aggregate.Arguments);
    }

    private bool VisitAggregateList(IList<DbAggregate> list)
    {
      return VisitList<DbAggregate>(new ListElementHandler<DbAggregate>(VisitAggregate), list);
    }

    private bool VisitBinaryExpression(DbBinaryExpression expr)
    {
      bool flag1 = VisitExpression(expr.Left);
      bool flag2 = VisitExpression(expr.Right);
      return (flag1 || flag2);
    }

    private bool VisitExpression(DbExpression expression)
    {
      if (expression == null)
      {
        return false;
      }
      return expression.Accept<bool>(this);
    }

    private bool VisitExpressionBinding(DbExpressionBinding expressionBinding)
    {
      return VisitExpression(expressionBinding.Expression);
    }

    private bool VisitExpressionBindingList(IList<DbExpressionBinding> list)
    {
      return VisitList<DbExpressionBinding>(new ListElementHandler<DbExpressionBinding>(VisitExpressionBinding), list);
    }

    private bool VisitExpressionList(IList<DbExpression> list)
    {
      return VisitList<DbExpression>(new ListElementHandler<DbExpression>(VisitExpression), list);
    }

    private static bool VisitList<TElementType>(ListElementHandler<TElementType> handler, IList<TElementType> list)
    {
      bool flag = false;
      foreach (TElementType local in list)
      {
        bool flag2 = handler(local);
        flag = flag || flag2;
      }
      return flag;
    }

    private bool VisitSortClause(DbSortClause sortClause)
    {
      return VisitExpression(sortClause.Expression);
    }

    private bool VisitSortClauseList(IList<DbSortClause> list)
    {
      return VisitList<DbSortClause>(new ListElementHandler<DbSortClause>(VisitSortClause), list);
    }

    private bool VisitUnaryExpression(DbUnaryExpression expr)
    {
      return VisitExpression(expr.Argument);
    }

    private delegate bool ListElementHandler<TElementType>(TElementType element);
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/SqlGenerator.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
//---------------------------------------------------------------------
// <copyright file="SqlGenerator.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System;
  using System.Linq;
  using System.Diagnostics;
  using System.Globalization;
  using System.Text;
  using System.Data.Common;
  using System.Data.Metadata.Edm;
  using System.Data.Common.CommandTrees;
  using System.Data;
  using System.Collections.ObjectModel;
  using System.Collections.Generic;

  /// <summary>
  /// Translates the command object into a SQL string that can be executed on
  /// SQLite.
  /// </summary>
  /// <remarks>
  /// The translation is implemented as a visitor <see cref="DbExpressionVisitor{T}"/>
  /// over the query tree.  It makes a single pass over the tree, collecting the sql
  /// fragments for the various nodes in the tree <see cref="ISqlFragment"/>.
  ///
  /// The major operations are
  /// <list type="bullet">
  /// <item>Select statement minimization.  Multiple nodes in the query tree
  /// that can be part of a single SQL select statement are merged. e.g. a
  /// Filter node that is the input of a Project node can typically share the
  /// same SQL statement.</item>
  /// <item>Alpha-renaming.  As a result of the statement minimization above, there
  /// could be name collisions when using correlated subqueries
  /// <example>
  /// <code>
  /// Filter(
  ///     b = Project( c.x
  ///         c = Extent(foo)
  ///         )
  ///     exists (
  ///         Filter(
  ///             c = Extent(foo)
  ///             b.x = c.x
  ///             )
  ///     )
  /// )
  /// </code>
  /// The first Filter, Project and Extent will share the same SQL select statement.
  /// The alias for the Project i.e. b, will be replaced with c.
  /// If the alias c for the Filter within the exists clause is not renamed,
  /// we will get <c>c.x = c.x</c>, which is incorrect.
  /// Instead, the alias c within the second filter should be renamed to c1, to give
  /// <c>c.x = c1.x</c> i.e. b is renamed to c, and c is renamed to c1.
  /// </example>
  /// </item>
  /// <item>Join flattening.  In the query tree, a list of join nodes is typically
  /// represented as a tree of Join nodes, each with 2 children. e.g.
  /// <example>
  /// <code>
  /// a = Join(InnerJoin
  ///     b = Join(CrossJoin
  ///         c = Extent(foo)
  ///         d = Extent(foo)
  ///         )
  ///     e = Extent(foo)
  ///     on b.c.x = e.x
  ///     )
  /// </code>
  /// If translated directly, this will be translated to
  /// <code>
  /// FROM ( SELECT c.*, d.*
  ///         FROM foo as c
  ///         CROSS JOIN foo as d) as b
  /// INNER JOIN foo as e on b.x' = e.x
  /// </code>
  /// It would be better to translate this as
  /// <code>
  /// FROM foo as c
  /// CROSS JOIN foo as d
  /// INNER JOIN foo as e on c.x = e.x
  /// </code>
  /// This allows the optimizer to choose an appropriate join ordering for evaluation.
  /// </example>
  /// </item>
  /// <item>Select * and column renaming.  In the example above, we noticed that
  /// in some cases we add <c>SELECT * FROM ...</c> to complete the SQL
  /// statement. i.e. there is no explicit PROJECT list.
  /// In this case, we enumerate all the columns available in the FROM clause
  /// This is particularly problematic in the case of Join trees, since the columns
  /// from the extents joined might have the same name - this is illegal.  To solve
  /// this problem, we will have to rename columns if they are part of a SELECT *
  /// for a JOIN node - we do not need renaming in any other situation.
  /// <see cref="SqlGenerator.AddDefaultColumns"/>.
  /// </item>
  /// </list>
  ///
  /// <para>
  /// Renaming issues.
  /// When rows or columns are renamed, we produce names that are unique globally
  /// with respect to the query.  The names are derived from the original names,
  /// with an integer as a suffix. e.g. CustomerId will be renamed to CustomerId1,
  /// CustomerId2 etc.
  ///
  /// Since the names generated are globally unique, they will not conflict when the
  /// columns of a JOIN SELECT statement are joined with another JOIN. 
  ///
  /// </para>
  ///
  /// <para>
  /// Record flattening.
  /// SQL server does not have the concept of records.  However, a join statement
  /// produces records.  We have to flatten the record accesses into a simple
  /// <c>alias.column</c> form.  <see cref="SqlGenerator.Visit(DbPropertyExpression)"/>
  /// </para>
  ///
  /// <para>
  /// Building the SQL.
  /// There are 2 phases
  /// <list type="numbered">
  /// <item>Traverse the tree, producing a sql builder <see cref="SqlBuilder"/></item>
  /// <item>Write the SqlBuilder into a string, renaming the aliases and columns
  /// as needed.</item>
  /// </list>
  ///
  /// In the first phase, we traverse the tree.  We cannot generate the SQL string
  /// right away, since
  /// <list type="bullet">
  /// <item>The WHERE clause has to be visited before the from clause.</item>
  /// <item>extent aliases and column aliases need to be renamed.  To minimize
  /// renaming collisions, all the names used must be known, before any renaming
  /// choice is made.</item>
  /// </list>
  /// To defer the renaming choices, we use symbols <see cref="Symbol"/>.  These
  /// are renamed in the second phase.
  ///
  /// Since visitor methods cannot transfer information to child nodes through
  /// parameters, we use some global stacks,
  /// <list type="bullet">
  /// <item>A stack for the current SQL select statement.  This is needed by
  /// <see cref="SqlGenerator.Visit(DbVariableReferenceExpression)"/> to create a
  /// list of free variables used by a select statement.  This is needed for
  /// alias renaming.
  /// </item>
  /// <item>A stack for the join context.  When visiting a <see cref="DbScanExpression"/>,
  /// we need to know whether we are inside a join or not.  If we are inside
  /// a join, we do not create a new SELECT statement.</item>
  /// </list>
  /// </para>
  ///
  /// <para>
  /// Global state.
  /// To enable renaming, we maintain
  /// <list type="bullet">
  /// <item>The set of all extent aliases used.</item>
  /// <item>The set of all column aliases used.</item>
  /// </list>
  ///
  /// Finally, we have a symbol table to lookup variable references.  All references
  /// to the same extent have the same symbol.
  /// </para>
  ///
  /// <para>
  /// Sql select statement sharing.
  ///
  /// Each of the relational operator nodes
  /// <list type="bullet">
  /// <item>Project</item>
  /// <item>Filter</item>
  /// <item>GroupBy</item>
  /// <item>Sort/OrderBy</item>
  /// </list>
  /// can add its non-input (e.g. project, predicate, sort order etc.) to
  /// the SQL statement for the input, or create a new SQL statement.
  /// If it chooses to reuse the input's SQL statement, we play the following
  /// symbol table trick to accomplish renaming.  The symbol table entry for
  /// the alias of the current node points to the symbol for the input in
  /// the input's SQL statement.
  /// <example>
  /// <code>
  /// Project(b.x
  ///     b = Filter(
  ///         c = Extent(foo)
  ///         c.x = 5)
  ///     )
  /// </code>
  /// The Extent node creates a new SqlSelectStatement.  This is added to the
  /// symbol table by the Filter as {c, Symbol(c)}.  Thus, <c>c.x</c> is resolved to
  /// <c>Symbol(c).x</c>.
  /// Looking at the project node, we add {b, Symbol(c)} to the symbol table if the
  /// SQL statement is reused, and {b, Symbol(b)}, if there is no reuse.
  ///
  /// Thus, <c>b.x</c> is resolved to <c>Symbol(c).x</c> if there is reuse, and to
  /// <c>Symbol(b).x</c> if there is no reuse.
  /// </example>
  /// </para>
  /// </remarks>
  internal sealed class SqlGenerator : DbExpressionVisitor<ISqlFragment>
  {
    private SQLiteProviderManifest _manifest;

    #region Visitor parameter stacks
    /// <summary>
    /// Every relational node has to pass its SELECT statement to its children
    /// This allows them (DbVariableReferenceExpression eventually) to update the list of
    /// outer extents (free variables) used by this select statement.
    /// </summary>
    Stack<SqlSelectStatement> selectStatementStack;

    /// <summary>
    /// The top of the stack
    /// </summary>
    private SqlSelectStatement CurrentSelectStatement
    {
      // There is always something on the stack, so we can always Peek.
      get { return selectStatementStack.Peek(); }
    }

    /// <summary>
    /// Nested joins and extents need to know whether they should create
    /// a new Select statement, or reuse the parent's.  This flag
    /// indicates whether the parent is a join or not.
    /// </summary>
    Stack<bool> isParentAJoinStack;

    /// <summary>
    /// The top of the stack
    /// </summary>
    private bool IsParentAJoin
    {
      // There might be no entry on the stack if a Join node has never
      // been seen, so we return false in that case.
      get { return isParentAJoinStack.Count == 0 ? false : isParentAJoinStack.Peek(); }
    }

    #endregion

    #region Global lists and state
    Dictionary<string, int> allExtentNames;
    internal Dictionary<string, int> AllExtentNames
    {
      get { return allExtentNames; }
    }

    // For each column name, we store the last integer suffix that
    // was added to produce a unique column name.  This speeds up
    // the creation of the next unique name for this column name.
    Dictionary<string, int> allColumnNames;
    internal Dictionary<string, int> AllColumnNames
    {
      get { return allColumnNames; }
    }

    SymbolTable symbolTable = new SymbolTable();

    /// <summary>
    /// VariableReferenceExpressions are allowed only as children of DbPropertyExpression
    /// or MethodExpression.  The cheapest way to ensure this is to set the following
    /// property in DbVariableReferenceExpression and reset it in the allowed parent expressions.
    /// </summary>
    bool isVarRefSingle = false;

    #endregion

    private bool HasBuiltMapForIn(DbExpression e, KeyToListMap<DbExpression, DbExpression> values)
    {
      DbExpressionKind expressionKind = e.ExpressionKind;
      if (expressionKind != DbExpressionKind.Equals)
      {
        if (expressionKind != DbExpressionKind.IsNull)
        {
          if (expressionKind != DbExpressionKind.Or)
          {
            return false;
          }
          DbBinaryExpression expression2 = e as DbBinaryExpression;
          return (this.HasBuiltMapForIn(expression2.Left, values) && this.HasBuiltMapForIn(expression2.Right, values));
        }
      }
      else
      {
        return this.TryAddExpressionForIn((DbBinaryExpression)e, values);
      }
      DbExpression argument = ((DbIsNullExpression)e).Argument;
      if (this.IsKeyForIn(argument))
      {
        values.Add(argument, e);
        return true;
      }
      return false;
    }

    #region Statics
    static private readonly Dictionary<string, FunctionHandler> _builtInFunctionHandlers = InitializeBuiltInFunctionHandlers();
    static private readonly Dictionary<string, FunctionHandler> _canonicalFunctionHandlers = InitializeCanonicalFunctionHandlers();
    static private readonly Dictionary<string, string> _functionNameToOperatorDictionary = InitializeFunctionNameToOperatorDictionary();
    static private readonly Dictionary<string, string> _datepartKeywords = InitializeDatepartKeywords();
    static private readonly char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    private delegate ISqlFragment FunctionHandler(SqlGenerator sqlgen, DbFunctionExpression functionExpr);

    /// <summary>
    /// All special built-in functions and their handlers
    /// </summary>
    /// <returns></returns>
    private static Dictionary<string, FunctionHandler> InitializeBuiltInFunctionHandlers()
    {
      Dictionary<string, FunctionHandler> functionHandlers = new Dictionary<string, FunctionHandler>(7, StringComparer.Ordinal);
      functionHandlers.Add("CONCAT", HandleConcatFunction);
      functionHandlers.Add("DATEPART", HandleDatepartDateFunction);
      functionHandlers.Add("DatePart", HandleDatepartDateFunction);
      functionHandlers.Add("GETDATE", HandleGetDateFunction);
      functionHandlers.Add("GETUTCDATE", HandleGetUtcDateFunction);
      return functionHandlers;
    }

    /// <summary>
    /// All special non-aggregate canonical functions and their handlers
    /// </summary>
    /// <returns></returns>
    private static Dictionary<string, FunctionHandler> InitializeCanonicalFunctionHandlers()
    {
      Dictionary<string, FunctionHandler> functionHandlers = new Dictionary<string, FunctionHandler>(16, StringComparer.Ordinal);
      functionHandlers.Add("IndexOf", HandleCanonicalFunctionIndexOf);
      functionHandlers.Add("Length", HandleCanonicalFunctionLength);
      functionHandlers.Add("NewGuid", HandleCanonicalFunctionNewGuid);
      functionHandlers.Add("Round", HandleCanonicalFunctionRound);
      functionHandlers.Add("ToLower", HandleCanonicalFunctionToLower);
      functionHandlers.Add("ToUpper", HandleCanonicalFunctionToUpper);
      functionHandlers.Add("Trim", HandleCanonicalFunctionTrim);
      functionHandlers.Add("Right", HandleCanonicalFunctionRight);
      functionHandlers.Add("CurrentDateTime", HandleGetDateFunction);
      functionHandlers.Add("CurrentUtcDateTime", HandleGetUtcDateFunction);

      //DatePartFunctions
      functionHandlers.Add("Year", HandleCanonicalFunctionDatepart);
      functionHandlers.Add("Month", HandleCanonicalFunctionDatepart);
      functionHandlers.Add("Day", HandleCanonicalFunctionDatepart);
      functionHandlers.Add("Hour", HandleCanonicalFunctionDatepart);
      functionHandlers.Add("Minute", HandleCanonicalFunctionDatepart);
      functionHandlers.Add("Second", HandleCanonicalFunctionDatepart);
      functionHandlers.Add("DateAdd", HandleCanonicalFunctionDateAdd);
      functionHandlers.Add("DateDiff", HandleCanonicalFunctionDateSubtract);
      functionHandlers.Add("DATEADD", HandleCanonicalFunctionDateAdd); // store
      functionHandlers.Add("DATEDIFF", HandleCanonicalFunctionDateSubtract); // store

      //Functions that translate to operators
      functionHandlers.Add("Concat", HandleConcatFunction);
      functionHandlers.Add("BitwiseAnd", HandleCanonicalFunctionBitwise);
      functionHandlers.Add("BitwiseNot", HandleCanonicalFunctionBitwise);
      functionHandlers.Add("BitwiseOr", HandleCanonicalFunctionBitwise);
      functionHandlers.Add("BitwiseXor", HandleCanonicalFunctionBitwise);
      return functionHandlers;
    }

    /// <summary>
    /// Valid datepart values
    /// </summary>
    /// <returns></returns>
    private static Dictionary<string, string> InitializeDatepartKeywords()
    {
      #region Datepart Keywords
      //
      // valid datepart values
      //
      Dictionary<string, string> datepartKeywords = new Dictionary<string, string>(30, StringComparer.OrdinalIgnoreCase);
      datepartKeywords.Add("d", "%d");
      datepartKeywords.Add("day", "%d");
      datepartKeywords.Add("dayofyear", "%j");
      datepartKeywords.Add("dd", "%d");
      datepartKeywords.Add("dw", "%w");
      datepartKeywords.Add("dy", "%j");
      datepartKeywords.Add("hh", "%H");
      datepartKeywords.Add("hour", "%H");
      datepartKeywords.Add("m", "%m");
      datepartKeywords.Add("mi", "%M");
      datepartKeywords.Add("millisecond", "%f");
      datepartKeywords.Add("minute", "%M");
      datepartKeywords.Add("mm", "%m");
      datepartKeywords.Add("month", "%m");
      datepartKeywords.Add("ms", "%f");
      datepartKeywords.Add("n", "%M");
      datepartKeywords.Add("s", "%S");
      datepartKeywords.Add("second", "%S");
      datepartKeywords.Add("ss", "%S");
      datepartKeywords.Add("week", "%W");
      datepartKeywords.Add("weekday", "%w");
      datepartKeywords.Add("wk", "%W");
      datepartKeywords.Add("ww", "%W");
      datepartKeywords.Add("y", "%Y");
      datepartKeywords.Add("year", "%Y");
      datepartKeywords.Add("yy", "%Y");
      datepartKeywords.Add("yyyy", "%Y");
      return datepartKeywords;
      #endregion
    }

    /// <summary>
    /// Initializes the mapping from functions to T-SQL operators
    /// for all functions that translate to T-SQL operators
    /// </summary>
    /// <returns></returns>
    private static Dictionary<string, string> InitializeFunctionNameToOperatorDictionary()
    {
      Dictionary<string, string> functionNameToOperatorDictionary = new Dictionary<string, string>(5, StringComparer.Ordinal);
      functionNameToOperatorDictionary.Add("Concat", "||");    //canonical
      functionNameToOperatorDictionary.Add("CONCAT", "||");    //store
      functionNameToOperatorDictionary.Add("BitwiseAnd", "&");
      functionNameToOperatorDictionary.Add("BitwiseNot", "~");
      functionNameToOperatorDictionary.Add("BitwiseOr", "|");
      functionNameToOperatorDictionary.Add("BitwiseXor", "^");
      return functionNameToOperatorDictionary;
    }

    #endregion

    #region Constructor
    /// <summary>
    /// Basic constructor. 
    /// </summary>
    private SqlGenerator(SQLiteProviderManifest manifest)
    {
      _manifest = manifest;
    }
    #endregion

    #region Entry points
    /// <summary>
    /// General purpose static function that can be called from System.Data assembly
    /// </summary>
    /// <param name="manifest"></param>
    /// <param name="tree">command tree</param>
    /// <param name="parameters">Parameters to add to the command tree corresponding
    /// to constants in the command tree. Used only in ModificationCommandTrees.</param>
    /// <param name="commandType"></param>
    /// <returns>The string representing the SQL to be executed.</returns>
    internal static string GenerateSql(SQLiteProviderManifest manifest, DbCommandTree tree, out List<DbParameter> parameters, out CommandType commandType)
    {
      commandType = CommandType.Text;

      //Handle Query
      DbQueryCommandTree queryCommandTree = tree as DbQueryCommandTree;
      if (queryCommandTree != null)
      {
        SqlGenerator sqlGen = new SqlGenerator(manifest);
        parameters = null;
        
        string sql = sqlGen.GenerateSql((DbQueryCommandTree)tree);

        return sql;
      }

      //Handle Function
      DbFunctionCommandTree DbFunctionCommandTree = tree as DbFunctionCommandTree;
      if (DbFunctionCommandTree != null)
      {
        SqlGenerator sqlGen = new SqlGenerator(manifest);
        parameters = null;

        string sql = sqlGen.GenerateFunctionSql(DbFunctionCommandTree, out commandType);

        return sql;
      }

      //Handle Insert
      DbInsertCommandTree insertCommandTree = tree as DbInsertCommandTree;
      if (insertCommandTree != null)
      {
        return DmlSqlGenerator.GenerateInsertSql(insertCommandTree, out parameters);
      }

      //Handle Delete
      DbDeleteCommandTree deleteCommandTree = tree as DbDeleteCommandTree;
      if (deleteCommandTree != null)
      {
        return DmlSqlGenerator.GenerateDeleteSql(deleteCommandTree, out parameters);
      }

      //Handle Update
      DbUpdateCommandTree updateCommandTree = tree as DbUpdateCommandTree;
      if (updateCommandTree != null)
      {
        return DmlSqlGenerator.GenerateUpdateSql(updateCommandTree, out parameters);
      }

      throw new NotSupportedException("Unrecognized command tree type");
    }
    #endregion

    //StringBuilder _typeDefs = new StringBuilder();

    #region Driver Methods
    /// <summary>
    /// Translate a command tree to a SQL string.
    ///
    /// The input tree could be translated to either a SQL SELECT statement
    /// or a SELECT expression.  This choice is made based on the return type
    /// of the expression
    /// CollectionType => select statement
    /// non collection type => select expression
    /// </summary>
    /// <param name="tree"></param>
    /// <returns>The string representing the SQL to be executed.</returns>
    private string GenerateSql(DbQueryCommandTree tree)
    {
#if false
      tree = SqlChecker.Rewrite(tree);
#endif

      selectStatementStack = new Stack<SqlSelectStatement>();
      isParentAJoinStack = new Stack<bool>();

      allExtentNames = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
      allColumnNames = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

      // Literals will not be converted to parameters.

      ISqlFragment result;
      if (MetadataHelpers.IsCollectionType(tree.Query.ResultType))
      {
        SqlSelectStatement sqlStatement = VisitExpressionEnsureSqlStatement(tree.Query);
        Debug.Assert(sqlStatement != null, "The outer most sql statment is null");
        sqlStatement.IsTopMost = true;
        result = sqlStatement;

      }
      else
      {
        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.Append("SELECT ");
        sqlBuilder.Append(tree.Query.Accept(this));

        result = sqlBuilder;
      }

      if (isVarRefSingle)
      {
        throw new NotSupportedException();
        // A DbVariableReferenceExpression has to be a child of DbPropertyExpression or MethodExpression
      }

      // Check that the parameter stacks are not leaking.
      Debug.Assert(selectStatementStack.Count == 0);
      Debug.Assert(isParentAJoinStack.Count == 0);

      //if (_typeDefs.Length > 0)
      //{
      //  _typeDefs.Insert(0x0, "TYPES ");
      //  _typeDefs.Append(";\r\n");
      //  _typeDefs.Append(WriteSql(result));
      //  return _typeDefs.ToString();
      //}

      return WriteSql(result);
    }

    /// <summary>
    /// Translate a function command tree to a SQL string.
    /// </summary>
    private string GenerateFunctionSql(DbFunctionCommandTree tree, out CommandType commandType)
    {
      EdmFunction function = tree.EdmFunction;

      // We expect function to always have these properties
      string userCommandText = (string)function.MetadataProperties["CommandTextAttribute"].Value;
      //string userSchemaName = (string)function.MetadataProperties["Schema"].Value;
      string userFuncName = (string)function.MetadataProperties["StoreFunctionNameAttribute"].Value;

      if (String.IsNullOrEmpty(userCommandText))
      {
        // build a quoted description of the function
        commandType = CommandType.StoredProcedure;

        // if the schema name is not explicitly given, it is assumed to be the metadata namespace
        //string schemaName = String.IsNullOrEmpty(userSchemaName) ?
        //    function.NamespaceName : userSchemaName;

        // if the function store name is not explicitly given, it is assumed to be the metadata name
        string functionName = String.IsNullOrEmpty(userFuncName) ?
            function.Name : userFuncName;

        // quote elements of function text
        //string quotedSchemaName = QuoteIdentifier(schemaName);
        string quotedFunctionName = QuoteIdentifier(functionName);

        // separator
        //const string schemaSeparator = ".";

        // concatenate elements of function text
        string quotedFunctionText = /* quotedSchemaName + schemaSeparator + */ quotedFunctionName;

        return quotedFunctionText;
      }
      else
      {
        // if the user has specified the command text, pass it through verbatim and choose CommandType.Text
        commandType = CommandType.Text;
        return userCommandText;
      }
    }

    /// <summary>
    /// Convert the SQL fragments to a string.
    /// We have to setup the Stream for writing.
    /// </summary>
    /// <param name="sqlStatement"></param>
    /// <returns>A string representing the SQL to be executed.</returns>
    string WriteSql(ISqlFragment sqlStatement)
    {
      StringBuilder builder = new StringBuilder(1024);
      using (SqlWriter writer = new SqlWriter(builder))
      {
        sqlStatement.WriteSql(writer, this);
      }

      return builder.ToString();
    }
    #endregion

    private bool TryTranslateIntoIn(DbOrExpression e, out ISqlFragment sqlFragment)
    {
      KeyToListMap<DbExpression, DbExpression> values = new KeyToListMap<DbExpression, DbExpression>(KeyFieldExpressionComparer.Singleton);
      if (!(this.HasBuiltMapForIn(e, values) && (values.Keys.Count<DbExpression>() > 0)))
      {
        sqlFragment = null;
        return false;
      }
      SqlBuilder result = new SqlBuilder();
      bool flag2 = true;
      foreach (DbExpression expression in values.Keys)
      {
        ReadOnlyCollection<DbExpression> source = values.ListForKey(expression);
        if (!flag2)
        {
          result.Append(" OR ");
        }
        else
        {
          flag2 = false;
        }
        IEnumerable<DbExpression> enumerable = source.Where<DbExpression>(delegate(DbExpression v)
        {
          return v.ExpressionKind != DbExpressionKind.IsNull;
        });
        int num = enumerable.Count<DbExpression>();
        if (num == 1)
        {
          this.ParanthesizeExpressionIfNeeded(expression, result);
          result.Append(" = ");
          DbExpression expression2 = enumerable.First<DbExpression>();
          this.ParenthesizeExpressionWithoutRedundantConstantCasts(expression2, result);
        }
        if (num > 1)
        {
          this.ParanthesizeExpressionIfNeeded(expression, result);
          result.Append(" IN (");
          bool flag3 = true;
          foreach (DbExpression expression3 in enumerable)
          {
            if (!flag3)
            {
              result.Append(",");
            }
            else
            {
              flag3 = false;
            }
            this.ParenthesizeExpressionWithoutRedundantConstantCasts(expression3, result);
          }
          result.Append(")");
        }
        DbIsNullExpression expression4 = source.FirstOrDefault<DbExpression>(delegate(DbExpression v)
        {
          return (v.ExpressionKind == DbExpressionKind.IsNull);
        }) as DbIsNullExpression;
        if (expression4 != null)
        {
          if (num > 0)
          {
            result.Append(" OR ");
          }
          result.Append(this.VisitIsNullExpression(expression4, false));
        }
      }
      sqlFragment = result;
      return true;
    }

    #region DbExpressionVisitor Members

    /// <summary>
    /// Translate(left) AND Translate(right)
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/>.</returns>
    public override ISqlFragment Visit(DbAndExpression e)
    {
      return VisitBinaryExpression(" AND ", e.Left, e.Right);
    }

    /// <summary>
    /// An apply is just like a join, so it shares the common join processing
    /// in <see cref="VisitJoinExpression"/>
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlSelectStatement"/>.</returns>
    public override ISqlFragment Visit(DbApplyExpression e)
    {
      throw new NotSupportedException("APPLY joins are not supported");
    }

    /// <summary>
    /// For binary expressions, we delegate to <see cref="VisitBinaryExpression"/>.
    /// We handle the other expressions directly.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbArithmeticExpression e)
    {
      SqlBuilder result;

      switch (e.ExpressionKind)
      {
        case DbExpressionKind.Divide:
          result = VisitBinaryExpression(" / ", e.Arguments[0], e.Arguments[1]);
          break;
        case DbExpressionKind.Minus:
          result = VisitBinaryExpression(" - ", e.Arguments[0], e.Arguments[1]);
          break;
        case DbExpressionKind.Modulo:
          result = VisitBinaryExpression(" % ", e.Arguments[0], e.Arguments[1]);
          break;
        case DbExpressionKind.Multiply:
          result = VisitBinaryExpression(" * ", e.Arguments[0], e.Arguments[1]);
          break;
        case DbExpressionKind.Plus:
          result = VisitBinaryExpression(" + ", e.Arguments[0], e.Arguments[1]);
          break;

        case DbExpressionKind.UnaryMinus:
          result = new SqlBuilder();
          result.Append(" -(");
          result.Append(e.Arguments[0].Accept(this));
          result.Append(")");
          break;

        default:
          Debug.Assert(false);
          throw new InvalidOperationException();
      }

      return result;
    }

    /// <summary>
    /// If the ELSE clause is null, we do not write it out.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbCaseExpression e)
    {
      SqlBuilder result = new SqlBuilder();

      Debug.Assert(e.When.Count == e.Then.Count);

      result.Append("CASE");
      for (int i = 0; i < e.When.Count; ++i)
      {
        result.Append(" WHEN (");
        result.Append(e.When[i].Accept(this));
        result.Append(") THEN ");
        result.Append(e.Then[i].Accept(this));
      }
      if (e.Else != null && !(e.Else is DbNullExpression))
      {
        result.Append(" ELSE ");
        result.Append(e.Else.Accept(this));
      }

      result.Append(" END");

      return result;
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbCastExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      result.Append(e.Argument.Accept(this));
      return result;
    }

    /// <summary>
    /// The parser generates Not(Equals(...)) for &lt;&gt;.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/>.</returns>
    public override ISqlFragment Visit(DbComparisonExpression e)
    {
      SqlBuilder result;
      switch (e.ExpressionKind)
      {
        case DbExpressionKind.Equals:
            result = VisitBinaryExpression(" = ", e.Left, e.Right);
          break;
        case DbExpressionKind.LessThan:
          result = VisitBinaryExpression(" < ", e.Left, e.Right);
          break;
        case DbExpressionKind.LessThanOrEquals:
          result = VisitBinaryExpression(" <= ", e.Left, e.Right);
          break;
        case DbExpressionKind.GreaterThan:
          result = VisitBinaryExpression(" > ", e.Left, e.Right);
          break;
        case DbExpressionKind.GreaterThanOrEquals:
          result = VisitBinaryExpression(" >= ", e.Left, e.Right);
          break;
        // The parser does not generate the expression kind below.
        case DbExpressionKind.NotEquals:
          result = VisitBinaryExpression(" <> ", e.Left, e.Right);
          break;

        default:
          throw new InvalidOperationException();
      }

      return result;
    }

    /// <summary>
    /// Constants will be send to the store as part of the generated TSQL, not as parameters
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/>.  Strings are wrapped in single
    /// quotes and escaped.  Numbers are written literally.</returns>
    public override ISqlFragment Visit(DbConstantExpression e)
    {
      SqlBuilder result = new SqlBuilder();

      PrimitiveTypeKind typeKind;
      // Model Types can be (at the time of this implementation):
      //      Binary, Boolean, Byte, DateTime, Decimal, Double, Guid, Int16, Int32, Int64,Single, String
      if (MetadataHelpers.TryGetPrimitiveTypeKind(e.ResultType, out typeKind))
      {
        switch (typeKind)
        {
          case PrimitiveTypeKind.Int32:
            result.Append(e.Value.ToString());
            break;

          case PrimitiveTypeKind.Binary:
            result.Append(" X'");
            result.Append(ByteArrayToBinaryString((Byte[])e.Value));
            result.Append("' ");
            break;

          case PrimitiveTypeKind.Boolean:
            result.Append((bool)e.Value ? "1" : "0");
            break;

          case PrimitiveTypeKind.Byte:
            result.Append(e.Value.ToString());
            break;

          case PrimitiveTypeKind.DateTime:
            result.Append(EscapeSingleQuote(((System.DateTime)e.Value).ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture), false /* IsUnicode */));
            break;

          case PrimitiveTypeKind.Decimal:
            string strDecimal = ((Decimal)e.Value).ToString(CultureInfo.InvariantCulture);
            // if the decimal value has no decimal part, cast as decimal to preserve type
            // if the number has precision > int64 max precision, it will be handled as decimal by sql server
            // and does not need cast. if precision is lest then 20, then cast using Max(literal precision, sql default precision)
            if (-1 == strDecimal.IndexOf('.') && (strDecimal.TrimStart(new char[] { '-' }).Length < 20))
            {
              byte precision = (Byte)strDecimal.Length;
              FacetDescription precisionFacetDescription;
              Debug.Assert(MetadataHelpers.TryGetTypeFacetDescriptionByName(e.ResultType.EdmType, "precision", out precisionFacetDescription), "Decimal primitive type must have Precision facet");
              if (MetadataHelpers.TryGetTypeFacetDescriptionByName(e.ResultType.EdmType, "precision", out precisionFacetDescription))
              {
                if (precisionFacetDescription.DefaultValue != null)
                {
                  precision = Math.Max(precision, (byte)precisionFacetDescription.DefaultValue);
                }
              }
              Debug.Assert(precision > 0, "Precision must be greater than zero");
              result.Append(strDecimal);
            }
            else
            {
              result.Append(strDecimal);
            }
            break;

          case PrimitiveTypeKind.Double:
            result.Append(((Double)e.Value).ToString(CultureInfo.InvariantCulture));
            break;

          case PrimitiveTypeKind.Guid:
            result.Append(EscapeSingleQuote(e.Value.ToString(), false /* IsUnicode */));
            break;

          case PrimitiveTypeKind.Int16:
            result.Append(e.Value.ToString());
            break;

          case PrimitiveTypeKind.Int64:
            result.Append(e.Value.ToString());
            break;

          case PrimitiveTypeKind.Single:
            result.Append(((Single)e.Value).ToString(CultureInfo.InvariantCulture));
            break;

          case PrimitiveTypeKind.String:
            bool isUnicode = MetadataHelpers.GetFacetValueOrDefault<bool>(e.ResultType, MetadataHelpers.UnicodeFacetName, true);
            result.Append(EscapeSingleQuote(e.Value as string, isUnicode));
            break;
          case PrimitiveTypeKind.DateTimeOffset:
            throw new NotSupportedException("datetimeoffset");
          case PrimitiveTypeKind.Time:
            throw new NotSupportedException("time");
          default:
            // all known scalar types should been handled already.
            throw new NotSupportedException();
        }
      }
      else
      {
        throw new NotSupportedException();
      }

      return result;

    }

    /// <summary>
    /// <see cref="DbDerefExpression"/> is illegal at this stage
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbDerefExpression e)
    {
      throw new NotSupportedException();
    }

    /// <summary>
    /// The DISTINCT has to be added to the beginning of SqlSelectStatement.Select,
    /// but it might be too late for that.  So, we use a flag on SqlSelectStatement
    /// instead, and add the "DISTINCT" in the second phase.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlSelectStatement"/></returns>
    public override ISqlFragment Visit(DbDistinctExpression e)
    {
      SqlSelectStatement result = VisitExpressionEnsureSqlStatement(e.Argument);

      if (!IsCompatible(result, e.ExpressionKind))
      {
        Symbol fromSymbol;
        TypeUsage inputType = MetadataHelpers.GetElementTypeUsage(e.Argument.ResultType);
        result = CreateNewSelectStatement(result, "DISTINCT", inputType, out fromSymbol);
        AddFromSymbol(result, "DISTINCT", fromSymbol, false);
      }

      result.IsDistinct = true;
      return result;
    }

    /// <summary>
    /// An element expression returns a scalar - so it is translated to
    /// ( Select ... )
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbElementExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      result.Append("(");
      result.Append(VisitExpressionEnsureSqlStatement(e.Argument));
      result.Append(")");

      return result;
    }

    /// <summary>
    /// <see cref="Visit(DbUnionAllExpression)"/>
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbExceptExpression e)
    {
      return VisitSetOpExpression(e.Left, e.Right, "EXCEPT");
    }

    /// <summary>
    /// Only concrete expression types will be visited.
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbExpression e)
    {
      throw new InvalidOperationException();
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="e"></param>
    /// <returns>If we are in a Join context, returns a <see cref="SqlBuilder"/>
    /// with the extent name, otherwise, a new <see cref="SqlSelectStatement"/>
    /// with the From field set.</returns>
    public override ISqlFragment Visit(DbScanExpression e)
    {
      EntitySetBase target = e.Target;

      if (IsParentAJoin)
      {
        SqlBuilder result = new SqlBuilder();
        result.Append(GetTargetTSql(target));

        return result;
      }
      else
      {
        SqlSelectStatement result = new SqlSelectStatement();
        result.From.Append(GetTargetTSql(target));

        return result;
      }
    }


    /// <summary>
    /// Gets escaped TSql identifier describing this entity set.
    /// </summary>
    /// <returns></returns>
    internal static string GetTargetTSql(EntitySetBase entitySetBase)
    {
      // construct escaped T-SQL referencing entity set
      StringBuilder builder = new StringBuilder(50);
      string definingQuery = MetadataHelpers.TryGetValueForMetadataProperty<string>(entitySetBase, "DefiningQuery");
      if (!string.IsNullOrEmpty(definingQuery))
      {
        //definingQuery = definingQuery.TrimStart(' ', '\t', '\r', '\n');
        //if (String.Compare(definingQuery, 0, "TYPES ", 0, 6, StringComparison.OrdinalIgnoreCase) == 0)
        //  definingQuery = definingQuery.Substring(definingQuery.IndexOf(';') + 1).TrimStart(' ', '\t', '\r', '\n');
        builder.Append("(");
        builder.Append(definingQuery);
        builder.Append(")");
      }
      else
      {
        //string schemaName = MetadataHelpers.TryGetValueForMetadataProperty<string>(entitySetBase, "Schema");
        //if (!string.IsNullOrEmpty(schemaName))
        //{
        //  builder.Append(SqlGenerator.QuoteIdentifier(schemaName));
        //  builder.Append(".");
        //}

        string tableName = MetadataHelpers.TryGetValueForMetadataProperty<string>(entitySetBase, "Table");
        if (!string.IsNullOrEmpty(tableName))
        {
          builder.Append(SqlGenerator.QuoteIdentifier(tableName));
        }
        else
        {
          builder.Append(SqlGenerator.QuoteIdentifier(entitySetBase.Name));
        }
      }
      return builder.ToString();
    }

    /// <summary>
    /// The bodies of <see cref="Visit(DbFilterExpression)"/>, <see cref="Visit(DbGroupByExpression)"/>,
    /// <see cref="Visit(DbProjectExpression)"/>, <see cref="Visit(DbSortExpression)"/> are similar.
    /// Each does the following.
    /// <list type="number">
    /// <item> Visit the input expression</item>
    /// <item> Determine if the input's SQL statement can be reused, or a new
    /// one must be created.</item>
    /// <item>Create a new symbol table scope</item>
    /// <item>Push the Sql statement onto a stack, so that children can
    /// update the free variable list.</item>
    /// <item>Visit the non-input expression.</item>
    /// <item>Cleanup</item>
    /// </list>
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlSelectStatement"/></returns>
    public override ISqlFragment Visit(DbFilterExpression e)
    {
      return VisitFilterExpression(e.Input, e.Predicate, false);
    }

    /// <summary>
    /// Lambda functions are not supported.
    /// The functions supported are:
    /// <list type="number">
    /// <item>Canonical Functions - We recognize these by their dataspace, it is DataSpace.CSpace</item>
    /// <item>Store Functions - We recognize these by the BuiltInAttribute and not being Canonical</item>
    /// <item>User-defined Functions - All the rest except for Lambda functions</item>
    /// </list>
    /// We handle Canonical and Store functions the same way: If they are in the list of functions 
    /// that need special handling, we invoke the appropriate handler, otherwise we translate them to
    /// FunctionName(arg1, arg2, ..., argn).
    /// We translate user-defined functions to NamespaceName.FunctionName(arg1, arg2, ..., argn).
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbFunctionExpression e)
    {
      //
      // check if function requires special case processing, if so, delegates to it
      //
      if (IsSpecialBuiltInFunction(e))
      {
        return HandleSpecialBuiltInFunction(e);
      }

      if (IsSpecialCanonicalFunction(e))
      {
        return HandleSpecialCanonicalFunction(e);
      }

      return HandleFunctionDefault(e);
    }


    /// <summary>
    /// <see cref="DbEntityRefExpression"/> is illegal at this stage
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbEntityRefExpression e)
    {
      throw new NotSupportedException();
    }

    /// <summary>
    /// <see cref="DbRefKeyExpression"/> is illegal at this stage
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbRefKeyExpression e)
    {
      throw new NotSupportedException();
    }

    /// <summary>
    /// <see cref="Visit(DbFilterExpression)"/> for general details.
    /// We modify both the GroupBy and the Select fields of the SqlSelectStatement.
    /// GroupBy gets just the keys without aliases,
    /// and Select gets the keys and the aggregates with aliases.
    /// 
    /// Whenever there exists at least one aggregate with an argument that is not is not a simple
    /// <see cref="DbPropertyExpression"/>  over <see cref="DbVariableReferenceExpression"/>, 
    /// we create a nested query in which we alias the arguments to the aggregates. 
    /// That is due to the following two limitations of Sql Server:
    /// <list type="number">
    /// <item>If an expression being aggregated contains an outer reference, then that outer 
    /// reference must be the only column referenced in the expression </item>
    /// <item>Sql Server cannot perform an aggregate function on an expression containing 
    /// an aggregate or a subquery. </item>
    /// </list>
    /// 
    /// The default translation, without inner query is: 
    /// 
    ///     SELECT 
    ///         kexp1 AS key1, kexp2 AS key2,... kexpn AS keyn, 
    ///         aggf1(aexpr1) AS agg1, .. aggfn(aexprn) AS aggn
    ///     FROM input AS a
    ///     GROUP BY kexp1, kexp2, .. kexpn
    /// 
    /// When we inject an innner query, the equivalent translation is:
    /// 
    ///     SELECT 
    ///         key1 AS key1, key2 AS key2, .. keyn AS keys,  
    ///         aggf1(agg1) AS agg1, aggfn(aggn) AS aggn
    ///     FROM (
    ///             SELECT 
    ///                 kexp1 AS key1, kexp2 AS key2,... kexpn AS keyn, 
    ///                 aexpr1 AS agg1, .. aexprn AS aggn
    ///             FROM input AS a
    ///         ) as a
    ///     GROUP BY key1, key2, keyn
    /// 
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlSelectStatement"/></returns>
    public override ISqlFragment Visit(DbGroupByExpression e)
    {
      Symbol fromSymbol;
      //SqlSelectStatement result = VisitInputExpression(e.Input.Expression,
      SqlSelectStatement innerQuery = VisitInputExpression(e.Input.Expression,
          e.Input.VariableName, e.Input.VariableType, out fromSymbol);

      // GroupBy is compatible with Filter and OrderBy
      // but not with Project, GroupBy
      if (!IsCompatible(innerQuery, e.ExpressionKind))
      {
        innerQuery = CreateNewSelectStatement(innerQuery, e.Input.VariableName, e.Input.VariableType, out fromSymbol);
      }

      selectStatementStack.Push(innerQuery);
      symbolTable.EnterScope();

      AddFromSymbol(innerQuery, e.Input.VariableName, fromSymbol);
      // This line is not present for other relational nodes.
      symbolTable.Add(e.Input.GroupVariableName, fromSymbol);


      // The enumerator is shared by both the keys and the aggregates,
      // so, we do not close it in between.
      RowType groupByType = MetadataHelpers.GetEdmType<RowType>(MetadataHelpers.GetEdmType<CollectionType>(e.ResultType).TypeUsage);

      //Whenever there exists at least one aggregate with an argument that is not simply a PropertyExpression 
      // over a VarRefExpression, we need a nested query in which we alias the arguments to the aggregates.
      bool needsInnerQuery = NeedsInnerQuery(e.Aggregates);

      SqlSelectStatement result;
      if (needsInnerQuery)
      {
        //Create the inner query
        result = CreateNewSelectStatement(innerQuery, e.Input.VariableName, e.Input.VariableType, false, out fromSymbol);
        AddFromSymbol(result, e.Input.VariableName, fromSymbol, false);
      }
      else
      {
        result = innerQuery;
      }

      using (IEnumerator<EdmProperty> members = groupByType.Properties.GetEnumerator())
      {
        members.MoveNext();
        Debug.Assert(result.Select.IsEmpty);

        string separator = "";

        foreach (DbExpression key in e.Keys)
        {
          EdmProperty member = members.Current;
          string alias = QuoteIdentifier(member.Name);

          result.GroupBy.Append(separator);

          ISqlFragment keySql = key.Accept(this);

          if (!needsInnerQuery)
          {
            //Default translation: Key AS Alias
            result.Select.Append(separator);
            result.Select.AppendLine();
            result.Select.Append(keySql);
            result.Select.Append(" AS ");
            result.Select.Append(alias);

            result.GroupBy.Append(keySql);
          }
          else
          {
            // The inner query contains the default translation Key AS Alias
            innerQuery.Select.Append(separator);
            innerQuery.Select.AppendLine();
            innerQuery.Select.Append(keySql);
            innerQuery.Select.Append(" AS ");
            innerQuery.Select.Append(alias);

            //The outer resulting query projects over the key aliased in the inner query: 
            //  fromSymbol.Alias AS Alias
            result.Select.Append(separator);
            result.Select.AppendLine();
            result.Select.Append(fromSymbol);
            result.Select.Append(".");
            result.Select.Append(alias);
            result.Select.Append(" AS ");
            result.Select.Append(alias);

            result.GroupBy.Append(alias);
          }

          separator = ", ";
          members.MoveNext();
        }

        foreach (DbAggregate aggregate in e.Aggregates)
        {
          EdmProperty member = members.Current;
          string alias = QuoteIdentifier(member.Name);

          Debug.Assert(aggregate.Arguments.Count == 1);
          ISqlFragment translatedAggregateArgument = aggregate.Arguments[0].Accept(this);

          object aggregateArgument;

          if (needsInnerQuery)
          {
            //In this case the argument to the aggratete is reference to the one projected out by the
            // inner query
            SqlBuilder wrappingAggregateArgument = new SqlBuilder();
            wrappingAggregateArgument.Append(fromSymbol);
            wrappingAggregateArgument.Append(".");
            wrappingAggregateArgument.Append(alias);
            aggregateArgument = wrappingAggregateArgument;

            innerQuery.Select.Append(separator);
            innerQuery.Select.AppendLine();
            innerQuery.Select.Append(translatedAggregateArgument);
            innerQuery.Select.Append(" AS ");
            innerQuery.Select.Append(alias);
          }
          else
          {
            aggregateArgument = translatedAggregateArgument;
          }

          ISqlFragment aggregateResult = VisitAggregate(aggregate, aggregateArgument);

          result.Select.Append(separator);
          result.Select.AppendLine();
          result.Select.Append(aggregateResult);
          result.Select.Append(" AS ");
          result.Select.Append(alias);

          separator = ", ";
          members.MoveNext();
        }
      }


      symbolTable.ExitScope();
      selectStatementStack.Pop();

      return result;
    }

    /// <summary>
    /// <see cref="Visit(DbUnionAllExpression)"/>
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbIntersectExpression e)
    {
      return VisitSetOpExpression(e.Left, e.Right, "INTERSECT");
    }

    /// <summary>
    /// Not(IsEmpty) has to be handled specially, so we delegate to
    /// <see cref="VisitIsEmptyExpression"/>.
    ///
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/>.
    /// <code>[NOT] EXISTS( ... )</code>
    /// </returns>
    public override ISqlFragment Visit(DbIsEmptyExpression e)
    {
      return VisitIsEmptyExpression(e, false);
    }

    /// <summary>
    /// Not(IsNull) is handled specially, so we delegate to
    /// <see cref="VisitIsNullExpression"/>
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/>
    /// <code>IS [NOT] NULL</code>
    /// </returns>
    public override ISqlFragment Visit(DbIsNullExpression e)
    {
      return VisitIsNullExpression(e, false);
    }

    /// <summary>
    /// <see cref="DbIsOfExpression"/> is illegal at this stage
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbIsOfExpression e)
    {
      throw new NotSupportedException();
    }

    /// <summary>
    /// <see cref="VisitJoinExpression"/>
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlSelectStatement"/>.</returns>
    public override ISqlFragment Visit(DbCrossJoinExpression e)
    {
      return VisitJoinExpression(e.Inputs, e.ExpressionKind, "CROSS JOIN", null);
    }

    /// <summary>
    /// <see cref="VisitJoinExpression"/>
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlSelectStatement"/>.</returns>
    public override ISqlFragment Visit(DbJoinExpression e)
    {
      #region Map join type to a string
      string joinString;
      switch (e.ExpressionKind)
      {
        case DbExpressionKind.FullOuterJoin:
          joinString = "FULL OUTER JOIN";
          break;

        case DbExpressionKind.InnerJoin:
          joinString = "INNER JOIN";
          break;

        case DbExpressionKind.LeftOuterJoin:
          joinString = "LEFT OUTER JOIN";
          break;

        default:
          Debug.Assert(false);
          joinString = null;
          break;
      }
      #endregion

      List<DbExpressionBinding> inputs = new List<DbExpressionBinding>(2);
      inputs.Add(e.Left);
      inputs.Add(e.Right);

      return VisitJoinExpression(inputs, e.ExpressionKind, joinString, e.JoinCondition);
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbLikeExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      result.Append(e.Argument.Accept(this));
      result.Append(" LIKE ");
      result.Append(e.Pattern.Accept(this));

      // if the ESCAPE expression is a DbNullExpression, then that's tantamount to 
      // not having an ESCAPE at all
      if (e.Escape.ExpressionKind != DbExpressionKind.Null)
      {
        result.Append(" ESCAPE ");
        result.Append(e.Escape.Accept(this));
      }

      return result;
    }

    /// <summary>
    ///  Translates to TOP expression.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbLimitExpression e)
    {
      Debug.Assert(e.Limit is DbConstantExpression || e.Limit is DbParameterReferenceExpression, "DbLimitExpression.Limit is of invalid expression type");

      SqlSelectStatement result = VisitExpressionEnsureSqlStatement(e.Argument, false);
      Symbol fromSymbol;

      if (!IsCompatible(result, e.ExpressionKind))
      {
        TypeUsage inputType = MetadataHelpers.GetElementTypeUsage(e.Argument.ResultType);

        result = CreateNewSelectStatement(result, "top", inputType, out fromSymbol);
        AddFromSymbol(result, "top", fromSymbol, false);
      }

      ISqlFragment topCount = HandleCountExpression(e.Limit);

      result.Top = new TopClause(topCount, e.WithTies);
      return result;
    }

    /// <summary>
    /// DbNewInstanceExpression is allowed as a child of DbProjectExpression only.
    /// If anyone else is the parent, we throw.
    /// We also perform special casing for collections - where we could convert
    /// them into Unions
    ///
    /// <see cref="VisitNewInstanceExpression"/> for the actual implementation.
    ///
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbNewInstanceExpression e)
    {
      if (MetadataHelpers.IsCollectionType(e.ResultType))
      {
        return VisitCollectionConstructor(e);
      }
      throw new NotSupportedException();
    }

    /// <summary>
    /// The Not expression may cause the translation of its child to change.
    /// These children are
    /// <list type="bullet">
    /// <item><see cref="DbNotExpression"/>NOT(Not(x)) becomes x</item>
    /// <item><see cref="DbIsEmptyExpression"/>NOT EXISTS becomes EXISTS</item>
    /// <item><see cref="DbIsNullExpression"/>IS NULL becomes IS NOT NULL</item>
    /// <item><see cref="DbComparisonExpression"/>= becomes&lt;&gt; </item>
    /// </list>
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbNotExpression e)
    {
      // Flatten Not(Not(x)) to x.
      DbNotExpression notExpression = e.Argument as DbNotExpression;
      if (notExpression != null)
      {
        return notExpression.Argument.Accept(this);
      }

      DbIsEmptyExpression isEmptyExpression = e.Argument as DbIsEmptyExpression;
      if (isEmptyExpression != null)
      {
        return VisitIsEmptyExpression(isEmptyExpression, true);
      }

      DbIsNullExpression isNullExpression = e.Argument as DbIsNullExpression;
      if (isNullExpression != null)
      {
        return VisitIsNullExpression(isNullExpression, true);
      }

      DbComparisonExpression comparisonExpression = e.Argument as DbComparisonExpression;
      if (comparisonExpression != null)
      {
        if (comparisonExpression.ExpressionKind == DbExpressionKind.Equals)
        {
          return VisitBinaryExpression(" <> ", comparisonExpression.Left, comparisonExpression.Right);
        }
      }

      SqlBuilder result = new SqlBuilder();
      result.Append(" NOT (");
      result.Append(e.Argument.Accept(this));
      result.Append(")");

      return result;
    }

    /// <summary>
    /// </summary>
    /// <param name="e"></param>
    /// <returns><see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbNullExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      // always cast nulls - sqlserver doesn't like case expressions where the "then" clause is null
      result.Append("NULL");
      return result;
    }

    /// <summary>
    /// <see cref="DbOfTypeExpression"/> is illegal at this stage
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbOfTypeExpression e)
    {
      throw new NotSupportedException();
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    /// <seealso cref="Visit(DbAndExpression)"/>
    public override ISqlFragment Visit(DbOrExpression e)
    {
      ISqlFragment sqlFragment = null;
      if (this.TryTranslateIntoIn(e, out sqlFragment))
      {
        return sqlFragment;
      }
      return VisitBinaryExpression(" OR ", e.Left, e.Right);
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbParameterReferenceExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      // Do not quote this name.
      // We are not checking that e.Name has no illegal characters. e.g. space
      result.Append("@" + e.ParameterName);

      return result;
    }

    /// <summary>
    /// <see cref="Visit(DbFilterExpression)"/> for the general ideas.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlSelectStatement"/></returns>
    /// <seealso cref="Visit(DbFilterExpression)"/>
    public override ISqlFragment Visit(DbProjectExpression e)
    {
      Symbol fromSymbol;
      SqlSelectStatement result = VisitInputExpression(e.Input.Expression, e.Input.VariableName, e.Input.VariableType, out fromSymbol);

      // Project is compatible with Filter
      // but not with Project, GroupBy
      if (!IsCompatible(result, e.ExpressionKind))
      {
        result = CreateNewSelectStatement(result, e.Input.VariableName, e.Input.VariableType, out fromSymbol);
      }

      selectStatementStack.Push(result);
      symbolTable.EnterScope();

      AddFromSymbol(result, e.Input.VariableName, fromSymbol);

      // Project is the only node that can have DbNewInstanceExpression as a child
      // so we have to check it here.
      // We call VisitNewInstanceExpression instead of Visit(DbNewInstanceExpression), since
      // the latter throws.
      DbNewInstanceExpression newInstanceExpression = e.Projection as DbNewInstanceExpression;
      if (newInstanceExpression != null)
      {
        result.Select.Append(VisitNewInstanceExpression(newInstanceExpression));
      }
      else
      {
        result.Select.Append(e.Projection.Accept(this));
      }

      symbolTable.ExitScope();
      selectStatementStack.Pop();

      return result;
    }

    /// <summary>
    /// This method handles record flattening, which works as follows.
    /// consider an expression <c>Prop(y, Prop(x, Prop(d, Prop(c, Prop(b, Var(a)))))</c>
    /// where a,b,c are joins, d is an extent and x and y are fields.
    /// b has been flattened into a, and has its own SELECT statement.
    /// c has been flattened into b.
    /// d has been flattened into c.
    ///
    /// We visit the instance, so we reach Var(a) first.  This gives us a (join)symbol.
    /// Symbol(a).b gives us a join symbol, with a SELECT statement i.e. Symbol(b).
    /// From this point on , we need to remember Symbol(b) as the source alias,
    /// and then try to find the column.  So, we use a SymbolPair.
    ///
    /// We have reached the end when the symbol no longer points to a join symbol.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="JoinSymbol"/> if we have not reached the first
    /// Join node that has a SELECT statement.
    /// A <see cref="SymbolPair"/> if we have seen the JoinNode, and it has
    /// a SELECT statement.
    /// A <see cref="SqlBuilder"/> with {Input}.propertyName otherwise.
    /// </returns>
    public override ISqlFragment Visit(DbPropertyExpression e)
    {
      SqlBuilder result;

      ISqlFragment instanceSql = e.Instance.Accept(this);

      // Since the DbVariableReferenceExpression is a proper child of ours, we can reset
      // isVarSingle.
      DbVariableReferenceExpression DbVariableReferenceExpression = e.Instance as DbVariableReferenceExpression;
      if (DbVariableReferenceExpression != null)
      {
        isVarRefSingle = false;
      }

      // We need to flatten, and have not yet seen the first nested SELECT statement.
      JoinSymbol joinSymbol = instanceSql as JoinSymbol;
      if (joinSymbol != null)
      {
        Debug.Assert(joinSymbol.NameToExtent.ContainsKey(e.Property.Name));
        if (joinSymbol.IsNestedJoin)
        {
          return new SymbolPair(joinSymbol, joinSymbol.NameToExtent[e.Property.Name]);
        }
        else
        {
          return joinSymbol.NameToExtent[e.Property.Name];
        }
      }

      // ---------------------------------------
      // We have seen the first nested SELECT statement, but not the column.
      SymbolPair symbolPair = instanceSql as SymbolPair;
      if (symbolPair != null)
      {
        JoinSymbol columnJoinSymbol = symbolPair.Column as JoinSymbol;
        if (columnJoinSymbol != null)
        {
          symbolPair.Column = columnJoinSymbol.NameToExtent[e.Property.Name];
          return symbolPair;
        }
        else
        {
          // symbolPair.Column has the base extent.
          // we need the symbol for the column, since it might have been renamed
          // when handling a JOIN.
          if (symbolPair.Column.Columns.ContainsKey(e.Property.Name))
          {
            result = new SqlBuilder();
            result.Append(symbolPair.Source);
            result.Append(".");
            result.Append(symbolPair.Column.Columns[e.Property.Name]);
            return result;
          }
        }
      }
      // ---------------------------------------

      result = new SqlBuilder();
      result.Append(instanceSql);
      result.Append(".");

      // At this point the column name cannot be renamed, so we do
      // not use a symbol.
      result.Append(QuoteIdentifier(e.Property.Name));

      return result;
    }

    /// <summary>
    /// Any(input, x) => Exists(Filter(input,x))
    /// All(input, x) => Not Exists(Filter(input, not(x))
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbQuantifierExpression e)
    {
      SqlBuilder result = new SqlBuilder();

      bool negatePredicate = (e.ExpressionKind == DbExpressionKind.All);
      if (e.ExpressionKind == DbExpressionKind.Any)
      {
        result.Append("EXISTS (");
      }
      else
      {
        Debug.Assert(e.ExpressionKind == DbExpressionKind.All);
        result.Append("NOT EXISTS (");
      }

      SqlSelectStatement filter = VisitFilterExpression(e.Input, e.Predicate, negatePredicate);
      if (filter.Select.IsEmpty)
      {
        AddDefaultColumns(filter);
      }

      result.Append(filter);
      result.Append(")");

      return result;
    }

    /// <summary>
    /// <see cref="DbRefExpression"/> is illegal at this stage
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbRefExpression e)
    {
      throw new NotSupportedException();
    }

    /// <summary>
    /// <see cref="DbRelationshipNavigationExpression"/> is illegal at this stage
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbRelationshipNavigationExpression e)
    {
      throw new NotSupportedException();
    }

    /// <summary>
    /// For Sql9 it translates to:
    /// SELECT Y.x1, Y.x2, ..., Y.xn
    /// FROM (
    ///     SELECT X.x1, X.x2, ..., X.xn, row_number() OVER (ORDER BY sk1, sk2, ...) AS [row_number] 
    ///     FROM input as X 
    ///     ) as Y
    /// WHERE Y.[row_number] > count 
    /// ORDER BY sk1, sk2, ...
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbSkipExpression e)
    {
        Debug.Assert(e.Count is DbConstantExpression || e.Count is DbParameterReferenceExpression, "DbLimitExpression.Count is of invalid expression type");

        Symbol fromSymbol;
        SqlSelectStatement result = VisitInputExpression(e.Input.Expression, e.Input.VariableName, e.Input.VariableType, out fromSymbol);

        if (!IsCompatible(result, e.ExpressionKind))
        {
            result = CreateNewSelectStatement(result, e.Input.VariableName, e.Input.VariableType, out fromSymbol);
        }

        selectStatementStack.Push(result);
        symbolTable.EnterScope();

        AddFromSymbol(result, e.Input.VariableName, fromSymbol);

        AddSortKeys(result.OrderBy, e.SortOrder);

        symbolTable.ExitScope();
        selectStatementStack.Pop();

        ISqlFragment skipCount = HandleCountExpression(e.Count);

        result.Skip = new SkipClause(skipCount);
        return result;
    }

    /// <summary>
    /// <see cref="Visit(DbFilterExpression)"/>
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlSelectStatement"/></returns>
    /// <seealso cref="Visit(DbFilterExpression)"/>
    public override ISqlFragment Visit(DbSortExpression e)
    {
      Symbol fromSymbol;
      SqlSelectStatement result = VisitInputExpression(e.Input.Expression, e.Input.VariableName, e.Input.VariableType, out fromSymbol);

      // OrderBy is compatible with Filter
      // and nothing else
      if (!IsCompatible(result, e.ExpressionKind))
      {
        result = CreateNewSelectStatement(result, e.Input.VariableName, e.Input.VariableType, out fromSymbol);
      }

      selectStatementStack.Push(result);
      symbolTable.EnterScope();

      AddFromSymbol(result, e.Input.VariableName, fromSymbol);

      AddSortKeys(result.OrderBy, e.SortOrder);

      symbolTable.ExitScope();
      selectStatementStack.Pop();

      return result;
    }

    /// <summary>
    /// <see cref="DbTreatExpression"/> is illegal at this stage
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    public override ISqlFragment Visit(DbTreatExpression e)
    {
      throw new NotSupportedException();
    }

    /// <summary>
    /// This code is shared by <see cref="Visit(DbExceptExpression)"/>
    /// and <see cref="Visit(DbIntersectExpression)"/>
    ///
    /// <see cref="VisitSetOpExpression"/>
    /// Since the left and right expression may not be Sql select statements,
    /// we must wrap them up to look like SQL select statements.
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override ISqlFragment Visit(DbUnionAllExpression e)
    {
      return VisitSetOpExpression(e.Left, e.Right, "UNION ALL");
    }

    /// <summary>
    /// This method determines whether an extent from an outer scope(free variable)
    /// is used in the CurrentSelectStatement.
    ///
    /// An extent in an outer scope, if its symbol is not in the FromExtents
    /// of the CurrentSelectStatement.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="Symbol"/>.</returns>
    public override ISqlFragment Visit(DbVariableReferenceExpression e)
    {
      if (isVarRefSingle)
      {
        throw new NotSupportedException();
        // A DbVariableReferenceExpression has to be a child of DbPropertyExpression or MethodExpression
        // This is also checked in GenerateSql(...) at the end of the visiting.
      }
      isVarRefSingle = true; // This will be reset by DbPropertyExpression or MethodExpression

      Symbol result = symbolTable.Lookup(e.VariableName);
      if (!CurrentSelectStatement.FromExtents.Contains(result))
      {
        CurrentSelectStatement.OuterExtents[result] = true;
      }

      return result;
    }

    #region Visits shared by multiple nodes
    /// <summary>
    /// Aggregates are not visited by the normal visitor walk.
    /// </summary>
    /// <param name="aggregate">The aggreate to be translated</param>
    /// <param name="aggregateArgument">The translated aggregate argument</param>
    /// <returns></returns>
    SqlBuilder VisitAggregate(DbAggregate aggregate, object aggregateArgument)
    {
      SqlBuilder aggregateResult = new SqlBuilder();
      DbFunctionAggregate functionAggregate = aggregate as DbFunctionAggregate;

      if (functionAggregate == null)
      {
        throw new NotSupportedException();
      }

      //The only aggregate function with different name is Big_Count
      //Note: If another such function is to be added, a dictionary should be created
      //if (MetadataHelpers.IsCanonicalFunction(functionAggregate.Function)
      //    && String.Equals(functionAggregate.Function.Name, "BigCount", StringComparison.Ordinal))
      //{
      //  aggregateResult.Append("COUNT_BIG");
      //}
      //else
      {
        WriteFunctionName(aggregateResult, functionAggregate.Function);
      }

      aggregateResult.Append("(");

      DbFunctionAggregate fnAggr = functionAggregate;
      if ((null != fnAggr) && (fnAggr.Distinct))
      {
        aggregateResult.Append("DISTINCT ");
      }

      aggregateResult.Append(aggregateArgument);

      aggregateResult.Append(")");
      return aggregateResult;
    }


    SqlBuilder VisitBinaryExpression(string op, DbExpression left, DbExpression right)
    {
      SqlBuilder result = new SqlBuilder();
      if (IsComplexExpression(left))
      {
        result.Append("(");
      }

      result.Append(left.Accept(this));

      if (IsComplexExpression(left))
      {
        result.Append(")");
      }

      result.Append(op);

      if (IsComplexExpression(right))
      {
        result.Append("(");
      }

      result.Append(right.Accept(this));

      if (IsComplexExpression(right))
      {
        result.Append(")");
      }

      return result;
    }

    /// <summary>
    /// This is called by the relational nodes.  It does the following
    /// <list>
    /// <item>If the input is not a SqlSelectStatement, it assumes that the input
    /// is a collection expression, and creates a new SqlSelectStatement </item>
    /// </list>
    /// </summary>
    /// <param name="inputExpression"></param>
    /// <param name="inputVarName"></param>
    /// <param name="inputVarType"></param>
    /// <param name="fromSymbol"></param>
    /// <returns>A <see cref="SqlSelectStatement"/> and the main fromSymbol
    /// for this select statement.</returns>
    SqlSelectStatement VisitInputExpression(DbExpression inputExpression,
        string inputVarName, TypeUsage inputVarType, out Symbol fromSymbol)
    {
      SqlSelectStatement result;
      ISqlFragment sqlFragment = inputExpression.Accept(this);
      result = sqlFragment as SqlSelectStatement;

      if (result == null)
      {
        result = new SqlSelectStatement();
        WrapNonQueryExtent(result, sqlFragment, inputExpression.ExpressionKind);
      }

      if (result.FromExtents.Count == 0)
      {
        // input was an extent
        fromSymbol = new Symbol(inputVarName, inputVarType);
      }
      else if (result.FromExtents.Count == 1)
      {
        // input was Filter/GroupBy/Project/OrderBy
        // we are likely to reuse this statement.
        fromSymbol = result.FromExtents[0];
      }
      else
      {
        // input was a join.
        // we are reusing the select statement produced by a Join node
        // we need to remove the original extents, and replace them with a
        // new extent with just the Join symbol.
        JoinSymbol joinSymbol = new JoinSymbol(inputVarName, inputVarType, result.FromExtents);
        joinSymbol.FlattenedExtentList = result.AllJoinExtents;

        fromSymbol = joinSymbol;
        result.FromExtents.Clear();
        result.FromExtents.Add(fromSymbol);
      }

      return result;
    }

    /// <summary>
    /// <see cref="Visit(DbIsEmptyExpression)"/>
    /// </summary>
    /// <param name="e"></param>
    /// <param name="negate">Was the parent a DbNotExpression?</param>
    /// <returns></returns>
    SqlBuilder VisitIsEmptyExpression(DbIsEmptyExpression e, bool negate)
    {
      SqlBuilder result = new SqlBuilder();
      if (!negate)
      {
        result.Append(" NOT");
      }
      result.Append(" EXISTS (");
      result.Append(VisitExpressionEnsureSqlStatement(e.Argument));
      result.AppendLine();
      result.Append(")");

      return result;
    }


    /// <summary>
    /// Translate a NewInstance(Element(X)) expression into
    ///   "select top(1) * from X"
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    private ISqlFragment VisitCollectionConstructor(DbNewInstanceExpression e)
    {
      Debug.Assert(e.Arguments.Count <= 1);

      if (e.Arguments.Count == 1 && e.Arguments[0].ExpressionKind == DbExpressionKind.Element)
      {
        DbElementExpression elementExpr = e.Arguments[0] as DbElementExpression;
        SqlSelectStatement result = VisitExpressionEnsureSqlStatement(elementExpr.Argument);

        if (!IsCompatible(result, DbExpressionKind.Element))
        {
          Symbol fromSymbol;
          TypeUsage inputType = MetadataHelpers.GetElementTypeUsage(elementExpr.Argument.ResultType);

          result = CreateNewSelectStatement(result, "element", inputType, out fromSymbol);
          AddFromSymbol(result, "element", fromSymbol, false);
        }
        result.Top = new TopClause(1, false);
        return result;
      }


      // Otherwise simply build this out as a union-all ladder
      CollectionType collectionType = MetadataHelpers.GetEdmType<CollectionType>(e.ResultType);
      Debug.Assert(collectionType != null);
      bool isScalarElement = MetadataHelpers.IsPrimitiveType(collectionType.TypeUsage);

      SqlBuilder resultSql = new SqlBuilder();
      string separator = "";

      // handle empty table
      if (e.Arguments.Count == 0)
      {
        Debug.Assert(isScalarElement);
        resultSql.Append(" SELECT NULL");
        resultSql.Append(" AS X FROM (SELECT 1) AS Y WHERE 1=0");
      }

      foreach (DbExpression arg in e.Arguments)
      {
        resultSql.Append(separator);
        resultSql.Append(" SELECT ");
        resultSql.Append(arg.Accept(this));
        // For scalar elements, no alias is appended yet. Add this.
        if (isScalarElement)
        {
          resultSql.Append(" AS X ");
        }
        separator = " UNION ALL ";
      }

      return resultSql;
    }


    /// <summary>
    /// <see cref="Visit(DbIsNullExpression)"/>
    /// </summary>
    /// <param name="e"></param>
    /// <param name="negate">Was the parent a DbNotExpression?</param>
    /// <returns></returns>
    SqlBuilder VisitIsNullExpression(DbIsNullExpression e, bool negate)
    {
      SqlBuilder result = new SqlBuilder();
      result.Append(e.Argument.Accept(this));
      if (!negate)
      {
        result.Append(" IS NULL");
      }
      else
      {
        result.Append(" IS NOT NULL");
      }

      return result;
    }

    /// <summary>
    /// This handles the processing of join expressions.
    /// The extents on a left spine are flattened, while joins
    /// not on the left spine give rise to new nested sub queries.
    ///
    /// Joins work differently from the rest of the visiting, in that
    /// the parent (i.e. the join node) creates the SqlSelectStatement
    /// for the children to use.
    ///
    /// The "parameter" IsInJoinContext indicates whether a child extent should
    /// add its stuff to the existing SqlSelectStatement, or create a new SqlSelectStatement
    /// By passing true, we ask the children to add themselves to the parent join,
    /// by passing false, we ask the children to create new Select statements for
    /// themselves.
    ///
    /// This method is called from <see cref="Visit(DbApplyExpression)"/> and
    /// <see cref="Visit(DbJoinExpression)"/>.
    /// </summary>
    /// <param name="inputs"></param>
    /// <param name="joinKind"></param>
    /// <param name="joinString"></param>
    /// <param name="joinCondition"></param>
    /// <returns> A <see cref="SqlSelectStatement"/></returns>
    ISqlFragment VisitJoinExpression(IList<DbExpressionBinding> inputs, DbExpressionKind joinKind,
        string joinString, DbExpression joinCondition)
    {
      SqlSelectStatement result;
      // If the parent is not a join( or says that it is not),
      // we should create a new SqlSelectStatement.
      // otherwise, we add our child extents to the parent's FROM clause.
      if (!IsParentAJoin)
      {
        result = new SqlSelectStatement();
        result.AllJoinExtents = new List<Symbol>();
        selectStatementStack.Push(result);
      }
      else
      {
        result = CurrentSelectStatement;
      }

      // Process each of the inputs, and then the joinCondition if it exists.
      // It would be nice if we could call VisitInputExpression - that would
      // avoid some code duplication
      // but the Join postprocessing is messy and prevents this reuse.
      symbolTable.EnterScope();

      string separator = "";
      bool isLeftMostInput = true;
      int inputCount = inputs.Count;
      for (int idx = 0; idx < inputCount; idx++)
      {
        DbExpressionBinding input = inputs[idx];

        if (separator != "")
        {
          result.From.AppendLine();
        }
        result.From.Append(separator + " ");
        // Change this if other conditions are required
        // to force the child to produce a nested SqlStatement.
        bool needsJoinContext = (input.Expression.ExpressionKind == DbExpressionKind.Scan)
                                || (isLeftMostInput &&
                                    (IsJoinExpression(input.Expression)
                                     || IsApplyExpression(input.Expression)))
                                ;

        isParentAJoinStack.Push(needsJoinContext ? true : false);
        // if the child reuses our select statement, it will append the from
        // symbols to our FromExtents list.  So, we need to remember the
        // start of the child's entries.
        int fromSymbolStart = result.FromExtents.Count;

        ISqlFragment fromExtentFragment = input.Expression.Accept(this);

        isParentAJoinStack.Pop();

        ProcessJoinInputResult(fromExtentFragment, result, input, fromSymbolStart);
        separator = joinString;

        isLeftMostInput = false;
      }

      // Visit the on clause/join condition.
      switch (joinKind)
      {
        case DbExpressionKind.FullOuterJoin:
        case DbExpressionKind.InnerJoin:
        case DbExpressionKind.LeftOuterJoin:
          result.From.Append(" ON ");
          isParentAJoinStack.Push(false);
          result.From.Append(joinCondition.Accept(this));
          isParentAJoinStack.Pop();
          break;
      }

      symbolTable.ExitScope();

      if (!IsParentAJoin)
      {
        selectStatementStack.Pop();
      }

      return result;
    }

    /// <summary>
    /// This is called from <see cref="VisitJoinExpression"/>.
    ///
    /// This is responsible for maintaining the symbol table after visiting
    /// a child of a join expression.
    ///
    /// The child's sql statement may need to be completed.
    ///
    /// The child's result could be one of
    /// <list type="number">
    /// <item>The same as the parent's - this is treated specially.</item>
    /// <item>A sql select statement, which may need to be completed</item>
    /// <item>An extent - just copy it to the from clause</item>
    /// <item>Anything else (from a collection-valued expression) -
    /// unnest and copy it.</item>
    /// </list>
    ///
    /// If the input was a Join, we need to create a new join symbol,
    /// otherwise, we create a normal symbol.
    ///
    /// We then call AddFromSymbol to add the AS clause, and update the symbol table.
    ///
    ///
    ///
    /// If the child's result was the same as the parent's, we have to clean up
    /// the list of symbols in the FromExtents list, since this contains symbols from
    /// the children of both the parent and the child.
    /// The happens when the child visited is a Join, and is the leftmost child of
    /// the parent.
    /// </summary>
    /// <param name="fromExtentFragment"></param>
    /// <param name="result"></param>
    /// <param name="input"></param>
    /// <param name="fromSymbolStart"></param>
    void ProcessJoinInputResult(ISqlFragment fromExtentFragment, SqlSelectStatement result,
        DbExpressionBinding input, int fromSymbolStart)
    {
      Symbol fromSymbol = null;

      if (result != fromExtentFragment)
      {
        // The child has its own select statement, and is not reusing
        // our select statement.
        // This should look a lot like VisitInputExpression().
        SqlSelectStatement sqlSelectStatement = fromExtentFragment as SqlSelectStatement;
        if (sqlSelectStatement != null)
        {
          if (sqlSelectStatement.Select.IsEmpty)
          {
            List<Symbol> columns = AddDefaultColumns(sqlSelectStatement);

            if (IsJoinExpression(input.Expression)
                || IsApplyExpression(input.Expression))
            {
              List<Symbol> extents = sqlSelectStatement.FromExtents;
              JoinSymbol newJoinSymbol = new JoinSymbol(input.VariableName, input.VariableType, extents);
              newJoinSymbol.IsNestedJoin = true;
              newJoinSymbol.ColumnList = columns;

              fromSymbol = newJoinSymbol;
            }
            else
            {
              // this is a copy of the code in CreateNewSelectStatement.

              // if the oldStatement has a join as its input, ...
              // clone the join symbol, so that we "reuse" the
              // join symbol.  Normally, we create a new symbol - see the next block
              // of code.
              JoinSymbol oldJoinSymbol = sqlSelectStatement.FromExtents[0] as JoinSymbol;
              if (oldJoinSymbol != null)
              {
                // Note: sqlSelectStatement.FromExtents will not do, since it might
                // just be an alias of joinSymbol, and we want an actual JoinSymbol.
                JoinSymbol newJoinSymbol = new JoinSymbol(input.VariableName, input.VariableType, oldJoinSymbol.ExtentList);
                // This indicates that the sqlSelectStatement is a blocking scope
                // i.e. it hides/renames extent columns
                newJoinSymbol.IsNestedJoin = true;
                newJoinSymbol.ColumnList = columns;
                newJoinSymbol.FlattenedExtentList = oldJoinSymbol.FlattenedExtentList;

                fromSymbol = newJoinSymbol;
              }
            }

          }
          result.From.Append(" (");
          result.From.Append(sqlSelectStatement);
          result.From.Append(" )");
        }
        else if (input.Expression is DbScanExpression)
        {
          result.From.Append(fromExtentFragment);
        }
        else // bracket it
        {
          WrapNonQueryExtent(result, fromExtentFragment, input.Expression.ExpressionKind);
        }

        if (fromSymbol == null) // i.e. not a join symbol
        {
          fromSymbol = new Symbol(input.VariableName, input.VariableType);
        }


        AddFromSymbol(result, input.VariableName, fromSymbol);
        result.AllJoinExtents.Add(fromSymbol);
      }
      else // result == fromExtentFragment.  The child extents have been merged into the parent's.
      {
        // we are adding extents to the current sql statement via flattening.
        // We are replacing the child's extents with a single Join symbol.
        // The child's extents are all those following the index fromSymbolStart.
        //
        List<Symbol> extents = new List<Symbol>();

        // We cannot call extents.AddRange, since the is no simple way to
        // get the range of symbols fromSymbolStart..result.FromExtents.Count
        // from result.FromExtents.
        // We copy these symbols to create the JoinSymbol later.
        for (int i = fromSymbolStart; i < result.FromExtents.Count; ++i)
        {
          extents.Add(result.FromExtents[i]);
        }
        result.FromExtents.RemoveRange(fromSymbolStart, result.FromExtents.Count - fromSymbolStart);
        fromSymbol = new JoinSymbol(input.VariableName, input.VariableType, extents);
        result.FromExtents.Add(fromSymbol);
        // this Join Symbol does not have its own select statement, so we
        // do not set IsNestedJoin


        // We do not call AddFromSymbol(), since we do not want to add
        // "AS alias" to the FROM clause- it has been done when the extent was added earlier.
        symbolTable.Add(input.VariableName, fromSymbol);
      }
    }

    /// <summary>
    /// We assume that this is only called as a child of a Project.
    ///
    /// This replaces <see cref="Visit(DbNewInstanceExpression)"/>, since
    /// we do not allow DbNewInstanceExpression as a child of any node other than
    /// DbProjectExpression.
    ///
    /// We write out the translation of each of the columns in the record.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>A <see cref="SqlBuilder"/></returns>
    ISqlFragment VisitNewInstanceExpression(DbNewInstanceExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      RowType rowType = e.ResultType.EdmType as RowType;

      if (null != rowType)
      {
        //_typeDefs.Length = 0;
        ReadOnlyMetadataCollection<EdmProperty> members = rowType.Properties;
        string separator = "";
        for (int i = 0; i < e.Arguments.Count; ++i)
        {
          DbExpression argument = e.Arguments[i];
          if (MetadataHelpers.IsRowType(argument.ResultType))
          {
            // We do not support nested records or other complex objects.
            throw new NotSupportedException();
          }

          EdmProperty member = members[i];
          //_typeDefs.Append(separator);
          //_typeDefs.Append(GetSqlPrimitiveType(member.TypeUsage));
          result.Append(separator);
          result.AppendLine();
          result.Append(argument.Accept(this));
          result.Append(" AS ");
          result.Append(QuoteIdentifier(member.Name));
          separator = ", ";
        }
      }
      else
      {
        //
        // Types other then RowType (such as UDTs for instance) are not supported.
        //
        throw new NotSupportedException();
      }

      return result;
    }

    ISqlFragment VisitSetOpExpression(DbExpression left, DbExpression right, string separator)
    {

      SqlSelectStatement leftSelectStatement = VisitExpressionEnsureSqlStatement(left);
      SqlSelectStatement rightSelectStatement = VisitExpressionEnsureSqlStatement(right);

      SqlBuilder setStatement = new SqlBuilder();
      setStatement.Append(leftSelectStatement);
      setStatement.AppendLine();
      setStatement.Append(separator); // e.g. UNION ALL
      setStatement.AppendLine();
      setStatement.Append(rightSelectStatement);

      return setStatement;
    }


    #endregion


    #region Function Handling Helpers
    /// <summary>
    /// Determines whether the given function is a built-in function that requires special handling
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    private bool IsSpecialBuiltInFunction(DbFunctionExpression e)
    {
      return IsBuiltinFunction(e.Function) && _builtInFunctionHandlers.ContainsKey(e.Function.Name);
    }

    /// <summary>
    /// Determines whether the given function is a canonical function that requires special handling
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    private bool IsSpecialCanonicalFunction(DbFunctionExpression e)
    {
      return MetadataHelpers.IsCanonicalFunction(e.Function) && _canonicalFunctionHandlers.ContainsKey(e.Function.Name);
    }

    /// <summary>
    /// Default handling for functions
    /// Translates them to FunctionName(arg1, arg2, ..., argn)
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    private ISqlFragment HandleFunctionDefault(DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      WriteFunctionName(result, e.Function);
      HandleFunctionArgumentsDefault(e, result);
      return result;
    }

    /// <summary>
    /// Default handling for functions with a given name.
    /// Translates them to functionName(arg1, arg2, ..., argn)
    /// </summary>
    /// <param name="e"></param>
    /// <param name="functionName"></param>
    /// <returns></returns>
    private ISqlFragment HandleFunctionDefaultGivenName(DbFunctionExpression e, string functionName)
    {
      SqlBuilder result = new SqlBuilder();
      result.Append(functionName);
      HandleFunctionArgumentsDefault(e, result);
      return result;
    }

    /// <summary>
    /// Default handling on function arguments
    /// Appends the list of arguments to the given result
    /// If the function is niladic it does not append anything,
    /// otherwise it appends (arg1, arg2, ..., argn)
    /// </summary>
    /// <param name="e"></param>
    /// <param name="result"></param>
    private void HandleFunctionArgumentsDefault(DbFunctionExpression e, SqlBuilder result)
    {
      bool isNiladicFunction = MetadataHelpers.TryGetValueForMetadataProperty<bool>(e.Function, "NiladicFunctionAttribute");
      if (isNiladicFunction && e.Arguments.Count > 0)
      {
        throw new InvalidOperationException("Niladic functions cannot have parameters");
      }

      if (!isNiladicFunction)
      {
        result.Append("(");
        string separator = "";
        foreach (DbExpression arg in e.Arguments)
        {
          result.Append(separator);
          result.Append(arg.Accept(this));
          separator = ", ";
        }
        result.Append(")");
      }
    }

    /// <summary>
    /// Handler for special built in functions
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    private ISqlFragment HandleSpecialBuiltInFunction(DbFunctionExpression e)
    {
      return HandleSpecialFunction(_builtInFunctionHandlers, e);
    }

    /// <summary>
    /// Handler for special canonical functions
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    private ISqlFragment HandleSpecialCanonicalFunction(DbFunctionExpression e)
    {
      return HandleSpecialFunction(_canonicalFunctionHandlers, e);
    }

    /// <summary>
    /// Dispatches the special function processing to the appropriate handler
    /// </summary>
    /// <param name="handlers"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private ISqlFragment HandleSpecialFunction(Dictionary<string, FunctionHandler> handlers, DbFunctionExpression e)
    {
      if (!handlers.ContainsKey(e.Function.Name))
        throw new InvalidOperationException("Special handling should be called only for functions in the list of special functions");

      return handlers[e.Function.Name](this, e);
    }

    /// <summary>
    /// Handles functions that are translated into TSQL operators.
    /// The given function should have one or two arguments. 
    /// Functions with one arguemnt are translated into 
    ///     op arg
    /// Functions with two arguments are translated into
    ///     arg0 op arg1
    /// Also, the arguments can be optionaly enclosed in parethesis
    /// </summary>
    /// <param name="e"></param>
    /// <param name="parenthesiseArguments">Whether the arguments should be enclosed in parethesis</param>
    /// <returns></returns>
    private ISqlFragment HandleSpecialFunctionToOperator(DbFunctionExpression e, bool parenthesiseArguments)
    {
      SqlBuilder result = new SqlBuilder();
      Debug.Assert(e.Arguments.Count > 0 && e.Arguments.Count <= 2, "There should be 1 or 2 arguments for operator");

      if (e.Arguments.Count > 1)
      {
        if (parenthesiseArguments)
        {
          result.Append("(");
        }
        result.Append(e.Arguments[0].Accept(this));
        if (parenthesiseArguments)
        {
          result.Append(")");
        }
      }
      result.Append(" ");
      Debug.Assert(_functionNameToOperatorDictionary.ContainsKey(e.Function.Name), "The function can not be mapped to an operator");
      result.Append(_functionNameToOperatorDictionary[e.Function.Name]);
      result.Append(" ");

      if (parenthesiseArguments)
      {
        result.Append("(");
      }
      result.Append(e.Arguments[e.Arguments.Count - 1].Accept(this));
      if (parenthesiseArguments)
      {
        result.Append(")");
      }
      return result;
    }


    /// <summary>
    /// <see cref="HandleSpecialFunctionToOperator"></see>
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleConcatFunction(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      return sqlgen.HandleSpecialFunctionToOperator(e, false);
    }

    /// <summary>
    /// <see cref="HandleSpecialFunctionToOperator"></see>
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionBitwise(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      return sqlgen.HandleSpecialFunctionToOperator(e, true);
    }

    private static ISqlFragment HandleGetDateFunction(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      Debug.Assert(e.Arguments.Count == 0, "Canonical getdate function should have no arguments");

      switch (sqlgen._manifest._dateFormat)
      {
        case SQLiteDateFormats.Ticks:
          result.Append("(STRFTIME('%s', 'now') * 10000000 + 621355968000000000)");
          break;
        case SQLiteDateFormats.JulianDay:
          result.Append("CAST(STRFTIME('%J', 'now') AS double)");
          break;
        default:
          result.Append("STRFTIME('%Y-%m-%d %H:%M:%S', 'now')");
          break;
      }

      return result;
    }

    private static ISqlFragment HandleGetUtcDateFunction(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      Debug.Assert(e.Arguments.Count == 0, "Canonical getutcdate function should have no arguments");

      switch (sqlgen._manifest._dateFormat)
      {
        case SQLiteDateFormats.Ticks:
          result.Append("(STRFTIME('%s', 'now', 'utc') * 10000000 + 621355968000000000)");
          break;
        case SQLiteDateFormats.JulianDay:
          result.Append("CAST(STRFTIME('%J', 'now', 'utc') AS double)");
          break;
        default:
          result.Append("STRFTIME('%Y-%m-%d %H:%M:%S', 'now', 'utc')");
          break;
      }

      return result;
    }

    /// <summary>
    /// Handles special case in which datepart 'type' parameter is present. all the functions
    /// handles here have *only* the 1st parameter as datepart. datepart value is passed along
    /// the QP as string and has to be expanded as TSQL keyword.
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleDatepartDateFunction(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      Debug.Assert(e.Arguments.Count == 2, "datepart function must have 2 arguments");

      DbConstantExpression constExpr = e.Arguments[0] as DbConstantExpression;
      if (null == constExpr)
      {
        throw new InvalidOperationException(String.Format("DATEPART argument to function '{0}.{1}' must be a literal string", e.Function.NamespaceName, e.Function.Name));
      }

      string datepart = constExpr.Value as string;
      if (null == datepart)
      {
        throw new InvalidOperationException(String.Format("DATEPART argument to function '{0}.{1}' must be a literal string", e.Function.NamespaceName, e.Function.Name));
      }

      SqlBuilder result = new SqlBuilder();

      //
      // check if datepart value is valid
      //
      string trans;
      if (!_datepartKeywords.TryGetValue(datepart, out trans))
      {
        throw new InvalidOperationException(String.Format("{0}' is not a valid value for DATEPART argument in '{1}.{2}' function", datepart, e.Function.NamespaceName, e.Function.Name));
      }

      if (trans != "%f")
      {
        result.Append("CAST(STRFTIME('");

        // expand the datepart literal as tsql kword
        result.Append(trans);
        result.Append("', ");

        switch (sqlgen._manifest._dateFormat)
        {
          case SQLiteDateFormats.Ticks:
            result.Append(String.Format("(({0} - 621355968000000000) / 10000000.0)", e.Arguments[1].Accept(sqlgen)));
            break;
          default:
            result.Append(e.Arguments[1].Accept(sqlgen));
            break;
        }

        result.Append(") AS integer)");
      }
      else
      {
        result.Append("CAST(SUBSTR(STRFTIME('%f', ");

        switch (sqlgen._manifest._dateFormat)
        {
          case SQLiteDateFormats.Ticks:
            result.Append(String.Format("(({0} - 621355968000000000) / 10000000.0)", e.Arguments[1].Accept(sqlgen)));
            break;
          default:
            result.Append(e.Arguments[1].Accept(sqlgen));
            break;
        }

        result.Append("), 4) AS integer)");
      }

      return result;
    }

    /// <summary>
    /// DateAdd(datetime, secondsToAdd) -> DATEADD ( seconds , number,  date)
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionDateAdd(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      Debug.Assert(e.Arguments.Count == 2, "Canonical datepart functions should have exactly two arguments");

      switch (sqlgen._manifest._dateFormat)
      {
        case SQLiteDateFormats.Ticks:
          result.Append(String.Format("(STRFTIME('%s', JULIANDAY({1}) + ({0} / 86400.0)) * 10000000 + 621355968000000000)", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen)));
          break;
        case SQLiteDateFormats.JulianDay:
          result.Append(String.Format("CAST(STRFTIME('%J', JULIANDAY({1}) + ({0} / 86400.0)) AS double)", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen)));
          break;
        default:
          result.Append(String.Format("STRFTIME('%Y-%m-%d %H:%M:%S', JULIANDAY({1}) + ({0} / 86400.0))", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen)));
          break;
      }

      return result;
    }

    /// <summary>
    /// DateSubtract(datetime1, datetime2) -> DATEDIFF ( seconds , startdate , enddate ) 
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionDateSubtract(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      Debug.Assert(e.Arguments.Count == 2, "Canonical datepart functions should have exactly two arguments");

      switch (sqlgen._manifest._dateFormat)
      {
        case SQLiteDateFormats.Ticks:
          result.Append(String.Format("CAST((({0} - 621355968000000000) / 10000000.0)  - (({1} - 621355968000000000) / 10000000.0) * 86400.0 AS integer)", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen)));
          break;
        default:
          result.Append(String.Format("CAST((JULIANDAY({1}) - JULIANDAY({0})) * 86400.0 AS integer)", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen)));
          break;
      }

      return result;
    }

    /// <summary>
    /// Handler for canonical functions for extracting date parts. 
    /// For example:
    ///     Year(date) -> DATEPART( year, date)
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionDatepart(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      string trans;
      if (!_datepartKeywords.TryGetValue(e.Function.Name, out trans))
      {
        throw new InvalidOperationException(String.Format("{0}' is not a valid value for STRFTIME argument", e.Function.Name));
      }

      SqlBuilder result = new SqlBuilder();
      result.Append("CAST(STRFTIME('");
      result.Append(trans);
      result.Append("', ");

      Debug.Assert(e.Arguments.Count == 1, "Canonical datepart functions should have exactly one argument");

      switch (sqlgen._manifest._dateFormat)
      {
        case SQLiteDateFormats.Ticks:
          result.Append(String.Format("(({0} - 621355968000000000) / 10000000.0)", e.Arguments[0].Accept(sqlgen)));
          break;
        default:
          result.Append(e.Arguments[0].Accept(sqlgen));
          break;
      }

      result.Append(") AS integer)");

      return result;
    }

    /// <summary>
    ///  Function rename IndexOf -> CHARINDEX
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionIndexOf(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      return sqlgen.HandleFunctionDefaultGivenName(e, "CHARINDEX");
    }

    /// <summary>
    ///  Function rename NewGuid -> NEWID
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionNewGuid(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();
      result.Append("RANDOMBLOB(16)");
      return result;
    }

    /// <summary>
    ///  Length(arg) -> LEN(arg + '.') - LEN('.')
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionLength(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();

      result.Append("LENGTH(");

      Debug.Assert(e.Arguments.Count == 1, "Len should have one argument");
      result.Append(e.Arguments[0].Accept(sqlgen));

      result.Append(")");
      //result.Append(" + '.') - LEN('.')");

      return result;
    }

    /// <summary>
    /// Round(numericExpression) -> Round(numericExpression, 0);
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionRound(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();

      result.Append("ROUND(");

      Debug.Assert(e.Arguments.Count == 1, "Round should have one argument");
      result.Append(e.Arguments[0].Accept(sqlgen));

      result.Append(", 0)");

      return result;
    }

    /// <summary>
    /// TRIM(string) -> LTRIM(RTRIM(string))
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionTrim(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      SqlBuilder result = new SqlBuilder();

      result.Append("TRIM(");

      Debug.Assert(e.Arguments.Count == 1, "Trim should have one argument");
      result.Append(e.Arguments[0].Accept(sqlgen));

      result.Append(")");

      return result;
    }

    /// <summary>
    /// RIGHT(string, length) -> SUBSTR(string, -(length), length)
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionRight(SqlGenerator sqlgen, DbFunctionExpression e)
    {
        SqlBuilder result = new SqlBuilder();

        result.Append("SUBSTR(");

        Debug.Assert(e.Arguments.Count == 2, "Right should have two arguments");
        result.Append(e.Arguments[0].Accept(sqlgen));
        result.Append(", -(");
        result.Append(e.Arguments[1].Accept(sqlgen));
        result.Append("), ");
        result.Append(e.Arguments[1].Accept(sqlgen));
        result.Append(")");

        return result;
    }

    /// <summary>
    ///  Function rename ToLower -> LOWER
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionToLower(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      return sqlgen.HandleFunctionDefaultGivenName(e, "LOWER");
    }

    /// <summary>
    ///  Function rename ToUpper -> UPPER
    /// </summary>
    /// <param name="sqlgen"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private static ISqlFragment HandleCanonicalFunctionToUpper(SqlGenerator sqlgen, DbFunctionExpression e)
    {
      return sqlgen.HandleFunctionDefaultGivenName(e, "UPPER");
    }

    #endregion


    #endregion

    #region Helper methods for the DbExpressionVisitor
    /// <summary>
    /// <see cref="AddDefaultColumns"/>
    /// Add the column names from the referenced extent/join to the
    /// select statement.
    ///
    /// If the symbol is a JoinSymbol, we recursively visit all the extents,
    /// halting at real extents and JoinSymbols that have an associated SqlSelectStatement.
    ///
    /// The column names for a real extent can be derived from its type.
    /// The column names for a Join Select statement can be got from the
    /// list of columns that was created when the Join's select statement
    /// was created.
    ///
    /// We do the following for each column.
    /// <list type="number">
    /// <item>Add the SQL string for each column to the SELECT clause</item>
    /// <item>Add the column to the list of columns - so that it can
    /// become part of the "type" of a JoinSymbol</item>
    /// <item>Check if the column name collides with a previous column added
    /// to the same select statement.  Flag both the columns for renaming if true.</item>
    /// <item>Add the column to a name lookup dictionary for collision detection.</item>
    /// </list>
    /// </summary>
    /// <param name="selectStatement">The select statement that started off as SELECT *</param>
    /// <param name="symbol">The symbol containing the type information for
    /// the columns to be added.</param>
    /// <param name="columnList">Columns that have been added to the Select statement.
    /// This is created in <see cref="AddDefaultColumns"/>.</param>
    /// <param name="columnDictionary">A dictionary of the columns above.</param>
    /// <param name="separator">Comma or nothing, depending on whether the SELECT
    /// clause is empty.</param>
    void AddColumns(SqlSelectStatement selectStatement, Symbol symbol,
        List<Symbol> columnList, Dictionary<string, Symbol> columnDictionary, ref string separator)
    {
      JoinSymbol joinSymbol = symbol as JoinSymbol;
      if (joinSymbol != null)
      {
        if (!joinSymbol.IsNestedJoin)
        {
          // Recurse if the join symbol is a collection of flattened extents
          foreach (Symbol sym in joinSymbol.ExtentList)
          {
            // if sym is ScalarType means we are at base case in the
            // recursion and there are not columns to add, just skip
            if (MetadataHelpers.IsPrimitiveType(sym.Type))
            {
              continue;
            }

            AddColumns(selectStatement, sym, columnList, columnDictionary, ref separator);
          }
        }
        else
        {
          foreach (Symbol joinColumn in joinSymbol.ColumnList)
          {
            // we write tableName.columnName
            // rather than tableName.columnName as alias
            // since the column name is unique (by the way we generate new column names)
            //
            // We use the symbols for both the table and the column,
            // since they are subject to renaming.
            selectStatement.Select.Append(separator);
            selectStatement.Select.Append(symbol);
            selectStatement.Select.Append(".");
            selectStatement.Select.Append(joinColumn);

            // check for name collisions.  If there is,
            // flag both the colliding symbols.
            if (columnDictionary.ContainsKey(joinColumn.Name))
            {
              columnDictionary[joinColumn.Name].NeedsRenaming = true; // the original symbol
              joinColumn.NeedsRenaming = true; // the current symbol.
            }
            else
            {
              columnDictionary[joinColumn.Name] = joinColumn;
            }

            columnList.Add(joinColumn);

            separator = ", ";
          }
        }
      }
      else
      {
        // This is a non-join extent/select statement, and the CQT type has
        // the relevant column information.

        // The type could be a record type(e.g. Project(...),
        // or an entity type ( e.g. EntityExpression(...)
        // so, we check whether it is a structuralType.

        // Consider an expression of the form J(a, b=P(E))
        // The inner P(E) would have been translated to a SQL statement
        // We should not use the raw names from the type, but the equivalent
        // symbols (they are present in symbol.Columns) if they exist.
        //
        // We add the new columns to the symbol's columns if they do
        // not already exist.
        //

        foreach (EdmProperty property in MetadataHelpers.GetProperties(symbol.Type))
        {
          string recordMemberName = property.Name;
          // Since all renaming happens in the second phase
          // we lose nothing by setting the next column name index to 0
          // many times.
          allColumnNames[recordMemberName] = 0;

          // Create a new symbol/reuse existing symbol for the column
          Symbol columnSymbol;
          if (!symbol.Columns.TryGetValue(recordMemberName, out columnSymbol))
          {
            // we do not care about the types of columns, so we pass null
            // when construction the symbol.
            columnSymbol = new Symbol(recordMemberName, null);
            symbol.Columns.Add(recordMemberName, columnSymbol);
          }

          selectStatement.Select.Append(separator);
          selectStatement.Select.Append(symbol);
          selectStatement.Select.Append(".");

          // We use the actual name before the "AS", the new name goes
          // after the AS.
          selectStatement.Select.Append(QuoteIdentifier(recordMemberName));

          selectStatement.Select.Append(" AS ");
          selectStatement.Select.Append(columnSymbol);

          // Check for column name collisions.
          if (columnDictionary.ContainsKey(recordMemberName))
          {
            columnDictionary[recordMemberName].NeedsRenaming = true;
            columnSymbol.NeedsRenaming = true;
          }
          else
          {
            columnDictionary[recordMemberName] = symbol.Columns[recordMemberName];
          }

          columnList.Add(columnSymbol);

          separator = ", ";
        }
      }
    }

    /// <summary>
    /// Expands Select * to "select the_list_of_columns"
    /// If the columns are taken from an extent, they are written as
    /// {original_column_name AS Symbol(original_column)} to allow renaming.
    ///
    /// If the columns are taken from a Join, they are written as just
    /// {original_column_name}, since there cannot be a name collision.
    ///
    /// We concatenate the columns from each of the inputs to the select statement.
    /// Since the inputs may be joins that are flattened, we need to recurse.
    /// The inputs are inferred from the symbols in FromExtents.
    /// </summary>
    /// <param name="selectStatement"></param>
    /// <returns></returns>
    List<Symbol> AddDefaultColumns(SqlSelectStatement selectStatement)
    {
      // This is the list of columns added in this select statement
      // This forms the "type" of the Select statement, if it has to
      // be expanded in another SELECT *
      List<Symbol> columnList = new List<Symbol>();

      // A lookup for the previous set of columns to aid column name
      // collision detection.
      Dictionary<string, Symbol> columnDictionary = new Dictionary<string, Symbol>(StringComparer.OrdinalIgnoreCase);

      string separator = "";
      // The Select should usually be empty before we are called,
      // but we do not mind if it is not.
      if (!selectStatement.Select.IsEmpty)
      {
        separator = ", ";
      }

      foreach (Symbol symbol in selectStatement.FromExtents)
      {
        AddColumns(selectStatement, symbol, columnList, columnDictionary, ref separator);
      }

      return columnList;
    }

    /// <summary>
    /// <see cref="AddFromSymbol(SqlSelectStatement, string, Symbol, bool)"/>
    /// </summary>
    /// <param name="selectStatement"></param>
    /// <param name="inputVarName"></param>
    /// <param name="fromSymbol"></param>
    void AddFromSymbol(SqlSelectStatement selectStatement, string inputVarName, Symbol fromSymbol)
    {
      AddFromSymbol(selectStatement, inputVarName, fromSymbol, true);
    }

    /// <summary>
    /// This method is called after the input to a relational node is visited.
    /// <see cref="Visit(DbProjectExpression)"/> and <see cref="ProcessJoinInputResult"/>
    /// There are 2 scenarios
    /// <list type="number">
    /// <item>The fromSymbol is new i.e. the select statement has just been
    /// created, or a join extent has been added.</item>
    /// <item>The fromSymbol is old i.e. we are reusing a select statement.</item>
    /// </list>
    ///
    /// If we are not reusing the select statement, we have to complete the
    /// FROM clause with the alias
    /// <code>
    /// -- if the input was an extent
    /// FROM = [SchemaName].[TableName]
    /// -- if the input was a Project
    /// FROM = (SELECT ... FROM ... WHERE ...)
    /// </code>
    ///
    /// These become
    /// <code>
    /// -- if the input was an extent
    /// FROM = [SchemaName].[TableName] AS alias
    /// -- if the input was a Project
    /// FROM = (SELECT ... FROM ... WHERE ...) AS alias
    /// </code>
    /// and look like valid FROM clauses.
    ///
    /// Finally, we have to add the alias to the global list of aliases used,
    /// and also to the current symbol table.
    /// </summary>
    /// <param name="selectStatement"></param>
    /// <param name="inputVarName">The alias to be used.</param>
    /// <param name="fromSymbol"></param>
    /// <param name="addToSymbolTable"></param>
    void AddFromSymbol(SqlSelectStatement selectStatement, string inputVarName, Symbol fromSymbol, bool addToSymbolTable)
    {
      // the first check is true if this is a new statement
      // the second check is true if we are in a join - we do not
      // check if we are in a join context.
      // We do not want to add "AS alias" if it has been done already
      // e.g. when we are reusing the Sql statement.
      if (selectStatement.FromExtents.Count == 0 || fromSymbol != selectStatement.FromExtents[0])
      {
        selectStatement.FromExtents.Add(fromSymbol);
        selectStatement.From.Append(" AS ");
        selectStatement.From.Append(fromSymbol);

        // We have this inside the if statement, since
        // we only want to add extents that are actually used.
        allExtentNames[fromSymbol.Name] = 0;
      }

      if (addToSymbolTable)
      {
        symbolTable.Add(inputVarName, fromSymbol);
      }
    }

    /// <summary>
    /// Translates a list of SortClauses.
    /// Used in the translation of OrderBy 
    /// </summary>
    /// <param name="orderByClause">The SqlBuilder to which the sort keys should be appended</param>
    /// <param name="sortKeys"></param>
    void AddSortKeys(SqlBuilder orderByClause, IList<DbSortClause> sortKeys)
    {
      string separator = "";
      foreach (DbSortClause sortClause in sortKeys)
      {
        orderByClause.Append(separator);
        orderByClause.Append(sortClause.Expression.Accept(this));
        Debug.Assert(sortClause.Collation != null);
        if (!String.IsNullOrEmpty(sortClause.Collation))
        {
          orderByClause.Append(" COLLATE ");
          orderByClause.Append(sortClause.Collation);
        }

        orderByClause.Append(sortClause.Ascending ? " ASC" : " DESC");

        separator = ", ";
      }
    }

    /// <summary>
    /// <see cref="CreateNewSelectStatement(SqlSelectStatement, string, TypeUsage, bool, out Symbol) " />
    /// </summary>
    /// <param name="oldStatement"></param>
    /// <param name="inputVarName"></param>
    /// <param name="inputVarType"></param>
    /// <param name="fromSymbol"></param>
    /// <returns>A new select statement, with the old one as the from clause.</returns>
    SqlSelectStatement CreateNewSelectStatement(SqlSelectStatement oldStatement,
        string inputVarName, TypeUsage inputVarType, out Symbol fromSymbol)
    {
      return CreateNewSelectStatement(oldStatement, inputVarName, inputVarType, true, out fromSymbol);
    }


    /// <summary>
    /// This is called after a relational node's input has been visited, and the
    /// input's sql statement cannot be reused.  <see cref="Visit(DbProjectExpression)"/>
    ///
    /// When the input's sql statement cannot be reused, we create a new sql
    /// statement, with the old one as the from clause of the new statement.
    ///
    /// The old statement must be completed i.e. if it has an empty select list,
    /// the list of columns must be projected out.
    ///
    /// If the old statement being completed has a join symbol as its from extent,
    /// the new statement must have a clone of the join symbol as its extent.
    /// We cannot reuse the old symbol, but the new select statement must behave
    /// as though it is working over the "join" record.
    /// </summary>
    /// <param name="oldStatement"></param>
    /// <param name="inputVarName"></param>
    /// <param name="inputVarType"></param>
    /// <param name="finalizeOldStatement"></param>
    /// <param name="fromSymbol"></param>
    /// <returns>A new select statement, with the old one as the from clause.</returns>
    SqlSelectStatement CreateNewSelectStatement(SqlSelectStatement oldStatement,
        string inputVarName, TypeUsage inputVarType, bool finalizeOldStatement, out Symbol fromSymbol)
    {
      fromSymbol = null;

      // Finalize the old statement
      if (finalizeOldStatement && oldStatement.Select.IsEmpty)
      {
        List<Symbol> columns = AddDefaultColumns(oldStatement);

        // Thid could not have been called from a join node.
        Debug.Assert(oldStatement.FromExtents.Count == 1);

        // if the oldStatement has a join as its input, ...
        // clone the join symbol, so that we "reuse" the
        // join symbol.  Normally, we create a new symbol - see the next block
        // of code.
        JoinSymbol oldJoinSymbol = oldStatement.FromExtents[0] as JoinSymbol;
        if (oldJoinSymbol != null)
        {
          // Note: oldStatement.FromExtents will not do, since it might
          // just be an alias of joinSymbol, and we want an actual JoinSymbol.
          JoinSymbol newJoinSymbol = new JoinSymbol(inputVarName, inputVarType, oldJoinSymbol.ExtentList);
          // This indicates that the oldStatement is a blocking scope
          // i.e. it hides/renames extent columns
          newJoinSymbol.IsNestedJoin = true;
          newJoinSymbol.ColumnList = columns;
          newJoinSymbol.FlattenedExtentList = oldJoinSymbol.FlattenedExtentList;

          fromSymbol = newJoinSymbol;
        }
      }

      if (fromSymbol == null)
      {
        // This is just a simple extent/SqlSelectStatement,
        // and we can get the column list from the type.
        fromSymbol = new Symbol(inputVarName, inputVarType);
      }

      // Observe that the following looks like the body of Visit(ExtentExpression).
      SqlSelectStatement selectStatement = new SqlSelectStatement();
      selectStatement.From.Append("( ");
      selectStatement.From.Append(oldStatement);
      selectStatement.From.AppendLine();
      selectStatement.From.Append(") ");


      return selectStatement;
    }


    /// <summary>
    /// Before we embed a string literal in a SQL string, we should
    /// convert all ' to '', and enclose the whole string in single quotes.
    /// </summary>
    /// <param name="s"></param>
    /// <param name="isUnicode"></param>
    /// <returns>The escaped sql string.</returns>
    private static string EscapeSingleQuote(string s, bool isUnicode)
    {
      return "'" + s.Replace("'", "''") + "'";
    }

    /// <summary>
    /// Returns the sql primitive/native type name. 
    /// It will include size, precision or scale depending on type information present in the 
    /// type facets
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    private string GetSqlPrimitiveType(TypeUsage type)
    {
      PrimitiveType primitiveType = MetadataHelpers.GetEdmType<PrimitiveType>(type);

      string typeName = primitiveType.Name;
      bool isUnicode = true;
      bool isFixedLength = false;
      int maxLength = 0;
      string length = "max";
      bool preserveSeconds = true;
      byte decimalPrecision = 0;
      byte decimalScale = 0;

      switch (primitiveType.PrimitiveTypeKind)
      {
        case PrimitiveTypeKind.Binary:
          maxLength = MetadataHelpers.GetFacetValueOrDefault<int>(type, MetadataHelpers.MaxLengthFacetName, MetadataHelpers.BinaryMaxMaxLength);
          if (maxLength == MetadataHelpers.BinaryMaxMaxLength)
          {
            length = "max";
          }
          else
          {
            length = maxLength.ToString(CultureInfo.InvariantCulture);
          }
          isFixedLength = MetadataHelpers.GetFacetValueOrDefault<bool>(type, MetadataHelpers.FixedLengthFacetName, false);
          typeName = (isFixedLength ? "binary(" : "varbinary(") + length + ")";
          break;

        case PrimitiveTypeKind.String:
          // Question: How do we handle ntext?
          isUnicode = MetadataHelpers.GetFacetValueOrDefault<bool>(type, MetadataHelpers.UnicodeFacetName, true);
          isFixedLength = MetadataHelpers.GetFacetValueOrDefault<bool>(type, MetadataHelpers.FixedLengthFacetName, false);
          maxLength = MetadataHelpers.GetFacetValueOrDefault<int>(type, MetadataHelpers.MaxLengthFacetName, Int32.MinValue);
          if (maxLength == Int32.MinValue)
          {
            length = "max";
          }
          else
          {
            length = maxLength.ToString(CultureInfo.InvariantCulture);
          }
          if (isUnicode && !isFixedLength && maxLength > 4000)
            length = "max";
          if (!isUnicode && !isFixedLength && maxLength > 8000)
            length = "max";
          if (isFixedLength)
          {
            typeName = (isUnicode ? "nchar(" : "char(") + length + ")";
          }
          else
          {
            typeName = (isUnicode ? "nvarchar(" : "varchar(") + length + ")";
          }
          break;

        case PrimitiveTypeKind.DateTime:
          preserveSeconds = MetadataHelpers.GetFacetValueOrDefault<bool>(type, MetadataHelpers.PreserveSecondsFacetName, false);
          typeName = preserveSeconds ? "datetime" : "smalldatetime";
          break;

        case PrimitiveTypeKind.Decimal:
          decimalPrecision = MetadataHelpers.GetFacetValueOrDefault<byte>(type, MetadataHelpers.PrecisionFacetName, 18);
          Debug.Assert(decimalPrecision > 0, "decimal precision must be greater than zero");
          decimalScale = MetadataHelpers.GetFacetValueOrDefault<byte>(type, MetadataHelpers.ScaleFacetName, 0);
          Debug.Assert(decimalPrecision >= decimalScale, "decimalPrecision must be greater or equal to decimalScale");
          Debug.Assert(decimalPrecision <= 53, "decimalPrecision must be less than or equal to 53");
          typeName = typeName + "(" + decimalPrecision + "," + decimalScale + ")";
          break;

        case PrimitiveTypeKind.Int32:
          typeName = "int";
          break;

        case PrimitiveTypeKind.Int64:
          typeName = "bigint";
          break;

        case PrimitiveTypeKind.Int16:
          typeName = "smallint";
          break;

        case PrimitiveTypeKind.Byte:
          typeName = "tinyint";
          break;

        case PrimitiveTypeKind.Boolean:
          typeName = "bit";
          break;

        case PrimitiveTypeKind.Single:
          typeName = "real";
          break;

        case PrimitiveTypeKind.Double:
          typeName = "float";
          break;

        case PrimitiveTypeKind.Guid:
          typeName = "uniqueidentifier";
          break;

        default:
          throw new NotSupportedException("Unsupported EdmType: " + primitiveType.PrimitiveTypeKind);
      }

      return typeName;
    }

    /// <summary>
    /// Handles the expression represending DbLimitExpression.Limit and DbSkipExpression.Count.
    /// If it is a constant expression, it simply does to string thus avoiding casting it to the specific value
    /// (which would be done if <see cref="Visit(DbConstantExpression)"/> is called)
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    private ISqlFragment HandleCountExpression(DbExpression e)
    {
      ISqlFragment result;

      if (e.ExpressionKind == DbExpressionKind.Constant)
      {
        //For constant expression we should not cast the value, 
        // thus we don't go throught the default DbConstantExpression handling
        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.Append(((DbConstantExpression)e).Value.ToString());
        result = sqlBuilder;
      }
      else
      {
        result = e.Accept(this);
      }

      return result;
    }

    /// <summary>
    /// This is used to determine if a particular expression is an Apply operation.
    /// This is only the case when the DbExpressionKind is CrossApply or OuterApply.
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    bool IsApplyExpression(DbExpression e)
    {
      return (DbExpressionKind.CrossApply == e.ExpressionKind || DbExpressionKind.OuterApply == e.ExpressionKind);
    }

    private bool IsKeyForIn(DbExpression e)
    {
      if ((e.ExpressionKind != DbExpressionKind.Property) && (e.ExpressionKind != DbExpressionKind.VariableReference))
      {
        return (e.ExpressionKind == DbExpressionKind.ParameterReference);
      }
      return true;
    }

    /// <summary>
    /// This is used to determine if a particular expression is a Join operation.
    /// This is true for DbCrossJoinExpression and DbJoinExpression, the
    /// latter of which may have one of several different ExpressionKinds.
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    bool IsJoinExpression(DbExpression e)
    {
      return (DbExpressionKind.CrossJoin == e.ExpressionKind ||
              DbExpressionKind.FullOuterJoin == e.ExpressionKind ||
              DbExpressionKind.InnerJoin == e.ExpressionKind ||
              DbExpressionKind.LeftOuterJoin == e.ExpressionKind);
    }

    /// <summary>
    /// This is used to determine if a calling expression needs to place
    /// round brackets around the translation of the expression e.
    ///
    /// Constants, parameters and properties do not require brackets,
    /// everything else does.
    /// </summary>
    /// <param name="e"></param>
    /// <returns>true, if the expression needs brackets </returns>
    bool IsComplexExpression(DbExpression e)
    {
      switch (e.ExpressionKind)
      {
        case DbExpressionKind.Constant:
        case DbExpressionKind.ParameterReference:
        case DbExpressionKind.Property:
          return false;

        default:
          return true;
      }
    }

    /// <summary>
    /// Determine if the owner expression can add its unique sql to the input's
    /// SqlSelectStatement
    /// </summary>
    /// <param name="result">The SqlSelectStatement of the input to the relational node.</param>
    /// <param name="expressionKind">The kind of the expression node(not the input's)</param>
    /// <returns></returns>
    bool IsCompatible(SqlSelectStatement result, DbExpressionKind expressionKind)
    {
      switch (expressionKind)
      {
        case DbExpressionKind.Distinct:
          return result.Top == null
            // The projection after distinct may not project all 
            // columns used in the Order By
              && result.OrderBy.IsEmpty;

        case DbExpressionKind.Filter:
          return result.Select.IsEmpty
                  && result.Where.IsEmpty
                  && result.GroupBy.IsEmpty
                  && result.Top == null;

        case DbExpressionKind.GroupBy:
          return result.Select.IsEmpty
                  && result.GroupBy.IsEmpty
                  && result.OrderBy.IsEmpty
                  && result.Top == null;

        case DbExpressionKind.Limit:
        case DbExpressionKind.Element:
          return result.Top == null;

        case DbExpressionKind.Project:
          return result.Select.IsEmpty
                  && result.GroupBy.IsEmpty;

        case DbExpressionKind.Skip:
          return result.Select.IsEmpty
                  && result.GroupBy.IsEmpty
                  && result.OrderBy.IsEmpty
                  && !result.IsDistinct;

        case DbExpressionKind.Sort:
          return result.Select.IsEmpty
                  && result.GroupBy.IsEmpty
                  && result.OrderBy.IsEmpty;

        default:
          Debug.Assert(false);
          throw new InvalidOperationException();
      }

    }

    private void ParenthesizeExpressionWithoutRedundantConstantCasts(DbExpression value, SqlBuilder sqlBuilder)
    {
      if (value.ExpressionKind == DbExpressionKind.Constant)
      {
        sqlBuilder.Append(this.Visit((DbConstantExpression)value));
      }
      else
      {
        this.ParanthesizeExpressionIfNeeded(value, sqlBuilder);
          }
      }

    private void ParanthesizeExpressionIfNeeded(DbExpression e, SqlBuilder result)
    {
      if (IsComplexExpression(e))
      {
        result.Append("(");
        result.Append(e.Accept<ISqlFragment>(this));
        result.Append(")");
      }
      else
      {
        result.Append(e.Accept<ISqlFragment>(this));
      }
    }

    /// <summary>
    /// We use the normal box quotes for SQL server.  We do not deal with ANSI quotes
    /// i.e. double quotes.
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    internal static string QuoteIdentifier(string name)
    {
      Debug.Assert(!String.IsNullOrEmpty(name));
      // We assume that the names are not quoted to begin with.
      return "[" + name.Replace("]", "]]") + "]";
    }

    private bool TryAddExpressionForIn(DbBinaryExpression e, KeyToListMap<DbExpression, DbExpression> values)
    {
      if (this.IsKeyForIn(e.Left))
      {
        values.Add(e.Left, e.Right);
        return true;
      }
      if (this.IsKeyForIn(e.Right))
      {
        values.Add(e.Right, e.Left);
        return true;
      }
      return false;
    }

    /// <summary>
    /// Simply calls <see cref="VisitExpressionEnsureSqlStatement(DbExpression, bool)"/>
    /// with addDefaultColumns set to true
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    SqlSelectStatement VisitExpressionEnsureSqlStatement(DbExpression e)
    {
      return VisitExpressionEnsureSqlStatement(e, true);
    }

    /// <summary>
    /// This is called from <see cref="GenerateSql(DbQueryCommandTree)"/> and nodes which require a
    /// select statement as an argument e.g. <see cref="Visit(DbIsEmptyExpression)"/>,
    /// <see cref="Visit(DbUnionAllExpression)"/>.
    ///
    /// SqlGenerator needs its child to have a proper alias if the child is
    /// just an extent or a join.
    ///
    /// The normal relational nodes result in complete valid SQL statements.
    /// For the rest, we need to treat them as there was a dummy
    /// <code>
    /// -- originally {expression}
    /// -- change that to
    /// SELECT *
    /// FROM {expression} as c
    /// </code>
    /// 
    /// DbLimitExpression needs to start the statement but not add the default columns
    /// </summary>
    /// <param name="e"></param>
    /// <param name="addDefaultColumns"></param>
    /// <returns></returns>
    SqlSelectStatement VisitExpressionEnsureSqlStatement(DbExpression e, bool addDefaultColumns)
    {
      Debug.Assert(MetadataHelpers.IsCollectionType(e.ResultType));

      SqlSelectStatement result;
      switch (e.ExpressionKind)
      {
        case DbExpressionKind.Project:
        case DbExpressionKind.Filter:
        case DbExpressionKind.GroupBy:
        case DbExpressionKind.Sort:
          result = e.Accept(this) as SqlSelectStatement;
          break;

        default:
          Symbol fromSymbol;
          string inputVarName = "c";  // any name will do - this is my random choice.
          symbolTable.EnterScope();

          TypeUsage type = null;
          switch (e.ExpressionKind)
          {
            case DbExpressionKind.Scan:
            case DbExpressionKind.CrossJoin:
            case DbExpressionKind.FullOuterJoin:
            case DbExpressionKind.InnerJoin:
            case DbExpressionKind.LeftOuterJoin:
            case DbExpressionKind.CrossApply:
            case DbExpressionKind.OuterApply:
              type = MetadataHelpers.GetElementTypeUsage(e.ResultType);
              break;

            default:
              Debug.Assert(MetadataHelpers.IsCollectionType(e.ResultType));
              type = MetadataHelpers.GetEdmType<CollectionType>(e.ResultType).TypeUsage;
              break;
          }

          result = VisitInputExpression(e, inputVarName, type, out fromSymbol);
          AddFromSymbol(result, inputVarName, fromSymbol);
          symbolTable.ExitScope();
          break;
      }

      if (addDefaultColumns && result.Select.IsEmpty)
      {
        AddDefaultColumns(result);
      }

      return result;
    }

    /// <summary>
    /// This method is called by <see cref="Visit(DbFilterExpression)"/> and
    /// <see cref="Visit(DbQuantifierExpression)"/>
    ///
    /// </summary>
    /// <param name="input"></param>
    /// <param name="predicate"></param>
    /// <param name="negatePredicate">This is passed from <see cref="Visit(DbQuantifierExpression)"/>
    /// in the All(...) case.</param>
    /// <returns></returns>
    SqlSelectStatement VisitFilterExpression(DbExpressionBinding input, DbExpression predicate, bool negatePredicate)
    {
      Symbol fromSymbol;
      SqlSelectStatement result = VisitInputExpression(input.Expression,
          input.VariableName, input.VariableType, out fromSymbol);

      // Filter is compatible with OrderBy
      // but not with Project, another Filter or GroupBy
      if (!IsCompatible(result, DbExpressionKind.Filter))
      {
        result = CreateNewSelectStatement(result, input.VariableName, input.VariableType, out fromSymbol);
      }

      selectStatementStack.Push(result);
      symbolTable.EnterScope();

      AddFromSymbol(result, input.VariableName, fromSymbol);

      if (negatePredicate)
      {
        result.Where.Append("NOT (");
      }
      result.Where.Append(predicate.Accept(this));
      if (negatePredicate)
      {
        result.Where.Append(")");
      }

      symbolTable.ExitScope();
      selectStatementStack.Pop();

      return result;
    }

    /// <summary>
    /// If the sql fragment for an input expression is not a SqlSelect statement
    /// or other acceptable form (e.g. an extent as a SqlBuilder), we need
    /// to wrap it in a form acceptable in a FROM clause.  These are
    /// primarily the
    /// <list type="bullet">
    /// <item>The set operation expressions - union all, intersect, except</item>
    /// <item>TVFs, which are conceptually similar to tables</item>
    /// </list>
    /// </summary>
    /// <param name="result"></param>
    /// <param name="sqlFragment"></param>
    /// <param name="expressionKind"></param>
    void WrapNonQueryExtent(SqlSelectStatement result, ISqlFragment sqlFragment, DbExpressionKind expressionKind)
    {
      switch (expressionKind)
      {
        case DbExpressionKind.Function:
          // TVF
          result.From.Append(sqlFragment);
          break;

        default:
          result.From.Append(" (");
          result.From.Append(sqlFragment);
          result.From.Append(")");
          break;
      }
    }

    /// <summary>
    /// Is this a builtin function (ie) does it have the builtinAttribute specified?
    /// </summary>
    /// <param name="function"></param>
    /// <returns></returns>
    private static bool IsBuiltinFunction(EdmFunction function)
    {
      return MetadataHelpers.TryGetValueForMetadataProperty<bool>(function, "BuiltInAttribute");
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="function"></param>
    /// <param name="result"></param>
    void WriteFunctionName(SqlBuilder result, EdmFunction function)
    {
      string storeFunctionName = MetadataHelpers.TryGetValueForMetadataProperty<string>(function, "StoreFunctionNameAttribute");

      if (string.IsNullOrEmpty(storeFunctionName))
      {
        storeFunctionName = function.Name;
      }

      // If the function is a builtin (ie) the BuiltIn attribute has been
      // specified, then, the function name should not be quoted; additionally,
      // no namespace should be used.
      if (IsBuiltinFunction(function))
      {
        if (function.NamespaceName == "Edm")
        {
          switch (storeFunctionName.ToUpperInvariant())
          {
            default:
              result.Append(storeFunctionName);
              break;
          }

        }
        else
        {
          result.Append(storeFunctionName);
        }

      }
      else
      {
        // Should we actually support this?
        //result.Append(QuoteIdentifier((string)function.MetadataProperties["Schema"].Value ?? "dbo"));
        //result.Append(".");
        result.Append(QuoteIdentifier(storeFunctionName));
      }
    }

    static string ByteArrayToBinaryString(Byte[] binaryArray)
    {
      StringBuilder sb = new StringBuilder(binaryArray.Length * 2);
      for (int i = 0; i < binaryArray.Length; i++)
      {
        sb.Append(hexDigits[(binaryArray[i] & 0xF0) >> 4]).Append(hexDigits[binaryArray[i] & 0x0F]);
      }
      return sb.ToString();
    }

    /// <summary>
    /// Helper method for the Group By visitor
    /// Returns true if at least one of the aggregates in the given list
    /// has an argument that is not a <see cref="DbPropertyExpression"/> 
    /// over <see cref="DbVariableReferenceExpression"/>
    /// </summary>
    /// <param name="aggregates"></param>
    /// <returns></returns>
    static bool NeedsInnerQuery(IList<DbAggregate> aggregates)
    {
      foreach (DbAggregate aggregate in aggregates)
      {
        Debug.Assert(aggregate.Arguments.Count == 1);
        if (!IsPropertyOverVarRef(aggregate.Arguments[0]))
        {
          return true;
        }
      }
      return false;
    }

    /// <summary>
    /// Determines whether the given expression is a <see cref="DbPropertyExpression"/> 
    /// over <see cref="DbVariableReferenceExpression"/>
    /// </summary>
    /// <param name="expression"></param>
    /// <returns></returns>
    static bool IsPropertyOverVarRef(DbExpression expression)
    {
      DbPropertyExpression propertyExpression = expression as DbPropertyExpression;
      if (propertyExpression == null)
      {
        return false;
      }
      DbVariableReferenceExpression varRefExpression = propertyExpression.Instance as DbVariableReferenceExpression;
      if (varRefExpression == null)
      {
        return false;
      }
      return true;
    }

    #endregion
    
    private class KeyFieldExpressionComparer : IEqualityComparer<DbExpression>
    {
      // Fields
      internal static readonly SqlGenerator.KeyFieldExpressionComparer Singleton = new SqlGenerator.KeyFieldExpressionComparer();

      // Methods
      private KeyFieldExpressionComparer()
      {
      }

      public bool Equals(DbExpression x, DbExpression y)
      {
        if (x.ExpressionKind == y.ExpressionKind)
        {
          DbExpressionKind expressionKind = x.ExpressionKind;
          if (expressionKind <= DbExpressionKind.ParameterReference)
          {
            switch (expressionKind)
            {
              case DbExpressionKind.Cast:
                {
                  DbCastExpression expression5 = (DbCastExpression)x;
                  DbCastExpression expression6 = (DbCastExpression)y;
                  return ((expression5.ResultType == expression6.ResultType) && this.Equals(expression5.Argument, expression6.Argument));
                }
              case DbExpressionKind.ParameterReference:
                {
                  DbParameterReferenceExpression expression3 = (DbParameterReferenceExpression)x;
                  DbParameterReferenceExpression expression4 = (DbParameterReferenceExpression)y;
                  return (expression3.ParameterName == expression4.ParameterName);
                }
            }
            goto Label_00CC;
          }
          if (expressionKind != DbExpressionKind.Property)
          {
            if (expressionKind == DbExpressionKind.VariableReference)
            {
              return (x == y);
            }
            goto Label_00CC;
          }
          DbPropertyExpression expression = (DbPropertyExpression)x;
          DbPropertyExpression expression2 = (DbPropertyExpression)y;
          if (expression.Property == expression2.Property)
          {
            return this.Equals(expression.Instance, expression2.Instance);
          }
        }
        return false;
      Label_00CC:
        return false;
      }

      public int GetHashCode(DbExpression obj)
      {
        switch (obj.ExpressionKind)
        {
          case DbExpressionKind.Cast:
            return this.GetHashCode(((DbCastExpression)obj).Argument);

          case DbExpressionKind.ParameterReference:
            return (((DbParameterReferenceExpression)obj).ParameterName.GetHashCode() ^ 0x7fffffff);

          case DbExpressionKind.Property:
            return ((DbPropertyExpression)obj).Property.GetHashCode();

          case DbExpressionKind.VariableReference:
            return ((DbVariableReferenceExpression)obj).VariableName.GetHashCode();
        }
        return obj.GetHashCode();
      }
    }
  }
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/SqlSelectStatement.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
//---------------------------------------------------------------------
// <copyright file="SqlSelectStatement.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Data.Common.CommandTrees;

  /// <summary>
  /// A SqlSelectStatement represents a canonical SQL SELECT statement.
  /// It has fields for the 5 main clauses
  /// <list type="number">
  /// <item>SELECT</item>
  /// <item>FROM</item>
  /// <item>WHERE</item>
  /// <item>GROUP BY</item>
  /// <item>ORDER BY</item>
  /// </list>
  /// We do not have HAVING, since it does not correspond to anything in the DbCommandTree.
  /// Each of the fields is a SqlBuilder, so we can keep appending SQL strings
  /// or other fragments to build up the clause.
  ///
  /// We have a IsDistinct property to indicate that we want distict columns.
  /// This is given out of band, since the input expression to the select clause
  /// may already have some columns projected out, and we use append-only SqlBuilders.
  /// The DISTINCT is inserted when we finally write the object into a string.
  /// 
  /// Also, we have a Top property, which is non-null if the number of results should
  /// be limited to certain number. It is given out of band for the same reasons as DISTINCT.
  ///
  /// The FromExtents contains the list of inputs in use for the select statement.
  /// There is usually just one element in this - Select statements for joins may
  /// temporarily have more than one.
  ///
  /// If the select statement is created by a Join node, we maintain a list of
  /// all the extents that have been flattened in the join in AllJoinExtents
  /// <example>
  /// in J(j1= J(a,b), c)
  /// FromExtents has 2 nodes JoinSymbol(name=j1, ...) and Symbol(name=c)
  /// AllJoinExtents has 3 nodes Symbol(name=a), Symbol(name=b), Symbol(name=c)
  /// </example>
  ///
  /// If any expression in the non-FROM clause refers to an extent in a higher scope,
  /// we add that extent to the OuterExtents list.  This list denotes the list
  /// of extent aliases that may collide with the aliases used in this select statement.
  /// It is set by <see cref="SqlGenerator.Visit(DbVariableReferenceExpression)"/>.
  /// An extent is an outer extent if it is not one of the FromExtents.
  ///
  ///
  /// </summary>
  internal sealed class SqlSelectStatement : ISqlFragment
  {
    private bool isDistinct;

    /// <summary>
    /// Do we need to add a DISTINCT at the beginning of the SELECT
    /// </summary>
    internal bool IsDistinct
    {
      get { return isDistinct; }
      set { isDistinct = value; }
    }

    private List<Symbol> allJoinExtents;
    internal List<Symbol> AllJoinExtents
    {
      get { return allJoinExtents; }
      // We have a setter as well, even though this is a list,
      // since we use this field only in special cases.
      set { allJoinExtents = value; }
    }

    private List<Symbol> fromExtents;
    internal List<Symbol> FromExtents
    {
      get
      {
        if (null == fromExtents)
        {
          fromExtents = new List<Symbol>();
        }
        return fromExtents;
      }
    }

    private Dictionary<Symbol, bool> outerExtents;
    internal Dictionary<Symbol, bool> OuterExtents
    {
      get
      {
        if (null == outerExtents)
        {
          outerExtents = new Dictionary<Symbol, bool>();
        }
        return outerExtents;
      }
    }

    private TopClause top;
    internal TopClause Top
    {
      get { return top; }
      set
      {
        Debug.Assert(top == null, "SqlSelectStatement.Top has already been set");
        top = value;
      }
    }

    private SkipClause skip;
    internal SkipClause Skip
    {
      get { return skip; }
      set
      {
          Debug.Assert(skip == null, "SqlSelectStatement.Skip has already been set");
          skip = value;
      }
    }

    private SqlBuilder select = new SqlBuilder();
    internal SqlBuilder Select
    {
      get { return select; }
    }

    private SqlBuilder from = new SqlBuilder();
    internal SqlBuilder From
    {
      get { return from; }
    }


    private SqlBuilder where;
    internal SqlBuilder Where
    {
      get
      {
        if (null == where)
        {
          where = new SqlBuilder();
        }
        return where;
      }
    }

    private SqlBuilder groupBy;
    internal SqlBuilder GroupBy
    {
      get
      {
        if (null == groupBy)
        {
          groupBy = new SqlBuilder();
        }
        return groupBy;
      }
    }

    private SqlBuilder orderBy;
    public SqlBuilder OrderBy
    {
      get
      {
        if (null == orderBy)
        {
          orderBy = new SqlBuilder();
        }
        return orderBy;
      }
    }

    //indicates whether it is the top most select statement, 
    // if not Order By should be omitted unless there is a corresponding TOP
    private bool isTopMost;
    internal bool IsTopMost
    {
      get { return this.isTopMost; }
      set { this.isTopMost = value; }
    }

    #region ISqlFragment Members

    /// <summary>
    /// Write out a SQL select statement as a string.
    /// We have to
    /// <list type="number">
    /// <item>Check whether the aliases extents we use in this statement have
    /// to be renamed.
    /// We first create a list of all the aliases used by the outer extents.
    /// For each of the FromExtents( or AllJoinExtents if it is non-null),
    /// rename it if it collides with the previous list.
    /// </item>
    /// <item>Write each of the clauses (if it exists) as a string</item>
    /// </list>
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="sqlGenerator"></param>
    public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator)
    {
      #region Check if FROM aliases need to be renamed

      // Create a list of the aliases used by the outer extents
      // JoinSymbols have to be treated specially.
      List<string> outerExtentAliases = null;
      if ((null != outerExtents) && (0 < outerExtents.Count))
      {
        foreach (Symbol outerExtent in outerExtents.Keys)
        {
          JoinSymbol joinSymbol = outerExtent as JoinSymbol;
          if (joinSymbol != null)
          {
            foreach (Symbol symbol in joinSymbol.FlattenedExtentList)
            {
              if (null == outerExtentAliases) { outerExtentAliases = new List<string>(); }
              outerExtentAliases.Add(symbol.NewName);
            }
          }
          else
          {
            if (null == outerExtentAliases) { outerExtentAliases = new List<string>(); }
            outerExtentAliases.Add(outerExtent.NewName);
          }
        }
      }

      // An then rename each of the FromExtents we have
      // If AllJoinExtents is non-null - it has precedence.
      // The new name is derived from the old name - we append an increasing int.
      List<Symbol> extentList = this.AllJoinExtents ?? this.fromExtents;
      if (null != extentList)
      {
        foreach (Symbol fromAlias in extentList)
        {
          if ((null != outerExtentAliases) && outerExtentAliases.Contains(fromAlias.Name))
          {
            int i = sqlGenerator.AllExtentNames[fromAlias.Name];
            string newName;
            do
            {
              ++i;
              newName = fromAlias.Name + i.ToString(System.Globalization.CultureInfo.InvariantCulture);
            }
            while (sqlGenerator.AllExtentNames.ContainsKey(newName));
            sqlGenerator.AllExtentNames[fromAlias.Name] = i;
            fromAlias.NewName = newName;

            // Add extent to list of known names (although i is always incrementing, "prefix11" can
            // eventually collide with "prefix1" when it is extended)
            sqlGenerator.AllExtentNames[newName] = 0;
          }

          // Add the current alias to the list, so that the extents
          // that follow do not collide with me.
          if (null == outerExtentAliases) { outerExtentAliases = new List<string>(); }
          outerExtentAliases.Add(fromAlias.NewName);
        }
      }
      #endregion

      // Increase the indent, so that the Sql statement is nested by one tab.
      writer.Indent += 1; // ++ can be confusing in this context

      writer.Write("SELECT ");
      if (IsDistinct)
      {
        writer.Write("DISTINCT ");
      }

      if ((null == this.select) || this.Select.IsEmpty)
      {
        Debug.Assert(false);  // we have removed all possibilities of SELECT *.
        writer.Write("*");
      }
      else
      {
        this.Select.WriteSql(writer, sqlGenerator);
      }

      writer.WriteLine();
      writer.Write("FROM ");
      this.From.WriteSql(writer, sqlGenerator);

      if ((null != this.where) && !this.Where.IsEmpty)
      {
        writer.WriteLine();
        writer.Write("WHERE ");
        this.Where.WriteSql(writer, sqlGenerator);
      }

      if ((null != this.groupBy) && !this.GroupBy.IsEmpty)
      {
        writer.WriteLine();
        writer.Write("GROUP BY ");
        this.GroupBy.WriteSql(writer, sqlGenerator);
      }

      if ((null != this.orderBy) && !this.OrderBy.IsEmpty && (this.IsTopMost || this.Top != null))
      {
        writer.WriteLine();
        writer.Write("ORDER BY ");
        this.OrderBy.WriteSql(writer, sqlGenerator);
      }

      if (this.Top != null)
      {
        this.Top.WriteSql(writer, sqlGenerator);
      }

      if (this.skip != null)
      {
        this.Skip.WriteSql(writer, sqlGenerator);
      }

      --writer.Indent;
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/SqlWriter.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
//---------------------------------------------------------------------
// <copyright file="SqlWriter.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System.IO;
  using System.Text;

    /// <summary>
  /// This extends StringWriter primarily to add the ability to add an indent
  /// to each line that is written out.
  /// </summary>
  class SqlWriter : StringWriter
  {
    // We start at -1, since the first select statement will increment it to 0.
    int indent = -1;
    /// <summary>
    /// The number of tabs to be added at the beginning of each new line.
    /// </summary>
    internal int Indent
    {
      get { return indent; }
      set { indent = value; }
    }

    bool atBeginningOfLine = true;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="b"></param>
    public SqlWriter(StringBuilder b)
      : base(b, System.Globalization.CultureInfo.InvariantCulture)
    {
    }

    /// <summary>
    /// Reset atBeginningofLine if we detect the newline string.
    /// <see cref="SqlBuilder.AppendLine"/>
    /// Add as many tabs as the value of indent if we are at the 
    /// beginning of a line.
    /// </summary>
    /// <param name="value"></param>
    public override void Write(string value)
    {
      if (value == "\r\n")
      {
        base.WriteLine();
        atBeginningOfLine = true;
      }
      else
      {
        if (atBeginningOfLine)
        {
          if (indent > 0)
          {
            base.Write(new string('\t', indent));
          }
          atBeginningOfLine = false;
        }
        base.Write(value);
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override void WriteLine()
    {
      base.WriteLine();
      atBeginningOfLine = true;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/StringUtil.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
/********************************************************
 * 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.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Collections;

#if !NET_20
using System.Runtime;
#endif

namespace System.Data.SQLite
{
	internal static class StringUtil
	{
		// Fields
		private const string s_defaultDelimiter = ", ";

		// Methods
		internal static string BuildDelimitedList<T>(IEnumerable<T> values, ToStringConverter<T> converter, string delimiter)
		{
			if (values == null)
			{
				return string.Empty;
			}
			if (converter == null)
			{
				converter = new ToStringConverter<T>(StringUtil.InvariantConvertToString<T>);
			}
			if (delimiter == null)
			{
				delimiter = ", ";
			}
			StringBuilder builder = new StringBuilder();
			bool flag = true;
			foreach (T local in values)
			{
				if (flag)
				{
					flag = false;
				}
				else
				{
					builder.Append(delimiter);
				}
				builder.Append(converter(local));
			}
			return builder.ToString();
		}

		internal static string FormatIndex(string arrayVarName, int index)
		{
			StringBuilder builder = new StringBuilder((arrayVarName.Length + 10) + 2);
			return builder.Append(arrayVarName).Append('[').Append(index).Append(']').ToString();
		}

		internal static string FormatInvariant(string format, params object[] args)
		{
			return string.Format(CultureInfo.InvariantCulture, format, args);
		}

		internal static StringBuilder FormatStringBuilder(StringBuilder builder, string format, params object[] args)
		{
			builder.AppendFormat(CultureInfo.InvariantCulture, format, args);
			return builder;
		}

		internal static StringBuilder IndentNewLine(StringBuilder builder, int indent)
		{
			builder.AppendLine();
			for (int i = 0; i < indent; i++)
			{
				builder.Append("    ");
			}
			return builder;
		}

		private static string InvariantConvertToString<T>(T value)
		{
			return string.Format(CultureInfo.InvariantCulture, "{0}", new object[] { value });
		}

#if !NET_20
		[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
		internal static bool IsNullOrEmptyOrWhiteSpace(string value)
		{
			return IsNullOrEmptyOrWhiteSpace(value, 0);
		}

		internal static bool IsNullOrEmptyOrWhiteSpace(string value, int offset)
		{
			if (value != null)
			{
				for (int i = offset; i < value.Length; i++)
				{
					if (!char.IsWhiteSpace(value[i]))
					{
						return false;
					}
				}
			}
			return true;
		}

		internal static bool IsNullOrEmptyOrWhiteSpace(string value, int offset, int length)
		{
			if (value != null)
			{
				length = Math.Min(value.Length, length);
				for (int i = offset; i < length; i++)
				{
					if (!char.IsWhiteSpace(value[i]))
					{
						return false;
					}
				}
			}
			return true;
		}

		internal static string MembersToCommaSeparatedString(IEnumerable members)
		{
			StringBuilder builder = new StringBuilder();
			builder.Append("{");
			ToCommaSeparatedString(builder, members);
			builder.Append("}");
			return builder.ToString();
		}

		internal static string ToCommaSeparatedString(IEnumerable list)
		{
			return ToSeparatedString(list, ", ", string.Empty);
		}

		internal static void ToCommaSeparatedString(StringBuilder builder, IEnumerable list)
		{
			ToSeparatedStringPrivate(builder, list, ", ", string.Empty, false);
		}

		internal static string ToCommaSeparatedStringSorted(IEnumerable list)
		{
			return ToSeparatedStringSorted(list, ", ", string.Empty);
		}

		internal static void ToCommaSeparatedStringSorted(StringBuilder builder, IEnumerable list)
		{
			ToSeparatedStringPrivate(builder, list, ", ", string.Empty, true);
		}

		internal static string ToSeparatedString(IEnumerable list, string separator, string nullValue)
		{
			StringBuilder stringBuilder = new StringBuilder();
			ToSeparatedString(stringBuilder, list, separator, nullValue);
			return stringBuilder.ToString();
		}

		internal static void ToSeparatedString(StringBuilder builder, IEnumerable list, string separator)
		{
			ToSeparatedStringPrivate(builder, list, separator, string.Empty, false);
		}

#if !NET_20
		[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
		internal static void ToSeparatedString(StringBuilder stringBuilder, IEnumerable list, string separator, string nullValue)
		{
			ToSeparatedStringPrivate(stringBuilder, list, separator, nullValue, false);
		}

		private static void ToSeparatedStringPrivate(StringBuilder stringBuilder, IEnumerable list, string separator, string nullValue, bool toSort)
		{
			if (list != null)
			{
				bool flag = true;
				List<string> list2 = new List<string>();
				foreach (object obj2 in list)
				{
					string str;
					if (obj2 == null)
					{
						str = nullValue;
					}
					else
					{
						str = FormatInvariant("{0}", new object[] { obj2 });
					}
					list2.Add(str);
				}
				if (toSort)
				{
					list2.Sort(StringComparer.Ordinal);
				}
				foreach (string str2 in list2)
				{
					if (!flag)
					{
						stringBuilder.Append(separator);
					}
					stringBuilder.Append(str2);
					flag = false;
				}
			}
		}

		internal static string ToSeparatedStringSorted(IEnumerable list, string separator, string nullValue)
		{
			StringBuilder stringBuilder = new StringBuilder();
			ToSeparatedStringPrivate(stringBuilder, list, separator, nullValue, true);
			return stringBuilder.ToString();
		}

		internal static void ToSeparatedStringSorted(StringBuilder builder, IEnumerable list, string separator)
		{
			ToSeparatedStringPrivate(builder, list, separator, string.Empty, true);
		}

		// Nested Types
		internal delegate string ToStringConverter<T>(T value);
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/Symbol.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
//---------------------------------------------------------------------
// <copyright file="Symbol.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Data.Metadata.Edm;

    /// <summary>
  /// <see cref="SymbolTable"/>
  /// This class represents an extent/nested select statement,
  /// or a column.
  ///
  /// The important fields are Name, Type and NewName.
  /// NewName starts off the same as Name, and is then modified as necessary.
  ///
  ///
  /// The rest are used by special symbols.
  /// e.g. NeedsRenaming is used by columns to indicate that a new name must
  /// be picked for the column in the second phase of translation.
  ///
  /// IsUnnest is used by symbols for a collection expression used as a from clause.
  /// This allows <see cref="SqlGenerator.AddFromSymbol(SqlSelectStatement, string, Symbol, bool)"/> to add the column list
  /// after the alias.
  ///
  /// </summary>
  class Symbol : ISqlFragment
  {
    private Dictionary<string, Symbol> columns = new Dictionary<string, Symbol>(StringComparer.CurrentCultureIgnoreCase);
    internal Dictionary<string, Symbol> Columns
    {
      get { return columns; }
    }

    private bool needsRenaming = false;
    internal bool NeedsRenaming
    {
      get { return needsRenaming; }
      set { needsRenaming = value; }
    }

    bool isUnnest = false;
    internal bool IsUnnest
    {
      get { return isUnnest; }
      set { isUnnest = value; }
    }

    string name;
    public string Name
    {
      get { return name; }
    }

    string newName;
    public string NewName
    {
      get { return newName; }
      set { newName = value; }
    }

    private TypeUsage type;
    internal TypeUsage Type
    {
      get { return type; }
      set { type = value; }
    }

    public Symbol(string name, TypeUsage type)
    {
      this.name = name;
      this.newName = name;
      this.Type = type;
    }

    #region ISqlFragment Members

    /// <summary>
    /// Write this symbol out as a string for sql.  This is just
    /// the new name of the symbol (which could be the same as the old name).
    ///
    /// We rename columns here if necessary.
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="sqlGenerator"></param>
    public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator)
    {
      if (this.NeedsRenaming)
      {
        string newName;
        int i = sqlGenerator.AllColumnNames[this.NewName];
        do
        {
          ++i;
          newName = this.Name + i.ToString(System.Globalization.CultureInfo.InvariantCulture);
        } while (sqlGenerator.AllColumnNames.ContainsKey(newName));
        sqlGenerator.AllColumnNames[this.NewName] = i;

        // Prevent it from being renamed repeatedly.
        this.NeedsRenaming = false;
        this.NewName = newName;

        // Add this column name to list of known names so that there are no subsequent
        // collisions
        sqlGenerator.AllColumnNames[newName] = 0;
      }
      writer.Write(SqlGenerator.QuoteIdentifier(this.NewName));
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































Deleted System.Data.SQLite.Linq/SQL Generation/SymbolPair.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
//---------------------------------------------------------------------
// <copyright file="SymbolPair.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System.Diagnostics;
  using System.Data.Common.CommandTrees;

  /// <summary>
  /// The SymbolPair exists to solve the record flattening problem.
  /// <see cref="SqlGenerator.Visit(DbPropertyExpression)"/>
  /// Consider a property expression D(v, "j3.j2.j1.a.x")
  /// where v is a VarRef, j1, j2, j3 are joins, a is an extent and x is a columns.
  /// This has to be translated eventually into {j'}.{x'}
  /// 
  /// The source field represents the outermost SqlStatement representing a join
  /// expression (say j2) - this is always a Join symbol.
  /// 
  /// The column field keeps moving from one join symbol to the next, until it
  /// stops at a non-join symbol.
  /// 
  /// This is returned by <see cref="SqlGenerator.Visit(DbPropertyExpression)"/>,
  /// but never makes it into a SqlBuilder.
  /// </summary>
  class SymbolPair : ISqlFragment
  {
    public Symbol Source;
    public Symbol Column;

    public SymbolPair(Symbol source, Symbol column)
    {
      this.Source = source;
      this.Column = column;
    }

    #region ISqlFragment Members

    public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator)
    {
      // Symbol pair should never be part of a SqlBuilder.
      Debug.Assert(false);
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































Deleted System.Data.SQLite.Linq/SQL Generation/SymbolTable.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
//---------------------------------------------------------------------
// <copyright file="SymbolTable.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Data.Common.CommandTrees;

  /// <summary>
  /// The symbol table is quite primitive - it is a stack with a new entry for
  /// each scope.  Lookups search from the top of the stack to the bottom, until
  /// an entry is found.
  /// 
  /// The symbols are of the following kinds
  /// <list type="bullet">
  /// <item><see cref="Symbol"/> represents tables (extents/nested selects/unnests)</item>
  /// <item><see cref="JoinSymbol"/> represents Join nodes</item>
  /// <item><see cref="Symbol"/> columns.</item>
  /// </list>
  /// 
  /// Symbols represent names <see cref="SqlGenerator.Visit(DbVariableReferenceExpression)"/> to be resolved, 
  /// or things to be renamed.
  /// </summary>
  internal sealed class SymbolTable
  {
    private List<Dictionary<string, Symbol>> symbols = new List<Dictionary<string, Symbol>>();

    internal void EnterScope()
    {
      symbols.Add(new Dictionary<string, Symbol>(StringComparer.OrdinalIgnoreCase));
    }

    internal void ExitScope()
    {
      symbols.RemoveAt(symbols.Count - 1);
    }

    internal void Add(string name, Symbol value)
    {
      symbols[symbols.Count - 1][name] = value;
    }

    internal Symbol Lookup(string name)
    {
      for (int i = symbols.Count - 1; i >= 0; --i)
      {
        if (symbols[i].ContainsKey(name))
        {
          return symbols[i][name];
        }
      }

      return null;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































Deleted System.Data.SQLite.Linq/SQL Generation/TopClause.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
//---------------------------------------------------------------------
// <copyright file="TopClause.cs" company="Microsoft">
//      Portions of this file copyright (c) Microsoft Corporation
//      and are released under the Microsoft Pulic License.  See
//      http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
//      or License.txt for details.
//      All rights reserved.
// </copyright>
//---------------------------------------------------------------------

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

    /// <summary>
  /// TopClause represents the a TOP expression in a SqlSelectStatement. 
  /// It has a count property, which indicates how many TOP rows should be selected and a 
  /// boolen WithTies property.
  /// </summary>
  class TopClause : ISqlFragment
  {
    ISqlFragment topCount;
    bool withTies;

    /// <summary>
    /// Do we need to add a WITH_TIES to the top statement
    /// </summary>
    internal bool WithTies
    {
      get { return withTies; }
    }

    /// <summary>
    /// How many top rows should be selected.
    /// </summary>
    internal ISqlFragment TopCount
    {
      get { return topCount; }
    }

    /// <summary>
    /// Creates a TopClause with the given topCount and withTies.
    /// </summary>
    /// <param name="topCount"></param>
    /// <param name="withTies"></param>
    internal TopClause(ISqlFragment topCount, bool withTies)
    {
      this.topCount = topCount;
      this.withTies = withTies;
    }

    /// <summary>
    /// Creates a TopClause with the given topCount and withTies.
    /// </summary>
    /// <param name="topCount"></param>
    /// <param name="withTies"></param>
    internal TopClause(int topCount, bool withTies)
    {
      SqlBuilder sqlBuilder = new SqlBuilder();
      sqlBuilder.Append(topCount.ToString(CultureInfo.InvariantCulture));
      this.topCount = sqlBuilder;
      this.withTies = withTies;
    }

    #region ISqlFragment Members

    /// <summary>
    /// Write out the TOP part of sql select statement 
    /// It basically writes LIMIT (X).
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="sqlGenerator"></param>
    public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator)
    {
      writer.Write(" LIMIT ");
      this.TopCount.WriteSql(writer, sqlGenerator);

      if (this.WithTies)
        throw new NotSupportedException("WITH TIES");

      //writer.Write(" ");

      //if (this.WithTies)
      //{
      //    writer.Write("WITH TIES ");
      //}
    }

    #endregion
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































Deleted System.Data.SQLite.Linq/SQLiteProviderManifest.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Reflection;
  using System.IO;
  using System.Xml;
  using System.Data.Common;
  using System.Data.Metadata.Edm;

  /// <summary>
  /// The Provider Manifest for SQL Server
  /// </summary>
  internal class SQLiteProviderManifest : DbXmlEnabledProviderManifest
  {
    internal SQLiteDateFormats _dateFormat;

    /// <summary>
    /// Constructs the provider manifest.
    /// </summary>
    /// <remarks>
    /// We pass the token as a DateTimeFormat enum text, because all the datetime functions
    /// are vastly different depending on how the user is opening the connection
    /// </remarks>
    /// <param name="manifestToken">A token used to infer the capabilities of the store</param>
    public SQLiteProviderManifest(string manifestToken)
      : base(SQLiteProviderManifest.GetProviderManifest())
    {
      _dateFormat = (SQLiteDateFormats)Enum.Parse(typeof(SQLiteDateFormats), manifestToken, true);
    }

    internal static XmlReader GetProviderManifest()
    {
      return GetXmlResource("System.Data.SQLite.Linq.Resources.SQLiteProviderServices.ProviderManifest.xml");
    }

    /// <summary>
    /// Returns manifest information for the provider
    /// </summary>
    /// <param name="informationType">The name of the information to be retrieved.</param>
    /// <returns>An XmlReader at the begining of the information requested.</returns>
    protected override XmlReader GetDbInformation(string informationType)
    {
      if (informationType == DbProviderManifest.StoreSchemaDefinition)
        return GetStoreSchemaDescription();
      else if (informationType == DbProviderManifest.StoreSchemaMapping)
        return GetStoreSchemaMapping();
      else if (informationType == DbProviderManifest.ConceptualSchemaDefinition)
        return null;

      throw new ProviderIncompatibleException(String.Format("SQLite does not support this information type '{0}'.", informationType));
    }

    /// <summary>
    /// This method takes a type and a set of facets and returns the best mapped equivalent type 
    /// in EDM.
    /// </summary>
    /// <param name="storeType">A TypeUsage encapsulating a store type and a set of facets</param>
    /// <returns>A TypeUsage encapsulating an EDM type and a set of facets</returns>
    public override TypeUsage GetEdmType(TypeUsage storeType)
    {
      if (storeType == null)
      {
        throw new ArgumentNullException("storeType");
      }

      string storeTypeName = storeType.EdmType.Name.ToLowerInvariant();
      //if (!base.StoreTypeNameToEdmPrimitiveType.ContainsKey(storeTypeName))
      //{
      //  switch (storeTypeName)
      //  {
      //    case "integer":
      //      return TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int64));
      //    default:
      //      throw new ArgumentException(String.Format("SQLite does not support the type '{0}'.", storeTypeName));
      //  }
      //}

      PrimitiveType edmPrimitiveType;
      
      if (base.StoreTypeNameToEdmPrimitiveType.TryGetValue(storeTypeName, out edmPrimitiveType) == false)
        throw new ArgumentException(String.Format("SQLite does not support the type '{0}'.", storeTypeName));

      int maxLength = 0;
      bool isUnicode = true;
      bool isFixedLen = false;
      bool isUnbounded = true;

      PrimitiveTypeKind newPrimitiveTypeKind;

      switch (storeTypeName)
      {
        case "tinyint":
        case "smallint":
        case "integer":
        case "bit":
        case "uniqueidentifier":
        case "int":
        case "float":
        case "real":
          return TypeUsage.CreateDefaultTypeUsage(edmPrimitiveType);

        case "varchar":
          newPrimitiveTypeKind = PrimitiveTypeKind.String;
          isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength);
          isUnicode = false;
          isFixedLen = false;
          break;
        case "char":
          newPrimitiveTypeKind = PrimitiveTypeKind.String;
          isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength);
          isUnicode = false;
          isFixedLen = true;
          break;
        case "nvarchar":
          newPrimitiveTypeKind = PrimitiveTypeKind.String;
          isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength);
          isUnicode = true;
          isFixedLen = false;
          break;
        case "nchar":
          newPrimitiveTypeKind = PrimitiveTypeKind.String;
          isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength);
          isUnicode = true;
          isFixedLen = true;
          break;
        case "blob":
          newPrimitiveTypeKind = PrimitiveTypeKind.Binary;
          isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength);
          isFixedLen = false;
          break;
        case "decimal":
          {
            byte precision;
            byte scale;
            if (TypeHelpers.TryGetPrecision(storeType, out precision) && TypeHelpers.TryGetScale(storeType, out scale))
            {
              return TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType, precision, scale);
            }
            else
            {
              return TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType);
            }
          }
        case "datetime":
          return TypeUsage.CreateDateTimeTypeUsage(edmPrimitiveType, null);
        default:
          throw new NotSupportedException(String.Format("SQLite does not support the type '{0}'.", storeTypeName));
      }

      switch (newPrimitiveTypeKind)
      {
        case PrimitiveTypeKind.String:
          if (!isUnbounded)
          {
            return TypeUsage.CreateStringTypeUsage(edmPrimitiveType, isUnicode, isFixedLen, maxLength);
          }
          else
          {
            return TypeUsage.CreateStringTypeUsage(edmPrimitiveType, isUnicode, isFixedLen);
          }
        case PrimitiveTypeKind.Binary:
          if (!isUnbounded)
          {
            return TypeUsage.CreateBinaryTypeUsage(edmPrimitiveType, isFixedLen, maxLength);
          }
          else
          {
            return TypeUsage.CreateBinaryTypeUsage(edmPrimitiveType, isFixedLen);
          }
        default:
          throw new NotSupportedException(String.Format("SQLite does not support the type '{0}'.", storeTypeName));
      }
    }

    /// <summary>
    /// This method takes a type and a set of facets and returns the best mapped equivalent type 
    /// </summary>
    /// <param name="edmType">A TypeUsage encapsulating an EDM type and a set of facets</param>
    /// <returns>A TypeUsage encapsulating a store type and a set of facets</returns>
    public override TypeUsage GetStoreType(TypeUsage edmType)
    {
      if (edmType == null)
        throw new ArgumentNullException("edmType");

      PrimitiveType primitiveType = edmType.EdmType as PrimitiveType;
      if (primitiveType == null)
        throw new ArgumentException(String.Format("SQLite does not support the type '{0}'.", edmType));

      ReadOnlyMetadataCollection<Facet> facets = edmType.Facets;

      switch (primitiveType.PrimitiveTypeKind)
      {
        case PrimitiveTypeKind.Boolean:
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["bit"]);
        case PrimitiveTypeKind.Byte:
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["tinyint"]);
        case PrimitiveTypeKind.Int16:
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["smallint"]);
        case PrimitiveTypeKind.Int32:
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int"]);
        case PrimitiveTypeKind.Int64:
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["integer"]);
        case PrimitiveTypeKind.Guid:
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["uniqueidentifier"]);
        case PrimitiveTypeKind.Double:
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float"]);
        case PrimitiveTypeKind.Single:
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["real"]);
        case PrimitiveTypeKind.Decimal: // decimal, numeric, smallmoney, money
          {
            byte precision;
            if (!TypeHelpers.TryGetPrecision(edmType, out precision))
            {
              precision = 18;
            }

            byte scale;
            if (!TypeHelpers.TryGetScale(edmType, out scale))
            {
              scale = 0;
            }

            return TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["decimal"], precision, scale);
          }
        case PrimitiveTypeKind.Binary: // binary, varbinary, varbinary(max), image, timestamp, rowversion
          {
            bool isFixedLength = null != facets["FixedLength"].Value && (bool)facets["FixedLength"].Value;
            Facet f = facets["MaxLength"];

            bool isMaxLength = f.IsUnbounded || null == f.Value || (int)f.Value > Int32.MaxValue;
            int maxLength = !isMaxLength ? (int)f.Value : Int32.MinValue;

            TypeUsage tu;
            if (isFixedLength)
              tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["blob"], true, maxLength);
            else
            {
              if (isMaxLength)
                tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["blob"], false);
              else
                tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["blob"], false, maxLength);
            }
            return tu;
          }
        case PrimitiveTypeKind.String: // char, nchar, varchar, nvarchar, varchar(max), nvarchar(max), ntext, text
          {
            bool isUnicode = null == facets["Unicode"].Value || (bool)facets["Unicode"].Value;
            bool isFixedLength = null != facets["FixedLength"].Value && (bool)facets["FixedLength"].Value;
            Facet f = facets["MaxLength"];
            // maxlen is true if facet value is unbounded, the value is bigger than the limited string sizes *or* the facet
            // value is null. this is needed since functions still have maxlength facet value as null
            bool isMaxLength = f.IsUnbounded || null == f.Value || (int)f.Value > (isUnicode ? Int32.MaxValue : Int32.MaxValue);
            int maxLength = !isMaxLength ? (int)f.Value : Int32.MinValue;

            TypeUsage tu;

            if (isUnicode)
            {
              if (isFixedLength)
                tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["nchar"], true, true, maxLength);
              else
              {
                if (isMaxLength)
                  tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["nvarchar"], true, false);
                else
                  tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["nvarchar"], true, false, maxLength);
              }
            }
            else
            {
              if (isFixedLength)
                tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["char"], false, true, maxLength);
              else
              {
                if (isMaxLength)
                  tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["varchar"], false, false);
                else
                  tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["varchar"], false, false, maxLength);
              }
            }
            return tu;
          }
        case PrimitiveTypeKind.DateTime: // datetime, smalldatetime
          return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["datetime"]);
        default:
          throw new NotSupportedException(String.Format("There is no store type corresponding to the EDM type '{0}' of primitive type '{1}'.", edmType, primitiveType.PrimitiveTypeKind));
      }
    }

    private XmlReader GetStoreSchemaMapping()
    {
      return GetXmlResource("System.Data.SQLite.Linq.Resources.SQLiteProviderServices.StoreSchemaMapping.msl");
    }

    private XmlReader GetStoreSchemaDescription()
    {
      return GetXmlResource("System.Data.SQLite.Linq.Resources.SQLiteProviderServices.StoreSchemaDefinition.ssdl");
    }

    internal static XmlReader GetXmlResource(string resourceName)
    {
      Assembly executingAssembly = Assembly.GetExecutingAssembly();
      Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
      return XmlReader.Create(stream);
    }

    private static class TypeHelpers
    {
      public static bool TryGetPrecision(TypeUsage tu, out byte precision)
      {
        Facet f;

        precision = 0;
        if (tu.Facets.TryGetValue("Precision", false, out f))
        {
          if (!f.IsUnbounded && f.Value != null)
          {
            precision = (byte)f.Value;
            return true;
          }
        }
        return false;
      }

      public static bool TryGetMaxLength(TypeUsage tu, out int maxLength)
      {
        Facet f;

        maxLength = 0;
        if (tu.Facets.TryGetValue("MaxLength", false, out f))
        {
          if (!f.IsUnbounded && f.Value != null)
          {
            maxLength = (int)f.Value;
            return true;
          }
        }
        return false;
      }

      public static bool TryGetScale(TypeUsage tu, out byte scale)
      {
        Facet f;

        scale = 0;
        if (tu.Facets.TryGetValue("Scale", false, out f))
        {
          if (!f.IsUnbounded && f.Value != null)
          {
            scale = (byte)f.Value;
            return true;
          }
        }
        return false;
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/SQLiteProviderServices.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data.Common;
  using System.Data.Common.CommandTrees;
  using System.Data.Metadata.Edm;
  using System.Diagnostics;
  using System.Collections.Generic;
  using System.Text;
  using System.Globalization;

  internal class SQLiteProviderServices : DbProviderServices, ISQLiteSchemaExtensions
  {
    internal static readonly SQLiteProviderServices Instance = new SQLiteProviderServices();

    protected override DbCommandDefinition CreateDbCommandDefinition(DbProviderManifest manifest, DbCommandTree commandTree)
    {
      DbCommand prototype = CreateCommand(manifest, commandTree);
      DbCommandDefinition result = this.CreateCommandDefinition(prototype);
      return result;
    }

    private DbCommand CreateCommand(DbProviderManifest manifest, DbCommandTree commandTree)
    {
      if (manifest == null)
        throw new ArgumentNullException("manifest");

      if (commandTree == null)
        throw new ArgumentNullException("commandTree");

      SQLiteCommand command = new SQLiteCommand();
      try
      {
        List<DbParameter> parameters;
        CommandType commandType;

        command.CommandText = SqlGenerator.GenerateSql((SQLiteProviderManifest)manifest, commandTree, out parameters, out commandType);
        command.CommandType = commandType;

        // Get the function (if any) implemented by the command tree since this influences our interpretation of parameters
        EdmFunction function = null;
        if (commandTree is DbFunctionCommandTree)
        {
          function = ((DbFunctionCommandTree)commandTree).EdmFunction;
        }

        // Now make sure we populate the command's parameters from the CQT's parameters:
        foreach (KeyValuePair<string, TypeUsage> queryParameter in commandTree.Parameters)
        {
          SQLiteParameter parameter;

          // Use the corresponding function parameter TypeUsage where available (currently, the SSDL facets and 
          // type trump user-defined facets and type in the EntityCommand).
          FunctionParameter functionParameter;
          if (null != function && function.Parameters.TryGetValue(queryParameter.Key, false, out functionParameter))
          {
            parameter = CreateSqlParameter(functionParameter.Name, functionParameter.TypeUsage, functionParameter.Mode, DBNull.Value);
          }
          else
          {
            parameter = CreateSqlParameter(queryParameter.Key, queryParameter.Value, ParameterMode.In, DBNull.Value);
          }

          command.Parameters.Add(parameter);
        }

        // Now add parameters added as part of SQL gen (note: this feature is only safe for DML SQL gen which
        // does not support user parameters, where there is no risk of name collision)
        if (null != parameters && 0 < parameters.Count)
        {
          if (!(commandTree is DbInsertCommandTree) &&
            !(commandTree is DbUpdateCommandTree) &&
            !(commandTree is DbDeleteCommandTree))
          {
            throw new InvalidOperationException("SqlGenParametersNotPermitted");
          }

          foreach (DbParameter parameter in parameters)
          {
            command.Parameters.Add(parameter);
          }
        }

        return command;
      }
      catch
      {
        command.Dispose();
        throw;
      }
    }

    protected override string GetDbProviderManifestToken(DbConnection connection)
    {
      if (String.IsNullOrEmpty(connection.ConnectionString))
        throw new ArgumentNullException("ConnectionString");

      SortedList<string, string> opts = SQLiteConnection.ParseConnectionString(connection.ConnectionString);
      return SQLiteConnection.FindKey(opts, "DateTimeFormat", "ISO8601");
    }

    protected override DbProviderManifest GetDbProviderManifest(string versionHint)
    {
      return new SQLiteProviderManifest(versionHint);
    }

    /// <summary>
    /// Creates a SQLiteParameter given a name, type, and direction
    /// </summary>
    internal static SQLiteParameter CreateSqlParameter(string name, TypeUsage type, ParameterMode mode, object value)
    {
      int? size;

      SQLiteParameter result = new SQLiteParameter(name, value);

      // .Direction
      ParameterDirection direction = MetadataHelpers.ParameterModeToParameterDirection(mode);
      if (result.Direction != direction)
      {
        result.Direction = direction;
      }

      // .Size and .DbType
      // output parameters are handled differently (we need to ensure there is space for return
      // values where the user has not given a specific Size/MaxLength)
      bool isOutParam = mode != ParameterMode.In;
      DbType sqlDbType = GetSqlDbType(type, isOutParam, out size);
      if (result.DbType != sqlDbType)
      {
        result.DbType = sqlDbType;
      }

      // Note that we overwrite 'facet' parameters where either the value is different or
      // there is an output parameter.
      if (size.HasValue && (isOutParam || result.Size != size.Value))
      {
        result.Size = size.Value;
      }

      // .IsNullable
      bool isNullable = MetadataHelpers.IsNullable(type);
      if (isOutParam || isNullable != result.IsNullable)
      {
        result.IsNullable = isNullable;
      }

      return result;
    }


    /// <summary>
    /// Determines DbType for the given primitive type. Extracts facet
    /// information as well.
    /// </summary>
    private static DbType GetSqlDbType(TypeUsage type, bool isOutParam, out int? size)
    {
      // only supported for primitive type
      PrimitiveTypeKind primitiveTypeKind = MetadataHelpers.GetPrimitiveTypeKind(type);

      size = default(int?);

      switch (primitiveTypeKind)
      {
        case PrimitiveTypeKind.Binary:
          // for output parameters, ensure there is space...
          size = GetParameterSize(type, isOutParam);
          return GetBinaryDbType(type);

        case PrimitiveTypeKind.Boolean:
          return DbType.Boolean;

        case PrimitiveTypeKind.Byte:
          return DbType.Byte;

        case PrimitiveTypeKind.Time:
          return DbType.Time;

        case PrimitiveTypeKind.DateTimeOffset:
          return DbType.DateTimeOffset;

        case PrimitiveTypeKind.DateTime:
          return DbType.DateTime;

        case PrimitiveTypeKind.Decimal:
          return DbType.Decimal;

        case PrimitiveTypeKind.Double:
          return DbType.Double;

        case PrimitiveTypeKind.Guid:
          return DbType.Guid;

        case PrimitiveTypeKind.Int16:
          return DbType.Int16;

        case PrimitiveTypeKind.Int32:
          return DbType.Int32;

        case PrimitiveTypeKind.Int64:
          return DbType.Int64;

        case PrimitiveTypeKind.SByte:
          return DbType.SByte;

        case PrimitiveTypeKind.Single:
          return DbType.Single;

        case PrimitiveTypeKind.String:
          size = GetParameterSize(type, isOutParam);
          return GetStringDbType(type);

        default:
          Debug.Fail("unknown PrimitiveTypeKind " + primitiveTypeKind);
          return DbType.Object;
      }
    }

    /// <summary>
    /// Determines preferred value for SqlParameter.Size. Returns null
    /// where there is no preference.
    /// </summary>
    private static int? GetParameterSize(TypeUsage type, bool isOutParam)
    {
      int maxLength;
      if (MetadataHelpers.TryGetMaxLength(type, out maxLength))
      {
        // if the MaxLength facet has a specific value use it
        return maxLength;
      }
      else if (isOutParam)
      {
        // if the parameter is a return/out/inout parameter, ensure there 
        // is space for any value
        return int.MaxValue;
      }
      else
      {
        // no value
        return default(int?);
      }
    }

    /// <summary>
    /// Chooses the appropriate DbType for the given string type.
    /// </summary>
    private static DbType GetStringDbType(TypeUsage type)
    {
      Debug.Assert(type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType &&
        PrimitiveTypeKind.String == ((PrimitiveType)type.EdmType).PrimitiveTypeKind, "only valid for string type");

      DbType dbType;

      // Specific type depends on whether the string is a unicode string and whether it is a fixed length string.
      // By default, assume widest type (unicode) and most common type (variable length)
      bool unicode;
      bool fixedLength;
      if (!MetadataHelpers.TryGetIsFixedLength(type, out fixedLength))
      {
        fixedLength = false;
      }

      if (!MetadataHelpers.TryGetIsUnicode(type, out unicode))
      {
        unicode = true;
      }

      if (fixedLength)
      {
        dbType = (unicode ? DbType.StringFixedLength : DbType.AnsiStringFixedLength);
      }
      else
      {
        dbType = (unicode ? DbType.String : DbType.AnsiString);
      }
      return dbType;
    }

    /// <summary>
    /// Chooses the appropriate DbType for the given binary type.
    /// </summary>
    private static DbType GetBinaryDbType(TypeUsage type)
    {
      Debug.Assert(type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType &&
        PrimitiveTypeKind.Binary == ((PrimitiveType)type.EdmType).PrimitiveTypeKind, "only valid for binary type");

      // Specific type depends on whether the binary value is fixed length. By default, assume variable length.
      bool fixedLength;
      if (!MetadataHelpers.TryGetIsFixedLength(type, out fixedLength))
      {
        fixedLength = false;
      }

      return DbType.Binary;
      //            return fixedLength ? DbType.Binary : DbType.VarBinary;
    }

    #region ISQLiteSchemaExtensions Members

    /// <summary>
    /// Creates temporary tables on the connection so schema information can be queried
    /// </summary>
    /// <remarks>
    /// There's a lot of work involved in getting schema information out of SQLite, but LINQ expects to
    /// be able to query on schema tables.  Therefore we need to "fake" it by generating temporary tables
    /// filled with the schema of the current connection.  We get away with making this information static
    /// because schema information seems to always be queried on a new connection object, so the schema is
    /// always fresh.
    /// </remarks>
    /// <param name="cnn">The connection upon which to build the schema tables</param>
    void ISQLiteSchemaExtensions.BuildTempSchema(SQLiteConnection cnn)
    {
      string[] arr = new string[] { "TABLES", "COLUMNS", "VIEWS", "VIEWCOLUMNS", "INDEXES", "INDEXCOLUMNS", "FOREIGNKEYS", "CATALOGS" };

      using (DataTable table = cnn.GetSchema("Tables", new string[] { "temp", null, String.Format("SCHEMA{0}", arr[0]) }))
      {
        if (table.Rows.Count > 0) return;
      }

      for (int n = 0; n < arr.Length; n++)
      {
        using (DataTable table = cnn.GetSchema(arr[n]))
        {
          DataTableToTable(cnn, table, String.Format("SCHEMA{0}", arr[n]));
        }
      }

      using (SQLiteCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = Properties.Resources.SQL_CONSTRAINTS;
        cmd.ExecuteNonQuery();

        cmd.CommandText = Properties.Resources.SQL_CONSTRAINTCOLUMNS;
        cmd.ExecuteNonQuery();
      }
    }

    /// <summary>
    /// Turn a datatable into a table in the temporary database for the connection
    /// </summary>
    /// <param name="cnn">The connection to make the temporary table in</param>
    /// <param name="table">The table to write out</param>
    /// <param name="dest">The temporary table name to write to</param>
    private void DataTableToTable(SQLiteConnection cnn, DataTable table, string dest)
    {
      StringBuilder sql = new StringBuilder();
      SQLiteCommandBuilder builder = new SQLiteCommandBuilder();

      using (SQLiteCommand cmd = cnn.CreateCommand())
      using (DataTable source = new DataTable())
      {
        sql.AppendFormat(CultureInfo.InvariantCulture, "CREATE TEMP TABLE {0} (", builder.QuoteIdentifier(dest));
        string separator = String.Empty;
        foreach (DataColumn dc in table.Columns)
        {
          DbType dbtypeName = SQLiteConvert.TypeToDbType(dc.DataType);
          string typeName = SQLiteConvert.DbTypeToTypeName(dbtypeName);

          sql.AppendFormat(CultureInfo.InvariantCulture, "{2}{0} {1} COLLATE NOCASE", builder.QuoteIdentifier(dc.ColumnName), typeName, separator);
          separator = ", ";
        }
        sql.Append(")");

        cmd.CommandText = sql.ToString();
        cmd.ExecuteNonQuery();

        cmd.CommandText = String.Format("SELECT * FROM TEMP.{0} WHERE 1=2", builder.QuoteIdentifier(dest));
        using (SQLiteDataAdapter adp = new SQLiteDataAdapter(cmd))
        {
          builder.DataAdapter = adp;

          adp.Fill(source);

          foreach (DataRow row in table.Rows)
          {
            object[] arr = row.ItemArray;

            source.Rows.Add(arr);
          }
          adp.Update(source);
        }
      }
    }

    #endregion
  }
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite.Linq/System.Data.SQLite.Linq.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * System.Data.SQLite.Linq.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>System.Data.SQLite.Linq</RootNamespace>
    <AssemblyName>System.Data.SQLite.Linq</AssemblyName>
    <OldToolsVersion>2.0</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)System.Data.SQLite.Linq.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Data" />
    <Reference Include="System.Data.Entity" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="SQL Generation\DmlSqlGenerator.cs" />
    <Compile Include="SQL Generation\InternalBase.cs" />
    <Compile Include="SQL Generation\ISqlFragment.cs" />
    <Compile Include="SQL Generation\JoinSymbol.cs" />
    <Compile Include="SQL Generation\KeyToListMap.cs" />
    <Compile Include="SQL Generation\MetadataHelpers.cs" />
    <Compile Include="SQL Generation\SkipClause.cs" />
    <Compile Include="SQL Generation\SqlBuilder.cs" />
    <Compile Include="SQL Generation\SqlChecker.cs" />
    <Compile Include="SQL Generation\SqlGenerator.cs" />
    <Compile Include="SQL Generation\SqlSelectStatement.cs" />
    <Compile Include="SQL Generation\SqlWriter.cs" />
    <Compile Include="SQL Generation\StringUtil.cs" />
    <Compile Include="SQL Generation\Symbol.cs" />
    <Compile Include="SQL Generation\SymbolPair.cs" />
    <Compile Include="SQL Generation\SymbolTable.cs" />
    <Compile Include="SQL Generation\TopClause.cs" />
    <Compile Include="SQLiteProviderManifest.cs" />
    <Compile Include="SQLiteProviderServices.cs" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Resources\Common.ConceptualSchemaDefinition.csdl" />
    <EmbeddedResource Include="Resources\SQLiteProviderServices.StoreSchemaDefinition.ssdl" />
    <EmbeddedResource Include="Resources\SQLiteProviderServices.StoreSchemaMapping.msl" />
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <EmbeddedResource Include="Resources\SQLiteProviderServices.ProviderManifest.xml" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.2008.csproj">
      <Project>{AC139952-261A-4463-B6FA-AEBC25283A66}</Project>
      <Name>System.Data.SQLite.2008</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































Deleted System.Data.SQLite.Linq/System.Data.SQLite.Linq.2010.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * System.Data.SQLite.Linq.2010.csproj -
 *
 * 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>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.30319</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E6BF9F74-58E2-413B-A7CE-EA653ECB728D}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>System.Data.SQLite.Linq</RootNamespace>
    <AssemblyName>System.Data.SQLite.Linq</AssemblyName>
    <OldToolsVersion>3.5</OldToolsVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <ConfigurationYear>2010</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)System.Data.SQLite.Linq.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Data" />
    <Reference Include="System.Data.Entity" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="SQL Generation\DmlSqlGenerator.cs" />
    <Compile Include="SQL Generation\InternalBase.cs" />
    <Compile Include="SQL Generation\ISqlFragment.cs" />
    <Compile Include="SQL Generation\JoinSymbol.cs" />
    <Compile Include="SQL Generation\KeyToListMap.cs" />
    <Compile Include="SQL Generation\MetadataHelpers.cs" />
    <Compile Include="SQL Generation\SkipClause.cs" />
    <Compile Include="SQL Generation\SqlBuilder.cs" />
    <Compile Include="SQL Generation\SqlChecker.cs" />
    <Compile Include="SQL Generation\SqlGenerator.cs" />
    <Compile Include="SQL Generation\SqlSelectStatement.cs" />
    <Compile Include="SQL Generation\SqlWriter.cs" />
    <Compile Include="SQL Generation\StringUtil.cs" />
    <Compile Include="SQL Generation\Symbol.cs" />
    <Compile Include="SQL Generation\SymbolPair.cs" />
    <Compile Include="SQL Generation\SymbolTable.cs" />
    <Compile Include="SQL Generation\TopClause.cs" />
    <Compile Include="SQLiteProviderManifest.cs" />
    <Compile Include="SQLiteProviderServices.cs" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Resources\Common.ConceptualSchemaDefinition.csdl" />
    <EmbeddedResource Include="Resources\SQLiteProviderServices.StoreSchemaDefinition.ssdl" />
    <EmbeddedResource Include="Resources\SQLiteProviderServices.StoreSchemaMapping.msl" />
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <EmbeddedResource Include="Resources\SQLiteProviderServices.ProviderManifest.xml" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.2010.csproj">
      <Project>{AC139952-261A-4463-B6FA-AEBC25283A66}</Project>
      <Name>System.Data.SQLite.2010</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































Changes to System.Data.SQLite/AssemblyInfo.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
/********************************************************
 * 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.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Resources;

#if !PLATFORM_COMPACTFRAMEWORK
using System.Security;
using System.Runtime.ConstrainedExecution;
#endif

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite Core")]
[assembly: AssemblyDescription("ADO.NET Data Provider for SQLite")]

[assembly: AssemblyCompany("http://system.data.sqlite.org/")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

#if PLATFORM_COMPACTFRAMEWORK && RETARGETABLE
[assembly: AssemblyFlags(AssemblyNameFlags.Retargetable)]
#endif

//  Setting ComVisible to false makes the types in this assembly not visible 
//  to COM componenets.  If you need to access a type in this assembly from 
//  COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
[assembly: InternalsVisibleTo("System.Data.SQLite.Linq, PublicKey=" + System.Data.SQLite.SQLite3.PublicKey)]
[assembly: NeutralResourcesLanguage("en")]

#if !PLATFORM_COMPACTFRAMEWORK
[assembly: AllowPartiallyTrustedCallers]
[assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]

#if !NET_20
//
// NOTE: This attribute is only available in .NET Framework 4.0 or higher.
//
[assembly: SecurityRules(System.Security.SecurityRuleSet.Level1)]
#endif
#endif

// Version information for an assembly consists of the following four values:
//
//      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.77.0")]
#if !PLATFORM_COMPACTFRAMEWORK
[assembly: AssemblyFileVersion("1.0.77.0")]
#endif
<
<
<
<
<
<
<
<



<
<
<
<
<
<




|
|
>
|


<
<
|
<
|
<
<
<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










|
<
<
<








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











using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;







// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite")]
[assembly: AssemblyDescription("ADO.NET 2.0 Data Provider for SQLite")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]


[assembly: AssemblyTrademark("")]

[assembly: AssemblyCulture("")]






//  Setting ComVisible to false makes the types in this assembly not visible 
//  to COM componenets.  If you need to access a type in this assembly from 
//  COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
















// Version information for an assembly consists of the following four values:
//
//      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.6.*")]



Deleted System.Data.SQLite/DataTypes.xml.
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
<?xml version="1.0" standalone="yes"?>

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<DocumentElement>
  <DataTypes>
    <TypeName>smallint</TypeName>
    <ProviderDbType>10</ProviderDbType>
    <ColumnSize>5</ColumnSize>
    <DataType>System.Int16</DataType>
    <CreateFormat>smallint</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>int</TypeName>
    <ProviderDbType>11</ProviderDbType>
    <ColumnSize>10</ColumnSize>
    <DataType>System.Int32</DataType>
    <CreateFormat>int</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>real</TypeName>
    <ProviderDbType>15</ProviderDbType>
    <ColumnSize>7</ColumnSize>
    <DataType>System.Single</DataType>
    <CreateFormat>real</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>float</TypeName>
    <ProviderDbType>8</ProviderDbType>
    <ColumnSize>6</ColumnSize>
    <DataType>System.Double</DataType>
    <CreateFormat>float</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>double</TypeName>
    <ProviderDbType>8</ProviderDbType>
    <ColumnSize>6</ColumnSize>
    <DataType>System.Double</DataType>
    <CreateFormat>double</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>money</TypeName>
    <ProviderDbType>7</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Decimal</DataType>
    <CreateFormat>money</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>currency</TypeName>
    <ProviderDbType>7</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Decimal</DataType>
    <CreateFormat>currency</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>decimal</TypeName>
    <ProviderDbType>7</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Decimal</DataType>
    <CreateFormat>decimal</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>numeric</TypeName>
    <ProviderDbType>7</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Decimal</DataType>
    <CreateFormat>numeric</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>bit</TypeName>
    <ProviderDbType>3</ProviderDbType>
    <ColumnSize>1</ColumnSize>
    <DataType>System.Boolean</DataType>
    <CreateFormat>bit</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>yesno</TypeName>
    <ProviderDbType>3</ProviderDbType>
    <ColumnSize>1</ColumnSize>
    <DataType>System.Boolean</DataType>
    <CreateFormat>yesno</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>logical</TypeName>
    <ProviderDbType>3</ProviderDbType>
    <ColumnSize>1</ColumnSize>
    <DataType>System.Boolean</DataType>
    <CreateFormat>logical</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>bool</TypeName>
    <ProviderDbType>3</ProviderDbType>
    <ColumnSize>1</ColumnSize>
    <DataType>System.Boolean</DataType>
    <CreateFormat>bool</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>boolean</TypeName>
    <ProviderDbType>3</ProviderDbType>
    <ColumnSize>1</ColumnSize>
    <DataType>System.Boolean</DataType>
    <CreateFormat>boolean</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>tinyint</TypeName>
    <ProviderDbType>2</ProviderDbType>
    <ColumnSize>3</ColumnSize>
    <DataType>System.Byte</DataType>
    <CreateFormat>tinyint</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>true</IsUnsigned>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>integer</TypeName>
    <ProviderDbType>12</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Int64</DataType>
    <CreateFormat>integer</CreateFormat>
    <IsAutoIncrementable>true</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>counter</TypeName>
    <ProviderDbType>12</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Int64</DataType>
    <CreateFormat>counter</CreateFormat>
    <IsAutoIncrementable>true</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>autoincrement</TypeName>
    <ProviderDbType>12</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Int64</DataType>
    <CreateFormat>autoincrement</CreateFormat>
    <IsAutoIncrementable>true</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>identity</TypeName>
    <ProviderDbType>12</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Int64</DataType>
    <CreateFormat>identity</CreateFormat>
    <IsAutoIncrementable>true</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>long</TypeName>
    <ProviderDbType>12</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Int64</DataType>
    <CreateFormat>long</CreateFormat>
    <IsAutoIncrementable>true</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>bigint</TypeName>
    <ProviderDbType>12</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Int64</DataType>
    <CreateFormat>bigint</CreateFormat>
    <IsAutoIncrementable>true</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>binary</TypeName>
    <ProviderDbType>1</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <DataType>System.Byte[]</DataType>
    <CreateFormat>binary</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>false</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>X'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>varbinary</TypeName>
    <ProviderDbType>1</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <DataType>System.Byte[]</DataType>
    <CreateFormat>varbinary</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>false</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>X'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>blob</TypeName>
    <ProviderDbType>1</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <DataType>System.Byte[]</DataType>
    <CreateFormat>blob</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>false</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>X'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>image</TypeName>
    <ProviderDbType>1</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <DataType>System.Byte[]</DataType>
    <CreateFormat>image</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>false</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>X'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>general</TypeName>
    <ProviderDbType>1</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <DataType>System.Byte[]</DataType>
    <CreateFormat>general</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>false</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>X'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>oleobject</TypeName>
    <ProviderDbType>1</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <DataType>System.Byte[]</DataType>
    <CreateFormat>oleobject</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>false</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>X'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>varchar</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>varchar({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>nvarchar</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>nvarchar({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>memo</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>memo({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>longtext</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>longtext({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>note</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>note({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>text</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>text({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>ntext</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>ntext({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>string</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>string({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>char</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>char({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>nchar</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <CreateFormat>char({0})</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>datetime</TypeName>
    <ProviderDbType>6</ProviderDbType>
    <ColumnSize>23</ColumnSize>
    <DataType>System.DateTime</DataType>
    <CreateFormat>datetime</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>smalldate</TypeName>
    <ProviderDbType>6</ProviderDbType>
    <ColumnSize>23</ColumnSize>
    <DataType>System.DateTime</DataType>
    <CreateFormat>smalldate</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>timestamp</TypeName>
    <ProviderDbType>6</ProviderDbType>
    <ColumnSize>23</ColumnSize>
    <DataType>System.DateTime</DataType>
    <CreateFormat>timestamp</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>date</TypeName>
    <ProviderDbType>6</ProviderDbType>
    <ColumnSize>23</ColumnSize>
    <DataType>System.DateTime</DataType>
    <CreateFormat>date</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>time</TypeName>
    <ProviderDbType>6</ProviderDbType>
    <ColumnSize>23</ColumnSize>
    <DataType>System.DateTime</DataType>
    <CreateFormat>time</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>uniqueidentifier</TypeName>
    <ProviderDbType>4</ProviderDbType>
    <ColumnSize>16</ColumnSize>
    <DataType>System.Guid</DataType>
    <CreateFormat>uniqueidentifier</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>true</IsBestMatch>
  </DataTypes>
  <DataTypes>
    <TypeName>guid</TypeName>
    <ProviderDbType>4</ProviderDbType>
    <ColumnSize>16</ColumnSize>
    <DataType>System.Guid</DataType>
    <CreateFormat>guid</CreateFormat>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
    <IsBestMatch>false</IsBestMatch>
  </DataTypes>
</DocumentElement>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite/LINQ/SQLiteConnection_Linq.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

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

  public sealed partial class SQLiteConnection
  {
    /// <summary>
    /// Returns a SQLiteProviderFactory object.
    /// </summary>
    protected override DbProviderFactory DbProviderFactory
    {
      get { return SQLiteFactory.Instance; }
    }
  }
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































Deleted System.Data.SQLite/LINQ/SQLiteFactory_Linq.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Reflection;
  using System.Security.Permissions;

  /// <summary>
  /// SQLite implementation of DbProviderFactory.
  /// </summary>
  public sealed partial class SQLiteFactory : IServiceProvider
  {
    private static Type _dbProviderServicesType;
    private static object _sqliteServices;

    static SQLiteFactory()
    {
#if !PLATFORM_COMPACTFRAMEWORK
        SQLiteLog.Initialize();
#endif

        string version =
#if NET_20
            "3.5.0.0";
#else
            "4.0.0.0";
#endif

        _dbProviderServicesType = Type.GetType(String.Format("System.Data.Common.DbProviderServices, System.Data.Entity, Version={0}, Culture=neutral, PublicKeyToken=b77a5c561934e089", version), false);
    }

    /// <summary>
    /// Will provide a DbProviderServices object in .NET 3.5
    /// </summary>
    /// <param name="serviceType">The class or interface type to query for</param>
    /// <returns></returns>
    object IServiceProvider.GetService(Type serviceType)
    {
      if (serviceType == typeof(ISQLiteSchemaExtensions) ||
        (_dbProviderServicesType != null && serviceType == _dbProviderServicesType))
      {
        return GetSQLiteProviderServicesInstance();
      }
      return null;
    }

    [ReflectionPermission(SecurityAction.Assert, MemberAccess = true)]
    private object GetSQLiteProviderServicesInstance()
    {
        if (_sqliteServices == null)
        {
            Version version = this.GetType().Assembly.GetName().Version;
            Type type = Type.GetType(String.Format("System.Data.SQLite.SQLiteProviderServices, System.Data.SQLite.Linq, Version={0}, Culture=neutral, PublicKeyToken=db937bc2d44ff139", version), false);

            if (type != null)
            {
                FieldInfo field = type.GetField("Instance", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
                _sqliteServices = field.GetValue(null);
            }
        }
        return _sqliteServices;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































Deleted System.Data.SQLite/MetaDataCollections.xml.
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
<?xml version="1.0" encoding="utf-8" ?>

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<DocumentElement>
  <MetaDataCollections>
    <CollectionName>MetaDataCollections</CollectionName>
    <NumberOfRestrictions>0</NumberOfRestrictions>
    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>DataSourceInformation</CollectionName>
    <NumberOfRestrictions>0</NumberOfRestrictions>
    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>DataTypes</CollectionName>
    <NumberOfRestrictions>0</NumberOfRestrictions>
    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>ReservedWords</CollectionName>
    <NumberOfRestrictions>0</NumberOfRestrictions>
    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Catalogs</CollectionName>
    <NumberOfRestrictions>1</NumberOfRestrictions>
    <NumberOfIdentifierParts>1</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Columns</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Indexes</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>IndexColumns</CollectionName>
    <NumberOfRestrictions>5</NumberOfRestrictions>
    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Tables</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Views</CollectionName>
    <NumberOfRestrictions>3</NumberOfRestrictions>
    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>ViewColumns</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>ForeignKeys</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Triggers</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIndentifierParts>3</NumberOfIndentifierParts>
  </MetaDataCollections>
</DocumentElement>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































Changes to System.Data.SQLite/SQLite3.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
#if DEBUG
  using System.Diagnostics;
#endif
  using System.Runtime.InteropServices;

#if !PLATFORM_COMPACTFRAMEWORK
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
  internal delegate void SQLiteLogCallback(IntPtr puser, int err_code, IntPtr message);

  /// <summary>
  /// This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET
  /// </summary>
  internal class SQLite3 : SQLiteBase
  {
    //
    // NOTE: This is the public key for the System.Data.SQLite assembly.  If you change the
    //       SNK file, you will need to change this as well.
    //
    internal const string PublicKey =
        "002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1" +
        "b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0" +
        "a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421" +
        "d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c";

#if !PLATFORM_COMPACTFRAMEWORK
    internal const string DesignerVersion = "1.0.77.0";
#endif

    /// <summary>
    /// The opaque pointer returned to us by the sqlite provider
    /// </summary>
    protected SQLiteConnectionHandle _sql;
    protected string _fileName;
    protected bool _usePool;
    protected int _poolVersion;

#if !PLATFORM_COMPACTFRAMEWORK
    private bool _buildingSchema;
#endif
    /// <summary>
    /// The user-defined functions registered on this connection
    /// </summary>
    protected SQLiteFunction[] _functionsArray;

    internal SQLite3(SQLiteDateFormats fmt, DateTimeKind kind)
      : base(fmt, kind)
    {
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLite3).Name);
#endif
    }

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

    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                //if (disposing)
                //{
                //    ////////////////////////////////////
                //    // dispose managed resources here...
                //    ////////////////////////////////////
                //}

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

                Close();

                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
    #endregion

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

    // It isn't necessary to cleanup any functions we've registered.  If the connection
    // goes to the pool and is resurrected later, re-registered functions will overwrite the
    // previous functions.  The SQLiteFunctionCookieHandle will take care of freeing unmanaged
    // resources belonging to the previously-registered functions.
    internal override void Close()
    {
      if (_sql != null)
      {
          if (_usePool)
          {
              SQLiteBase.ResetConnection(_sql);
              SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion);
          }
          else
          {
              _sql.Dispose();
          }
          _sql = null;
      }
    }

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

    internal override void Cancel()
    {
      UnsafeNativeMethods.sqlite3_interrupt(_sql);
    }

    internal override string Version
    {
      get
      {
        return SQLite3.SQLiteVersion;
      }
    }

    internal static string SQLiteVersion
    {
      get
      {
        return UTF8ToString(UnsafeNativeMethods.sqlite3_libversion(), -1);
      }
    }

    internal static string SQLiteSourceId
    {
      get
      {
        return UTF8ToString(UnsafeNativeMethods.sqlite3_sourceid(), -1);
      }
    }

    internal override bool AutoCommit
    {
      get
      {
        return IsAutocommit(_sql);
      }
    }

    internal override long LastInsertRowId
    {
      get
      {
        return UnsafeNativeMethods.sqlite3_last_insert_rowid(_sql);
      }
    }

    internal override int Changes
    {
      get
      {
        return UnsafeNativeMethods.sqlite3_changes(_sql);
      }
    }

    internal override long MemoryUsed
    {
      get
      {
        return UnsafeNativeMethods.sqlite3_memory_used();
      }
    }

    internal override long MemoryHighwater
    {
      get
      {
        return UnsafeNativeMethods.sqlite3_memory_highwater(0);
      }
    }

    /// <summary>
    /// Shutdown the SQLite engine so that it can be restarted with different config options.
    /// We depend on auto initialization to recover.
    /// </summary>
    /// <returns>Returns a result code</returns>
    internal override int Shutdown()
    {
        int rc = UnsafeNativeMethods.sqlite3_shutdown();
        return rc;
    }

    internal override bool IsOpen()
    {
        return (_sql != null);
    }

    internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool)
    {
      if (_sql != null) return;

      _usePool = usePool;
      if (usePool)
      {
        _fileName = strFilename;
        _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);
      }

      if (_sql == null)
      {
        IntPtr db;

#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), (int)flags, out db);
#else
        int n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, IntPtr.Zero);
#endif

#if DEBUG
        Trace.WriteLine(String.Format("Open: {0}", db));
#endif

        if (n > 0) throw new SQLiteException(n, null);

        _sql = db;
      }
      // Bind functions to this connection.  If any previous functions of the same name
      // were already bound, then the new bindings replace the old.
      _functionsArray = SQLiteFunction.BindFunctions(this);
      SetTimeout(0);
    }

    internal override void ClearPool()
    {
      SQLiteConnectionPool.ClearPool(_fileName);
    }

    internal override void SetTimeout(int nTimeoutMS)
    {
      int n = UnsafeNativeMethods.sqlite3_busy_timeout(_sql, nTimeoutMS);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }
















    internal override bool Step(SQLiteStatement stmt)
    {
      int n;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;
      uint timeout = (uint)(stmt._command._commandTimeout * 1000);

      while (true)
      {
        n = UnsafeNativeMethods.sqlite3_step(stmt._sqlite_stmt);

        if (n == 100) return true;
        if (n == 101) return false;

        if (n > 0)
        {
          int r;

          // An error occurred, attempt to reset the statement.  If the reset worked because the
          // schema has changed, re-try the step again.  If it errored our because the database
          // is locked, then keep retrying until the command timeout occurs.
          r = Reset(stmt);

          if (r == 0)
            throw new SQLiteException(n, SQLiteLastError());

          else if ((r == 6 || r == 5) && stmt._command != null) // SQLITE_LOCKED || SQLITE_BUSY


          {
            // Keep trying
            if (rnd == null) // First time we've encountered the lock
              rnd = new Random();


            // If we've exceeded the command's timeout, give up and throw an error
            if ((uint)Environment.TickCount - starttick > timeout)
            {

              throw new SQLiteException(r, SQLiteLastError());
            }
            else
            {
              // Otherwise sleep for a random amount of time up to 150ms
              System.Threading.Thread.Sleep(rnd.Next(1, 150));

            }
          }
        }
      }
    }

    internal override int Reset(SQLiteStatement stmt)
    {
      int n;

#if !SQLITE_STANDARD
      n = UnsafeNativeMethods.sqlite3_reset_interop(stmt._sqlite_stmt);
#else
      n = UnsafeNativeMethods.sqlite3_reset(stmt._sqlite_stmt);
#endif

      // If the schema changed, try and re-prepare it
      if (n == 17) // SQLITE_SCHEMA
      {
        // Recreate a dummy statement

        string str;
        using (SQLiteStatement tmp = Prepare(null, stmt._sqlStatement, null, (uint)(stmt._command._commandTimeout * 1000), out str))
        {
          // Finalize the existing statement

          stmt._sqlite_stmt.Dispose();
          // Reassign a new statement pointer to the old statement and clear the temporary one
          stmt._sqlite_stmt = tmp._sqlite_stmt;
          tmp._sqlite_stmt = null;

          // Reapply parameters
          stmt.BindParameters();
        }
        return -1; // Reset was OK, with schema change
      }
      else if (n == 6 || n == 5) // SQLITE_LOCKED || SQLITE_BUSY
        return n;

      if (n > 0)
        throw new SQLiteException(n, SQLiteLastError());

      return 0; // We reset OK, no schema changes
    }

    internal override string SQLiteLastError()
    {
      return SQLiteBase.SQLiteLastError(_sql);
    }

    internal override SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain)
    {
      if (!String.IsNullOrEmpty(strSql))
      {
        //
        // NOTE: SQLite does not support the concept of separate schemas
        //       in one database; therefore, remove the base schema name
        //       used to smooth integration with the base .NET Framework
        //       data classes.
        //
        string baseSchemaName = (cnn != null) ? cnn._baseSchemaName : null;

        if (!String.IsNullOrEmpty(baseSchemaName))
        {
          strSql = strSql.Replace(
              String.Format("[{0}].", baseSchemaName), String.Empty);

          strSql = strSql.Replace(
              String.Format("{0}.", baseSchemaName), String.Empty);
        }
      }

      IntPtr stmt = IntPtr.Zero;
      IntPtr ptr = IntPtr.Zero;
      int len = 0;
      int n = 17;
      int retries = 0;
      byte[] b = ToUTF8(strSql);
      string typedefs = null;
      SQLiteStatement cmd = null;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;

      GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned);
      IntPtr psql = handle.AddrOfPinnedObject();
      try
      {
        while ((n == 17 || n == 6 || n == 5) && retries < 3)
        {
#if !SQLITE_STANDARD
          n = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, psql, b.Length - 1, out stmt, out ptr, out len);
#else
          n = UnsafeNativeMethods.sqlite3_prepare(_sql, psql, b.Length - 1, out stmt, out ptr);
          len = -1;
#endif

#if DEBUG
          Trace.WriteLine(String.Format("Prepare: {0}", stmt));
#endif

          if (n == 17)
            retries++;
          else if (n == 1)
          {
            if (String.Compare(SQLiteLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0)
            {
              int pos = strSql.IndexOf(';');
              if (pos == -1) pos = strSql.Length - 1;

              typedefs = strSql.Substring(0, pos + 1);
              strSql = strSql.Substring(pos + 1);

              strRemain = "";

              while (cmd == null && strSql.Length > 0)
              {
                cmd = Prepare(cnn, strSql, previous, timeoutMS, out strRemain);
                strSql = strRemain;
              }

              if (cmd != null)
                cmd.SetTypes(typedefs);

              return cmd;
            }
#if !PLATFORM_COMPACTFRAMEWORK
            else if (_buildingSchema == false && String.Compare(SQLiteLastError(), 0, "no such table: TEMP.SCHEMA", 0, 26, StringComparison.OrdinalIgnoreCase) == 0)
            {
              strRemain = "";
              _buildingSchema = true;
              try
              {
                ISQLiteSchemaExtensions ext = ((IServiceProvider)SQLiteFactory.Instance).GetService(typeof(ISQLiteSchemaExtensions)) as ISQLiteSchemaExtensions;

                if (ext != null)
                  ext.BuildTempSchema(cnn);

                while (cmd == null && strSql.Length > 0)
                {
                  cmd = Prepare(cnn, strSql, previous, timeoutMS, out strRemain);
                  strSql = strRemain;
                }

                return cmd;
              }
              finally
              {
                _buildingSchema = false;
              }
            }
#endif
          }
          else if (n == 6 || n == 5) // Locked -- delay a small amount before retrying
          {
            // Keep trying
            if (rnd == null) // First time we've encountered the lock
              rnd = new Random();

            // If we've exceeded the command's timeout, give up and throw an error
            if ((uint)Environment.TickCount - starttick > timeoutMS)
            {
              throw new SQLiteException(n, SQLiteLastError());
            }
            else
            {
              // Otherwise sleep for a random amount of time up to 150ms
              System.Threading.Thread.Sleep(rnd.Next(1, 150));
            }
          }
        }

        if (n > 0) throw new SQLiteException(n, SQLiteLastError());

        strRemain = UTF8ToString(ptr, len);

        if (stmt != IntPtr.Zero) cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), previous);

        return cmd;
      }
      finally
      {
        handle.Free();
      }
    }

    internal override void Bind_Double(SQLiteStatement stmt, int index, double value)
    {
#if !PLATFORM_COMPACTFRAMEWORK
      int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value);
#else
      int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value);
#endif
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_Int32(SQLiteStatement stmt, int index, int value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_int(stmt._sqlite_stmt, index, value);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_UInt32(SQLiteStatement stmt, int index, uint value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_uint(stmt._sqlite_stmt, index, value);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_Int64(SQLiteStatement stmt, int index, long value)
    {
#if !PLATFORM_COMPACTFRAMEWORK
      int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value);
#else
      int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value);
#endif
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_UInt64(SQLiteStatement stmt, int index, ulong value)
    {
#if !PLATFORM_COMPACTFRAMEWORK
      int n = UnsafeNativeMethods.sqlite3_bind_uint64(stmt._sqlite_stmt, index, value);
#else
      int n = UnsafeNativeMethods.sqlite3_bind_uint64_interop(stmt._sqlite_stmt, index, ref value);
#endif
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_Text(SQLiteStatement stmt, int index, string value)
    {
      byte[] b = ToUTF8(value);
      int n = UnsafeNativeMethods.sqlite3_bind_text(stmt._sqlite_stmt, index, b, b.Length - 1, (IntPtr)(-1));
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt)
    {
        switch (_datetimeFormat)
        {
            case SQLiteDateFormats.Ticks:
                {
                    long value = dt.Ticks;

#if !PLATFORM_COMPACTFRAMEWORK
                    int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value);
#else
                    int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value);
#endif
                    if (n > 0) throw new SQLiteException(n, SQLiteLastError());
                    break;
                }
            case SQLiteDateFormats.JulianDay:
                {
                    double value = ToJulianDay(dt);

#if !PLATFORM_COMPACTFRAMEWORK
                    int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value);
#else
                    int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value);
#endif
                    if (n > 0) throw new SQLiteException(n, SQLiteLastError());
                    break;
                }
            case SQLiteDateFormats.UnixEpoch:
                {
                    long value = Convert.ToInt64(dt.Subtract(UnixEpoch).TotalSeconds);

#if !PLATFORM_COMPACTFRAMEWORK
                    int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value);
#else
                    int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value);
#endif
                    if (n > 0) throw new SQLiteException(n, SQLiteLastError());
                    break;
                }
            default:
                {
                    byte[] b = ToUTF8(dt);
                    int n = UnsafeNativeMethods.sqlite3_bind_text(stmt._sqlite_stmt, index, b, b.Length - 1, (IntPtr)(-1));
                    if (n > 0) throw new SQLiteException(n, SQLiteLastError());
                    break;
                }
        }
    }

    internal override void Bind_Blob(SQLiteStatement stmt, int index, byte[] blobData)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_blob(stmt._sqlite_stmt, index, blobData, blobData.Length, (IntPtr)(-1));
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_Null(SQLiteStatement stmt, int index)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_null(stmt._sqlite_stmt, index);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override int Bind_ParamCount(SQLiteStatement stmt)
    {
      return UnsafeNativeMethods.sqlite3_bind_parameter_count(stmt._sqlite_stmt);
    }

    internal override string Bind_ParamName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override int Bind_ParamIndex(SQLiteStatement stmt, string paramName)
    {
      return UnsafeNativeMethods.sqlite3_bind_parameter_index(stmt._sqlite_stmt, ToUTF8(paramName));
    }

    internal override int ColumnCount(SQLiteStatement stmt)
    {
      return UnsafeNativeMethods.sqlite3_column_count(stmt._sqlite_stmt);
    }

    internal override string ColumnName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_name_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_name(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override TypeAffinity ColumnAffinity(SQLiteStatement stmt, int index)
    {
      return UnsafeNativeMethods.sqlite3_column_type(stmt._sqlite_stmt, index);
    }

    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)
    {


      int len;
#if !SQLITE_STANDARD
      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype_interop(stmt._sqlite_stmt, index, out len);
#else
      len = -1;
      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype(stmt._sqlite_stmt, index);
#endif
      nAffinity = ColumnAffinity(stmt, index);

      if (p != IntPtr.Zero) return UTF8ToString(p, len);
      else
      {
        string[] ar = stmt.TypeDefinitions;
        if (ar != null)
        {
          if (index < ar.Length && ar[index] != null)
            return ar[index];
        }
        return String.Empty;

        //switch (nAffinity)
        //{

        //  case TypeAffinity.Int64:
        //    return "BIGINT";
        //  case TypeAffinity.Double:
        //    return "DOUBLE";
        //  case TypeAffinity.Blob:
        //    return "BLOB";
        //  default:
        //    return "TEXT";
        //}

      }
    }

    internal override int ColumnIndex(SQLiteStatement stmt, string columnName)
    {
      int x = ColumnCount(stmt);

      for (int n = 0; n < x; n++)
      {
        if (String.Compare(columnName, ColumnName(stmt, n), StringComparison.OrdinalIgnoreCase) == 0)
          return n;
      }
      return -1;
    }

    internal override string ColumnOriginalName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_origin_name_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_origin_name(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override string ColumnDatabaseName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_database_name_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_database_name(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override string ColumnTableName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_table_name_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_table_name(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override void ColumnMetaData(string dataBase, string table, string column, out string dataType, out string collateSequence, out bool notNull, out bool primaryKey, out bool autoIncrement)
    {
      IntPtr dataTypePtr;
      IntPtr collSeqPtr;
      int nnotNull;
      int nprimaryKey;
      int nautoInc;
      int n;
      int dtLen;
      int csLen;

#if !SQLITE_STANDARD
      n = UnsafeNativeMethods.sqlite3_table_column_metadata_interop(_sql, ToUTF8(dataBase), ToUTF8(table), ToUTF8(column), out dataTypePtr, out collSeqPtr, out nnotNull, out nprimaryKey, out nautoInc, out dtLen, out csLen);
#else
      dtLen = -1;
      csLen = -1;

      n = UnsafeNativeMethods.sqlite3_table_column_metadata(_sql, ToUTF8(dataBase), ToUTF8(table), ToUTF8(column), out dataTypePtr, out collSeqPtr, out nnotNull, out nprimaryKey, out nautoInc);
#endif
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      dataType = UTF8ToString(dataTypePtr, dtLen);
      collateSequence = UTF8ToString(collSeqPtr, csLen);

      notNull = (nnotNull == 1);
      primaryKey = (nprimaryKey == 1);
      autoIncrement = (nautoInc == 1);
    }

    internal override double GetDouble(SQLiteStatement stmt, int index)
    {
      double value;
#if !PLATFORM_COMPACTFRAMEWORK
      value = UnsafeNativeMethods.sqlite3_column_double(stmt._sqlite_stmt, index);
#else
      UnsafeNativeMethods.sqlite3_column_double_interop(stmt._sqlite_stmt, index, out value);
#endif
      return value;
    }

    internal override int GetInt32(SQLiteStatement stmt, int index)
    {
      return UnsafeNativeMethods.sqlite3_column_int(stmt._sqlite_stmt, index);
    }

    internal override long GetInt64(SQLiteStatement stmt, int index)
    {
      long value;
#if !PLATFORM_COMPACTFRAMEWORK
      value = UnsafeNativeMethods.sqlite3_column_int64(stmt._sqlite_stmt, index);
#else
      UnsafeNativeMethods.sqlite3_column_int64_interop(stmt._sqlite_stmt, index, out value);
#endif
      return value;
    }

    internal override string GetText(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_text(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return ToDateTime(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return ToDateTime(UnsafeNativeMethods.sqlite3_column_text(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override long GetBytes(SQLiteStatement stmt, int index, int nDataOffset, byte[] bDest, int nStart, int nLength)
    {

      int nlen = UnsafeNativeMethods.sqlite3_column_bytes(stmt._sqlite_stmt, index);




      // If no destination buffer, return the size needed.
      if (bDest == null) return nlen;

      int nCopied = nLength;

      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;

      if (nCopied > 0)
      {
        IntPtr ptr = UnsafeNativeMethods.sqlite3_column_blob(stmt._sqlite_stmt, index);

        Marshal.Copy((IntPtr)(ptr.ToInt64() + nDataOffset), bDest, nStart, nCopied);
      }
      else
      {
        nCopied = 0;
      }

      return nCopied;
    }

    internal override long GetChars(SQLiteStatement stmt, int index, int nDataOffset, char[] bDest, int nStart, int nLength)
    {
      int nlen;










<
<
<

|
<
<
<
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
<
<
|

<
<
<





|
|

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


<
<
|

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


|

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

<
|
<
<
<
<
<
|
|
<
|



<
<
<
|
<
<
<
<
|







|



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

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

<
<
<
<

<
<
<
<
<
<




|


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




<
<
<



|






<
<

|
<
|
|
|
|
|
<
>
>
|
<
<
<
>
|
<
|
|
>
|
|
<
<
<
<
>
|
|
<
<
<
<
|

<
<
<
|
<
<
<





>

|


>
|


|




|

<
<




|




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

<
<
<
<

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

|

|

|
<
<
<
<
<




<
<
<

<





|
<
<
<
<
<
<





<
<
<

<
<
<
<
<
<
<
<
<
<
<






|





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


|





|





|




<

|
<
<
<




|




|




<

|
<
<
<
<
<
<
<
<




>
>

<

<
<
<
<
<
<
|


<
<
<
<
<
<
<
|
|
<
>
|
|
|
|
|
|
|
|
<
>





<
<
|

|
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
<
<

<





|





<
<
<

<





<

|
<
<
<




<


<
<
<




>
|
>

>
>
|

<
<





<
<
<
|
<
<
<
|
<







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

namespace System.Data.SQLite
{
  using System;



  using System.Runtime.InteropServices;
  using System.Collections.Generic;





  /// <summary>
  /// This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET
  /// </summary>
  internal class SQLite3 : SQLiteBase
  {














    /// <summary>
    /// The opaque pointer returned to us by the sqlite provider
    /// </summary>



    protected int              _sql;




    /// <summary>
    /// The user-defined functions registered on this connection
    /// </summary>
    protected SQLiteFunction[] _functionsArray;

    internal SQLite3(DateTimeFormat fmt)
      : base(fmt)
    {

      _sql = 0;

      _functionsArray = null;








    }



    protected override void Dispose(bool bDisposing)
    {















      Close();
    }
















    internal override void Close()
    {
      if (_sql != 0)
      {

















        int n = UnsafeNativeMethods.sqlite3_close_interop(_sql);

        if (n > 0) throw new SQLiteException(n, SQLiteLastError());







        SQLiteFunction.UnbindFunctions(this, _functionsArray);





      }

      _sql = 0;





    }


    internal override string Version
    {
      get
      {



        int len;




        return ToString(UnsafeNativeMethods.sqlite3_libversion_interop(out len), len);
      }
    }

    internal override int Changes
    {
      get
      {
        return UnsafeNativeMethods.sqlite3_changes_interop(_sql);
      }
    }

































    internal override void Open(string strFilename)
    {
      if (_sql != 0) return;













      int n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), out _sql);








      if (n > 0) throw new SQLiteException(n, SQLiteLastError());





      _functionsArray = SQLiteFunction.BindFunctions(this);






    }

    internal override void SetTimeout(int nTimeoutMS)
    {
      int n = UnsafeNativeMethods.sqlite3_busy_timeout_interop(_sql, nTimeoutMS);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Execute(string strSql)
    {
      IntPtr p;
      string str = strSql;
      int len;

      int n = UnsafeNativeMethods.sqlite3_exec_interop(_sql, ToUTF8(strSql), 0, 0, out p, out len);
      if (p != IntPtr.Zero)
      {
        str = ToString(p, len);
        UnsafeNativeMethods.sqlite3_free_interop(p);
      }
      if (n > 0) throw new SQLiteException(n, str);
    }

    internal override bool Step(SQLiteStatement stmt)
    {
      int n;




      while (true)
      {
        n = UnsafeNativeMethods.sqlite3_step_interop(stmt._sqlite_stmt);

        if (n == 100) return true;
        if (n == 101) return false;

        if (n > 0)
        {


          // An error occurred, attempt to reset the statement.  If the reset worked because the
          // schema has changed, re-try the step again.  Otherwise throw the original error.

          string str = SQLiteLastError();
          
          if (Reset(stmt) == false)
            throw new SQLiteException(n, str);
        }

      }
    }




    internal override void Finalize(SQLiteStatement stmt)
    {

      if (stmt._sqlite_stmt > 0)
      {
        int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt._sqlite_stmt);
        if (n > 0) throw new SQLiteException(n, SQLiteLastError());
      }




      stmt._sqlite_stmt = 0;
    }





    internal override bool Reset(SQLiteStatement stmt)
    {



      int n = UnsafeNativeMethods.sqlite3_reset_interop(stmt._sqlite_stmt);




      // If the schema changed, try and re-prepare it
      if (n == 17) // SQLITE_SCHEMA
      {
        // Recreate a dummy statement
        int nc = 0;
        string str;
        using (SQLiteStatement tmp = Prepare(stmt._sqlStatement, ref nc, out str))
        {
          // Finalize the existing statement
          Finalize(stmt);

          // Reassign a new statement pointer to the old statement and clear the temporary one
          stmt._sqlite_stmt = tmp._sqlite_stmt;
          tmp._sqlite_stmt = 0;

          // Reapply parameters
          stmt.BindParameters();
        }
        return true; // Reset was OK, with schema change
      }



      if (n > 0)
        throw new SQLiteException(n, SQLiteLastError());

      return false; // We reset OK, no schema changes
    }

    internal override string SQLiteLastError()
    {


      int len;


      return ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(_sql, out len), len);








    }




    internal override SQLiteStatement Prepare(string strSql, ref int nParamStart, out string strRemain)




    {
      int stmt;
      IntPtr ptr;
      int len;


      byte[] b = ToUTF8(strSql);












      int n = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, b, b.Length - 1, out stmt, out ptr, out len);
















































































      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      strRemain = ToString(ptr, len);

      SQLiteStatement cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), ref nParamStart);

      return cmd;





    }

    internal override void Bind_Double(SQLiteStatement stmt, int index, double value)
    {



      int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value);

      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_Int32(SQLiteStatement stmt, int index, int value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_int_interop(stmt._sqlite_stmt, index, value);






      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_Int64(SQLiteStatement stmt, int index, long value)
    {



      int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value);











      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_Text(SQLiteStatement stmt, int index, string value)
    {
      byte[] b = ToUTF8(value);
      int n = UnsafeNativeMethods.sqlite3_bind_text_interop(stmt._sqlite_stmt, index, b, b.Length - 1, -1);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt)
    {








































      byte[] b = ToUTF8(dt);
      int n = UnsafeNativeMethods.sqlite3_bind_text_interop(stmt._sqlite_stmt, index, b, b.Length - 1, -1);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

    }



    internal override void Bind_Blob(SQLiteStatement stmt, int index, byte[] blobData)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_blob_interop(stmt._sqlite_stmt, index, blobData, blobData.Length, -1);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void Bind_Null(SQLiteStatement stmt, int index)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_null_interop(stmt._sqlite_stmt, index);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override int Bind_ParamCount(SQLiteStatement stmt)
    {
      return UnsafeNativeMethods.sqlite3_bind_parameter_count_interop(stmt._sqlite_stmt);
    }

    internal override string Bind_ParamName(SQLiteStatement stmt, int index)
    {

      int len;
      return ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name_interop(stmt._sqlite_stmt, index, out len), len);



    }

    internal override int Bind_ParamIndex(SQLiteStatement stmt, string paramName)
    {
      return UnsafeNativeMethods.sqlite3_bind_parameter_index_interop(stmt._sqlite_stmt, ToUTF8(paramName));
    }

    internal override int ColumnCount(SQLiteStatement stmt)
    {
      return UnsafeNativeMethods.sqlite3_column_count_interop(stmt._sqlite_stmt);
    }

    internal override string ColumnName(SQLiteStatement stmt, int index)
    {

      int len;
      return ToString(UnsafeNativeMethods.sqlite3_column_name_interop(stmt._sqlite_stmt, index, out len), len);








    }

    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)
    {
      nAffinity = TypeAffinity.None;

      int len;

      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype_interop(stmt._sqlite_stmt, index, out len);






      if (p != IntPtr.Zero) return ToString(p, len);
      else
      {







        nAffinity = UnsafeNativeMethods.sqlite3_column_type_interop(stmt._sqlite_stmt, index);
        switch (nAffinity)

        {
          case TypeAffinity.Int64:
            return "BIGINT";
          case TypeAffinity.Double:
            return "DOUBLE";
          case TypeAffinity.Blob:
            return "BLOB";
          default:
            return "TEXT";

        }
      }
    }

    internal override int ColumnIndex(SQLiteStatement stmt, string columnName)
    {


      for (int n = 0; n < ColumnCount(stmt); n++)
      {
        if (String.Compare(columnName, ColumnName(stmt, n), true) == 0) return n;

      }
      return -1;
    }




























































    internal override double GetDouble(SQLiteStatement stmt, int index)
    {
      double value;



      UnsafeNativeMethods.sqlite3_column_double_interop(stmt._sqlite_stmt, index, out value);

      return value;
    }

    internal override int GetInt32(SQLiteStatement stmt, int index)
    {
      return UnsafeNativeMethods.sqlite3_column_int_interop(stmt._sqlite_stmt, index);
    }

    internal override long GetInt64(SQLiteStatement stmt, int index)
    {
      long value;



      UnsafeNativeMethods.sqlite3_column_int64_interop(stmt._sqlite_stmt, index, out value);

      return value;
    }

    internal override string GetText(SQLiteStatement stmt, int index)
    {

      int len;
      return ToString(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, out len), len);



    }

    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
    {

      int len;
      return ToDateTime(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, out len), len);



    }

    internal override long GetBytes(SQLiteStatement stmt, int index, int nDataOffset, byte[] bDest, int nStart, int nLength)
    {
      IntPtr ptr;
      int nlen;
      int nCopied = nLength;

      nlen = UnsafeNativeMethods.sqlite3_column_bytes_interop(stmt._sqlite_stmt, index);
      ptr = UnsafeNativeMethods.sqlite3_column_blob_interop(stmt._sqlite_stmt, index);

      if (bDest == null) return nlen;



      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;

      if (nCopied > 0)



        Marshal.Copy((IntPtr)(ptr.ToInt32() + nDataOffset), bDest, nStart, nCopied);



      else nCopied = 0;


      return nCopied;
    }

    internal override long GetChars(SQLiteStatement stmt, int index, int nDataOffset, char[] bDest, int nStart, int nLength)
    {
      int nlen;
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
      else nCopied = 0;

      return nCopied;
    }

    internal override bool IsNull(SQLiteStatement stmt, int index)
    {
      return (ColumnAffinity(stmt, index) == TypeAffinity.Null);
    }

    internal override int AggregateCount(IntPtr context)
    {
      return UnsafeNativeMethods.sqlite3_aggregate_count(context);
    }

    internal override void CreateFunction(string strFunction, int nArgs, bool needCollSeq, SQLiteCallback func, SQLiteCallback funcstep, SQLiteFinalCallback funcfinal)
    {
      int n;

#if !SQLITE_STANDARD
      n = UnsafeNativeMethods.sqlite3_create_function_interop(_sql, ToUTF8(strFunction), nArgs, 4, IntPtr.Zero, func, funcstep, funcfinal, (needCollSeq == true) ? 1 : 0);
      if (n == 0) n = UnsafeNativeMethods.sqlite3_create_function_interop(_sql, ToUTF8(strFunction), nArgs, 1, IntPtr.Zero, func, funcstep, funcfinal, (needCollSeq == true) ? 1 : 0);
#else
      n = UnsafeNativeMethods.sqlite3_create_function(_sql, ToUTF8(strFunction), nArgs, 4, IntPtr.Zero, func, funcstep, funcfinal);
      if (n == 0) n = UnsafeNativeMethods.sqlite3_create_function(_sql, ToUTF8(strFunction), nArgs, 1, IntPtr.Zero, func, funcstep, funcfinal);
#endif
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void CreateCollation(string strCollation, SQLiteCollation func, SQLiteCollation func16)
    {
      int n = UnsafeNativeMethods.sqlite3_create_collation(_sql, ToUTF8(strCollation), 2, IntPtr.Zero, func16);
      if (n == 0) n = UnsafeNativeMethods.sqlite3_create_collation(_sql, ToUTF8(strCollation), 1, IntPtr.Zero, func);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, string s1, string s2)
    {
#if !SQLITE_STANDARD
      byte[] b1;
      byte[] b2;
      System.Text.Encoding converter = null;

      switch (enc)
      {
        case CollationEncodingEnum.UTF8:
          converter = System.Text.Encoding.UTF8;
          break;
        case CollationEncodingEnum.UTF16LE:
          converter = System.Text.Encoding.Unicode;
          break;
        case CollationEncodingEnum.UTF16BE:
          converter = System.Text.Encoding.BigEndianUnicode;
          break;
      }

      b1 = converter.GetBytes(s1);
      b2 = converter.GetBytes(s2);

      return UnsafeNativeMethods.sqlite3_context_collcompare(context, b1, b1.Length, b2, b2.Length);
#else
      throw new NotImplementedException();
#endif
    }

    internal override int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, char[] c1, char[] c2)
    {
#if !SQLITE_STANDARD
      byte[] b1;
      byte[] b2;
      System.Text.Encoding converter = null;

      switch (enc)
      {
        case CollationEncodingEnum.UTF8:
          converter = System.Text.Encoding.UTF8;
          break;
        case CollationEncodingEnum.UTF16LE:
          converter = System.Text.Encoding.Unicode;
          break;
        case CollationEncodingEnum.UTF16BE:
          converter = System.Text.Encoding.BigEndianUnicode;
          break;
      }

      b1 = converter.GetBytes(c1);
      b2 = converter.GetBytes(c2);


      return UnsafeNativeMethods.sqlite3_context_collcompare(context, b1, b1.Length, b2, b2.Length);
#else
      throw new NotImplementedException();
#endif
    }

    internal override CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context)
    {
#if !SQLITE_STANDARD
      CollationSequence seq = new CollationSequence();
      int len;
      int type;
      int enc;
      IntPtr p = UnsafeNativeMethods.sqlite3_context_collseq(context, out type, out enc, out len);

      if (p != null) seq.Name = UTF8ToString(p, len);
      seq.Type = (CollationTypeEnum)type;
      seq._func = func;
      seq.Encoding = (CollationEncodingEnum)enc;

      return seq;
#else
      throw new NotImplementedException();
#endif
    }

    internal override long GetParamValueBytes(IntPtr p, int nDataOffset, byte[] bDest, int nStart, int nLength)
    {
      int nlen = UnsafeNativeMethods.sqlite3_value_bytes(p);

      // If no destination buffer, return the size needed.
      if (bDest == null) return nlen;

      int nCopied = nLength;

      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;

      if (nCopied > 0)
      {
        IntPtr ptr = UnsafeNativeMethods.sqlite3_value_blob(p);

        Marshal.Copy((IntPtr)(ptr.ToInt64() + nDataOffset), bDest, nStart, nCopied);
      }
      else
      {
        nCopied = 0;
      }

      return nCopied;
    }

    internal override double GetParamValueDouble(IntPtr ptr)
    {
      double value;
#if !PLATFORM_COMPACTFRAMEWORK
      value = UnsafeNativeMethods.sqlite3_value_double(ptr);
#else
      UnsafeNativeMethods.sqlite3_value_double_interop(ptr, out value);
#endif
      return value;
    }

    internal override int GetParamValueInt32(IntPtr ptr)
    {
      return UnsafeNativeMethods.sqlite3_value_int(ptr);
    }

    internal override long GetParamValueInt64(IntPtr ptr)
    {
      Int64 value;
#if !PLATFORM_COMPACTFRAMEWORK
      value = UnsafeNativeMethods.sqlite3_value_int64(ptr);
#else
      UnsafeNativeMethods.sqlite3_value_int64_interop(ptr, out value);
#endif
      return value;
    }

    internal override string GetParamValueText(IntPtr ptr)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_value_text_interop(ptr, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_value_text(ptr), -1);
#endif
    }

    internal override TypeAffinity GetParamValueType(IntPtr ptr)
    {
      return UnsafeNativeMethods.sqlite3_value_type(ptr);
    }

    internal override void ReturnBlob(IntPtr context, byte[] value)
    {
      UnsafeNativeMethods.sqlite3_result_blob(context, value, value.Length, (IntPtr)(-1));
    }

    internal override void ReturnDouble(IntPtr context, double value)
    {
#if !PLATFORM_COMPACTFRAMEWORK
      UnsafeNativeMethods.sqlite3_result_double(context, value);
#else
      UnsafeNativeMethods.sqlite3_result_double_interop(context, ref value);
#endif
    }

    internal override void ReturnError(IntPtr context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_error(context, ToUTF8(value), value.Length);
    }

    internal override void ReturnInt32(IntPtr context, int value)
    {
      UnsafeNativeMethods.sqlite3_result_int(context, value);
    }

    internal override void ReturnInt64(IntPtr context, long value)
    {
#if !PLATFORM_COMPACTFRAMEWORK
      UnsafeNativeMethods.sqlite3_result_int64(context, value);
#else
      UnsafeNativeMethods.sqlite3_result_int64_interop(context, ref value);
#endif
    }

    internal override void ReturnNull(IntPtr context)
    {
      UnsafeNativeMethods.sqlite3_result_null(context);
    }

    internal override void ReturnText(IntPtr context, string value)
    {
      byte[] b = ToUTF8(value);
      UnsafeNativeMethods.sqlite3_result_text(context, ToUTF8(value), b.Length - 1, (IntPtr)(-1));
    }

    internal override IntPtr AggregateContext(IntPtr context)
    {
      return UnsafeNativeMethods.sqlite3_aggregate_context(context, 1);
    }

    /// Enables or disabled extended result codes returned by SQLite
    internal override void SetExtendedResultCodes(bool bOnOff)
    {
      UnsafeNativeMethods.sqlite3_extended_result_codes(_sql, (bOnOff ? -1 : 0));
    }
    /// Gets the last SQLite error code
    internal override int ResultCode()
    {
      return UnsafeNativeMethods.sqlite3_errcode(_sql);
    }
    /// Gets the last SQLite extended error code
    internal override int ExtendedResultCode()
    {
      return UnsafeNativeMethods.sqlite3_extended_errcode(_sql);
    }

    /// Add a log message via the SQLite sqlite3_log interface.
    internal override void LogMessage(int iErrCode, string zMessage)
    {
      UnsafeNativeMethods.sqlite3_log(iErrCode, ToUTF8(zMessage));
    }

    internal override void SetPassword(byte[] passwordBytes)
    {
      int n = UnsafeNativeMethods.sqlite3_key(_sql, passwordBytes, passwordBytes.Length);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void ChangePassword(byte[] newPasswordBytes)
    {
      int n = UnsafeNativeMethods.sqlite3_rekey(_sql, newPasswordBytes, (newPasswordBytes == null) ? 0 : newPasswordBytes.Length);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void SetUpdateHook(SQLiteUpdateCallback func)
    {
      UnsafeNativeMethods.sqlite3_update_hook(_sql, func, IntPtr.Zero);
    }

    internal override void SetCommitHook(SQLiteCommitCallback func)
    {
      UnsafeNativeMethods.sqlite3_commit_hook(_sql, func, IntPtr.Zero);
    }

    internal override void SetTraceCallback(SQLiteTraceCallback func)
    {
      UnsafeNativeMethods.sqlite3_trace(_sql, func, IntPtr.Zero);
    }

    internal override void SetRollbackHook(SQLiteRollbackCallback func)
    {
      UnsafeNativeMethods.sqlite3_rollback_hook(_sql, func, IntPtr.Zero);
    }

    /// <summary>
    /// Allows the setting of a logging callback invoked by SQLite when a
    /// log event occurs.  Only one callback may be set.  If NULL is passed,
    /// the logging callback is unregistered.
    /// </summary>
    /// <param name="func">The callback function to invoke.</param>
    /// <returns>Returns a result code</returns>
    internal override int SetLogCallback(SQLiteLogCallback func)
    {
        int rc = UnsafeNativeMethods.sqlite3_config(
            (int)SQLiteConfigOpsEnum.SQLITE_CONFIG_LOG, func, (IntPtr)0);

        return rc;
    }

    /// <summary>
    /// Determines if the SQLite core library has been initialized for the
    /// current process.
    /// </summary>
    /// <returns>
    /// A boolean indicating whether or not the SQLite core library has been
    /// initialized for the current process.
    /// </returns>
    internal override bool IsInitialized()
    {
        return StaticIsInitialized();

    }

    /// <summary>
    /// Determines if the SQLite core library has been initialized for the
    /// current process.
    /// </summary>
    /// <returns>
    /// A boolean indicating whether or not the SQLite core library has been
    /// initialized for the current process.
    /// </returns>
    internal static bool StaticIsInitialized()
    {
        //
        // NOTE: Save the state of the logging class and then restore it
        //       after we are done to avoid logging too many false errors.
        //
        bool savedEnabled = SQLiteLog.Enabled;
        SQLiteLog.Enabled = false;

        try

        {
            //
            // NOTE: This method [ab]uses the fact that SQLite will always
            //       return SQLITE_ERROR for any unknown configuration option
            //       *unless* the SQLite library has already been initialized.
            //       In that case it will always return SQLITE_MISUSE.
            //
            int rc = UnsafeNativeMethods.sqlite3_config(
                (int)SQLiteConfigOpsEnum.SQLITE_CONFIG_NONE, null, (IntPtr)0);

            return (rc == /* SQLITE_MISUSE */ 21);
        }
        finally
        {
            SQLiteLog.Enabled = savedEnabled;
        }
    }

    /// <summary>
    /// Helper function to retrieve a column of data from an active statement.
    /// </summary>
    /// <param name="stmt">The statement being step()'d through</param>
    /// <param name="index">The column index to retrieve</param>
    /// <param name="typ">The type of data contained in the column.  If Uninitialized, this function will retrieve the datatype information.</param>
    /// <returns>Returns the data in the column</returns>
    internal override object GetValue(SQLiteStatement stmt, int index, SQLiteType typ)
    {
      if (IsNull(stmt, index)) return DBNull.Value;
      TypeAffinity aff = typ.Affinity;
      Type t = null;


      if (typ.Type != DbType.Object)
      {
        t = SQLiteConvert.SQLiteTypeToType(typ);
        aff = TypeToAffinity(t);
      }

      switch (aff)
      {
        case TypeAffinity.Blob:
          if (typ.Type == DbType.Guid && typ.Affinity == TypeAffinity.Text)
            return new Guid(GetText(stmt, index));


          int n = (int)GetBytes(stmt, index, 0, null, 0, 0);
          byte[] b = new byte[n];
          GetBytes(stmt, index, 0, b, 0, n);

          if (typ.Type == DbType.Guid && n == 16)
            return new Guid(b);

          return b;
        case TypeAffinity.DateTime:
          return GetDateTime(stmt, index);
        case TypeAffinity.Double:
          if (t == null) return GetDouble(stmt, index);
          else
            return Convert.ChangeType(GetDouble(stmt, index), t, null);
        case TypeAffinity.Int64:
          if (t == null) return GetInt64(stmt, index);
          else
            return Convert.ChangeType(GetInt64(stmt, index), t, null);
        default:
          return GetText(stmt, index);

      }
    }

    internal override int GetCursorForTable(SQLiteStatement stmt, int db, int rootPage)
    {
#if !SQLITE_STANDARD
      return UnsafeNativeMethods.sqlite3_table_cursor(stmt._sqlite_stmt, db, rootPage);
#else
      return -1;
#endif
    }

    internal override long GetRowIdForCursor(SQLiteStatement stmt, int cursor)
    {
#if !SQLITE_STANDARD
      long rowid;
      int rc = UnsafeNativeMethods.sqlite3_cursor_rowid(stmt._sqlite_stmt, cursor, out rowid);
      if (rc == 0) return rowid;

      return 0;
#else
      return 0;
#endif
    }

    internal override void GetIndexColumnExtendedInfo(string database, string index, string column, out int sortMode, out int onError, out string collationSequence)
    {
#if !SQLITE_STANDARD
      IntPtr coll;
      int colllen;
      int rc;

      rc = UnsafeNativeMethods.sqlite3_index_column_info_interop(_sql, ToUTF8(database), ToUTF8(index), ToUTF8(column), out sortMode, out onError, out coll, out colllen);
      if (rc != 0) throw new SQLiteException(rc, "");

      collationSequence = UTF8ToString(coll, colllen);
#else
      sortMode = 0;
      onError = 2;
      collationSequence = "BINARY";
#endif
    }

    internal override int FileControl(string zDbName, int op, IntPtr pArg)
    {
      return UnsafeNativeMethods.sqlite3_file_control(_sql, (zDbName != null) ? ToUTF8(zDbName) : null, op, pArg);
    }
  }
}







|


|

|


|

|

<
<
|
<
<
<
<

|
|
<
<
<
<
<


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

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

<
<
>
|
|
<
<
<


|

<
<
|
<
|
<
|
<
<
<
<

<
<
<
<
<
|
<
<
|

<

<
<





<
<
<
|
<
<
<
|
<




|


<
<
<

<



|

|


|


<
<
<

<



|

<

|
<
<
<


|

|


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

|

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

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

<
>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
>
|
<
<
<
<
<
<
|
<
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<

<
<
<
>
|
<
<
<
<
|
|
<
|
<
<
<
>
|
<
<
<

<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
|
|
<

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

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



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
      else nCopied = 0;

      return nCopied;
    }

    internal override bool IsNull(SQLiteStatement stmt, int index)
    {
      return (UnsafeNativeMethods.sqlite3_column_type_interop(stmt._sqlite_stmt, index) == TypeAffinity.Null);
    }

    internal override int AggregateCount(int context)
    {
      return UnsafeNativeMethods.sqlite3_aggregate_count_interop(context);
    }

    internal override int CreateFunction(string strFunction, int nArgs, SQLiteCallback func, SQLiteCallback funcstep, SQLiteCallback funcfinal)
    {
      int nCookie;



      int n = UnsafeNativeMethods.sqlite3_create_function_interop(_sql, ToUTF8(strFunction), nArgs, 1, func, funcstep, funcfinal, out nCookie);




      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      return nCookie;





    }







    internal override int CreateCollation(string strCollation, SQLiteCollation func)

    {










      int nCookie;









      int n = UnsafeNativeMethods.sqlite3_create_collation_interop(_sql, ToUTF8(strCollation), 1, 0, func, out nCookie);





      if (n > 0) throw new SQLiteException(n, SQLiteLastError());




      return nCookie;






    }



    internal override void FreeFunction(int nCookie)
    {
      UnsafeNativeMethods.sqlite3_function_free_callbackcookie(nCookie);



    }

    internal override long GetParamValueBytes(int p, int nDataOffset, byte[] bDest, int nStart, int nLength)
    {


      IntPtr ptr;

      int nlen;

      int nCopied = nLength;










      nlen = UnsafeNativeMethods.sqlite3_value_bytes_interop(p);


      ptr = UnsafeNativeMethods.sqlite3_value_blob_interop(p);


      if (bDest == null) return nlen;



      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;

      if (nCopied > 0)



        Marshal.Copy((IntPtr)(ptr.ToInt32() + nDataOffset), bDest, nStart, nCopied);



      else nCopied = 0;


      return nCopied;
    }

    internal override double GetParamValueDouble(int ptr)
    {
      double value;



      UnsafeNativeMethods.sqlite3_value_double_interop(ptr, out value);

      return value;
    }

    internal override int GetParamValueInt32(int ptr)
    {
      return UnsafeNativeMethods.sqlite3_value_int_interop(ptr);
    }

    internal override long GetParamValueInt64(int ptr)
    {
      Int64 value;



      UnsafeNativeMethods.sqlite3_value_int64_interop(ptr, out value);

      return value;
    }

    internal override string GetParamValueText(int ptr)
    {

      int len;
      return ToString(UnsafeNativeMethods.sqlite3_value_text_interop(ptr, out len), len);



    }

    internal override TypeAffinity GetParamValueType(int ptr)
    {
      return UnsafeNativeMethods.sqlite3_value_type_interop(ptr);
    }


































    internal override void ReturnBlob(int context, byte[] value)
    {
      UnsafeNativeMethods.sqlite3_result_blob_interop(context, value, value.Length, -1);
    }









































































    internal override void ReturnDouble(int context, double value)
    {
      UnsafeNativeMethods.sqlite3_result_double_interop(context, ref value);

    }











    internal override void ReturnError(int context, string value)
    {

      UnsafeNativeMethods.sqlite3_result_error_interop(context, ToUTF8(value), value.Length);
    }



















    internal override void ReturnInt32(int context, int value)
    {






      UnsafeNativeMethods.sqlite3_result_int_interop(context, value);

    }







    internal override void ReturnInt64(int context, long value)








    {



      UnsafeNativeMethods.sqlite3_result_int64_interop(context, ref value);
    }





    internal override void ReturnNull(int context)

    {



      UnsafeNativeMethods.sqlite3_result_null_interop(context);
    }





    internal override void ReturnText(int context, string value)
    {













      UnsafeNativeMethods.sqlite3_result_text_interop(context, ToUTF8(value), value.Length, -1);
    }










    internal override int AggregateContext(int context)

    {


      return UnsafeNativeMethods.sqlite3_aggregate_context_interop(context, 1);

    }





    internal override void SetRealColNames(bool bOn)

    {




      UnsafeNativeMethods.sqlite3_realcolnames(_sql, Convert.ToInt32(bOn));














    }
  }
}
Changes to System.Data.SQLite/SQLite3_UTF16.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
#if DEBUG
  using System.Diagnostics;
#endif
  using System.Runtime.InteropServices;

  /// <summary>
  /// Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode)
  /// </summary>
  internal class SQLite3_UTF16 : SQLite3
  {
    internal SQLite3_UTF16(SQLiteDateFormats fmt, DateTimeKind kind)
      : base(fmt, kind)
    {
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLite3_UTF16).Name);
#endif
    }

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

    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                //if (disposing)
                //{
                //    ////////////////////////////////////
                //    // dispose managed resources here...
                //    ////////////////////////////////////
                //}

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

                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
    #endregion

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

    /// <summary>
    /// Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8
    /// </summary>
    /// <param name="b">A pointer to a UTF-16 string</param>
    /// <param name="nbytelen">The length (IN BYTES) of the string</param>
    /// <returns>A .NET string</returns>
    public override string ToString(IntPtr b, int nbytelen)
    {
      CheckDisposed();
      return UTF16ToString(b, nbytelen);
    }






    public static string UTF16ToString(IntPtr b, int nbytelen)
    {
      if (nbytelen == 0 || b == IntPtr.Zero) return "";

      if (nbytelen == -1)
        return Marshal.PtrToStringUni(b);
      else
        return Marshal.PtrToStringUni(b, nbytelen / 2);
    }

    internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool)
    {
      if (_sql != null) return;

      _usePool = usePool;
      if (usePool)
      {
        _fileName = strFilename;
        _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);
      }

      if (_sql == null)
      {
        IntPtr db;

#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), (int)flags, out db);
#else
        if ((flags & SQLiteOpenFlagsEnum.Create) == 0 && System.IO.File.Exists(strFilename) == false)
          throw new SQLiteException((int)SQLiteErrorCode.CantOpen, strFilename);

        int n = UnsafeNativeMethods.sqlite3_open16(strFilename, out db);
#endif

#if DEBUG
        Trace.WriteLine(String.Format("Open: {0}", db));
#endif

        if (n > 0) throw new SQLiteException(n, null);

        _sql = db;
      }
      _functionsArray = SQLiteFunction.BindFunctions(this);
    }

    internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt)
    {
        switch (_datetimeFormat)
        {
            case SQLiteDateFormats.Ticks:
                {
                    long value = dt.Ticks;

#if !PLATFORM_COMPACTFRAMEWORK
                    int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value);
#else
                    int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value);
#endif
                    if (n > 0) throw new SQLiteException(n, SQLiteLastError());
                    break;
                }
            case SQLiteDateFormats.JulianDay:
                {
                    double value = ToJulianDay(dt);



#if !PLATFORM_COMPACTFRAMEWORK
                    int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value);
#else
                    int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value);
#endif
                    if (n > 0) throw new SQLiteException(n, SQLiteLastError());
                    break;
                }
            case SQLiteDateFormats.UnixEpoch:

                {
                    long value = Convert.ToInt64(dt.Subtract(UnixEpoch).TotalSeconds);


#if !PLATFORM_COMPACTFRAMEWORK
                    int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value);
#else
                    int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value);
#endif
                    if (n > 0) throw new SQLiteException(n, SQLiteLastError());
                    break;
                }
            default:

                {
                    Bind_Text(stmt, index, ToString(dt));
                    break;
                }
        }
    }

    internal override void Bind_Text(SQLiteStatement stmt, int index, string value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_text16(stmt._sqlite_stmt, index, value, value.Length * 2, (IntPtr)(-1));
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }






    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
    {
      return ToDateTime(GetText(stmt, index));
    }

    internal override string ColumnName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_name16(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override string GetText(SQLiteStatement stmt, int index)
    {

#if !SQLITE_STANDARD
      int len;
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16_interop(stmt._sqlite_stmt, index, out len), len);

#else
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16(stmt._sqlite_stmt, index), -1);
#endif
    }

    internal override string ColumnOriginalName(SQLiteStatement stmt, int index)


    {
#if !SQLITE_STANDARD
      int len;
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_origin_name16_interop(stmt._sqlite_stmt, index, out len), len);


#else
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_origin_name16(stmt._sqlite_stmt, index), -1);
#endif

    }


    internal override string ColumnDatabaseName(SQLiteStatement stmt, int index)

    {
#if !SQLITE_STANDARD
      int len;
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_database_name16_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_database_name16(stmt._sqlite_stmt, index), -1);

#endif

    }

    internal override string ColumnTableName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16(stmt._sqlite_stmt, index), -1);

#endif

    }

    internal override string GetParamValueText(IntPtr ptr)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF16ToString(UnsafeNativeMethods.sqlite3_value_text16_interop(ptr, out len), len);
#else
      return UTF16ToString(UnsafeNativeMethods.sqlite3_value_text16(ptr), -1);
#endif
    }

    internal override void ReturnError(IntPtr context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_error16(context, value, value.Length * 2);
    }

    internal override void ReturnText(IntPtr context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_text16(context, value, value.Length * 2, (IntPtr)(-1));
    }
  }
}










<
<
<







|
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|
|


>
>
>
>
>
|

|
<
<
|
<
<


|

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

<
<



|

|
<
<
<
<
|
<
<
<
<
<
<
<
|
|
|
<
>
>

<
|
<
<
<
|
<
|
<
>
|
<
>

<
<
<
<
<
<
|
|
|
>
|
|
<
<
<




|


>
>
>
>
>





<
|

<
<
<
<
|
<


|

>
|
<
|
>
|
<
<
<
|
<
>
>
|
<
|
|
>
>
|
|
|
>
|
|
>
|
>

<
|
|
<
|
>
|
>


|

<
|
|
<
|
>
|
>


|

<
<
|
<
<
<


|

|


|

|



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

namespace System.Data.SQLite
{
  using System;



  using System.Runtime.InteropServices;

  /// <summary>
  /// Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode)
  /// </summary>
  internal class SQLite3_UTF16 : SQLite3
  {
    internal SQLite3_UTF16(DateTimeFormat fmt)
      : base(fmt)
    {
    }












































    /// <summary>
    /// Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8
    /// </summary>
    /// <param name="b">A pointer to a UTF-16 string</param>
    /// <param name="nbytelen">The length (IN BYTES) of the string</param>
    /// <returns>A .NET string</returns>
    public override string ToString(IntPtr b, int nbytelen)
    {
      if (nbytelen == 0) return "";
      return Marshal.PtrToStringUni(b, nbytelen / 2);
    }

    /// <summary>
    /// Another custom string marshaling function
    /// </summary>
    /// <param name="b">A pointer to a zero-terminated UTF-16 string</param>
    /// <returns>A .NET string</returns>
    internal string ToString(IntPtr b)
    {
      if (b == IntPtr.Zero) return "";


      return Marshal.PtrToStringUni(b);


    }

    internal override void Open(string strFilename)
    {
      if (_sql != 0) return;













      int n = UnsafeNativeMethods.sqlite3_open16_interop(strFilename, out _sql);











      if (n > 0) throw new SQLiteException(n, SQLiteLastError());



      _functionsArray = SQLiteFunction.BindFunctions(this);
    }

    internal override string SQLiteLastError()
    {
      return ToString(UnsafeNativeMethods.sqlite3_errmsg16_interop(_sql));




    }








    internal override SQLiteStatement Prepare(string strSql, ref int nParamStart, out string strRemain)
    {

      int stmt;
      IntPtr ptr;


      int n = UnsafeNativeMethods.sqlite3_prepare16_interop(_sql, strSql, strSql.Length, out stmt, out ptr);



      if (n > 0) throw new SQLiteException(n, SQLiteLastError());



      strRemain = ToString(ptr);


      SQLiteStatement cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), ref nParamStart);







      return cmd;
    }

    internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt)
    {
      Bind_Text(stmt, index, ToString(dt));



    }

    internal override void Bind_Text(SQLiteStatement stmt, int index, string value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_text16_interop(stmt._sqlite_stmt, index, value, value.Length * 2, -1);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override string ColumnName(SQLiteStatement stmt, int index)
    {
      return ToString(UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index));
    }

    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
    {
      return ToDateTime(GetText(stmt, index));
    }

    internal override string GetText(SQLiteStatement stmt, int index)
    {




      return ToString(UnsafeNativeMethods.sqlite3_column_text16_interop(stmt._sqlite_stmt, index));

    }

    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)
    {
      nAffinity = TypeAffinity.None;


      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype16_interop(stmt._sqlite_stmt, index);
      if (p != IntPtr.Zero) return ToString(p);
      else



      {

        nAffinity = UnsafeNativeMethods.sqlite3_column_type_interop(stmt._sqlite_stmt, index);
        switch (nAffinity)
        {

          case TypeAffinity.Int64:
            return "BIGINT";
          case TypeAffinity.Double:
            return "DOUBLE";
          case TypeAffinity.Blob:
            return "BLOB";
          default:
            return "TEXT";
        }
      }
    }

    internal override int CreateFunction(string strFunction, int nArgs, SQLiteCallback func, SQLiteCallback funcstep, SQLiteCallback funcfinal)
    {

      int nCookie;


      int n = UnsafeNativeMethods.sqlite3_create_function16_interop(_sql, strFunction, nArgs, 4, func, funcstep, funcfinal, out nCookie);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      return nCookie;
    }

    internal override int CreateCollation(string strCollation, SQLiteCollation func)
    {

      int nCookie;


      int n = UnsafeNativeMethods.sqlite3_create_collation16_interop(_sql, strCollation, 4, 0, func, out nCookie);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      return nCookie;
    }

    internal override string GetParamValueText(int ptr)
    {


      return ToString(UnsafeNativeMethods.sqlite3_value_text16_interop(ptr));



    }

    internal override void ReturnError(int context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_error16_interop(context, value, value.Length);
    }

    internal override void ReturnText(int context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_text16_interop(context, value, value.Length, -1);
    }
  }
}
Changes to System.Data.SQLite/SQLiteBase.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;




  /// <summary>
  /// This internal class provides the foundation of SQLite support.  It defines all the abstract members needed to implement
  /// a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite.
  /// </summary>
  internal abstract class SQLiteBase : SQLiteConvert, IDisposable
  {
    internal SQLiteBase(SQLiteDateFormats fmt, DateTimeKind kind)
      : base(fmt, kind) { }

    static internal object _lock = new object();

    /// <summary>
    /// Returns a string representing the active version of SQLite
    /// </summary>
    internal abstract string Version { get; }
    /// <summary>
    /// Returns the rowid of the most recent successful INSERT into the database from this connection.
    /// </summary>
    internal abstract long LastInsertRowId { get; }
    /// <summary>
    /// Returns the number of changes the last executing insert/update caused.
    /// </summary>
    internal abstract int Changes { get; }
    /// <summary>
    /// Returns the amount of memory (in bytes) currently in use by the SQLite core library.
    /// </summary>
    internal abstract long MemoryUsed { get; }
    /// <summary>
    /// Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset.
    /// </summary>
    internal abstract long MemoryHighwater { get; }
    /// <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 int Shutdown();
    /// <summary>
    /// Returns non-zero if a database connection is open.
    /// </summary>
    /// <returns></returns>
    internal abstract bool IsOpen();
    /// <summary>
    /// Opens a database.
    /// </summary>
    /// <remarks>
    /// Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection
    /// to bind all attributed user-defined functions and collating sequences to the new connection.
    /// </remarks>
    /// <param name="strFilename">The filename of the database to open.  SQLite automatically creates it if it doesn't exist.</param>
    /// <param name="flags">The open flags to use when creating the connection</param>
    /// <param name="maxPoolSize">The maximum size of the pool for the given filename</param>
    /// <param name="usePool">If true, the connection can be pulled from the connection pool</param>
    internal abstract void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool);
    /// <summary>
    /// Closes the currently-open database.
    /// </summary>
    /// <remarks>
    /// After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated
    /// memory associated with the user-defined functions and collating sequences tied to the closed connection.
    /// </remarks>
    internal abstract void Close();
    /// <summary>
    /// Sets the busy timeout on the connection.  SQLiteCommand will call this before executing any command.
    /// </summary>
    /// <param name="nTimeoutMS">The number of milliseconds to wait before returning SQLITE_BUSY</param>
    internal abstract void SetTimeout(int nTimeoutMS);






    /// <summary>
    /// Returns the text of the last error issued by SQLite
    /// </summary>
    /// <returns></returns>
    internal abstract string SQLiteLastError();

    /// <summary>
    /// When pooling is enabled, force this connection to be disposed rather than returned to the pool
    /// </summary>
    internal abstract void ClearPool();

    /// <summary>
    /// Prepares a SQL statement for execution.
    /// </summary>
    /// <param name="cnn">The source connection preparing the command.  Can be null for any caller except LINQ</param>
    /// <param name="strSql">The SQL command text to prepare</param>
    /// <param name="previous">The previous statement in a multi-statement command, or null if no previous statement exists</param>



    /// <param name="timeoutMS">The timeout to wait before aborting the prepare</param>
    /// <param name="strRemain">The remainder of the statement that was not processed.  Each call to prepare parses the
    /// SQL up to to either the end of the text or to the first semi-colon delimiter.  The remaining text is returned
    /// here for a subsequent call to Prepare() until all the text has been processed.</param>
    /// <returns>Returns an initialized SQLiteStatement.</returns>
    internal abstract SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain);
    /// <summary>
    /// Steps through a prepared statement.
    /// </summary>
    /// <param name="stmt">The SQLiteStatement to step through</param>
    /// <returns>True if a row was returned, False if not.</returns>
    internal abstract bool Step(SQLiteStatement stmt);
    /// <summary>





    /// Resets a prepared statement so it can be executed again.  If the error returned is SQLITE_SCHEMA, 
    /// transparently attempt to rebuild the SQL statement and throw an error if that was not possible.
    /// </summary>
    /// <param name="stmt">The statement to reset</param>
    /// <returns>Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock</returns>
    internal abstract int Reset(SQLiteStatement stmt);










    internal abstract void Cancel();

    internal abstract void Bind_Double(SQLiteStatement stmt, int index, double value);
    internal abstract void Bind_Int32(SQLiteStatement stmt, int index, Int32 value);
    internal abstract void Bind_UInt32(SQLiteStatement stmt, int index, UInt32 value);
    internal abstract void Bind_Int64(SQLiteStatement stmt, int index, Int64 value);
    internal abstract void Bind_UInt64(SQLiteStatement stmt, int index, UInt64 value);
    internal abstract void Bind_Text(SQLiteStatement stmt, int index, string value);
    internal abstract void Bind_Blob(SQLiteStatement stmt, int index, byte[] blobData);
    internal abstract void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt);
    internal abstract void Bind_Null(SQLiteStatement stmt, int index);

    internal abstract int Bind_ParamCount(SQLiteStatement stmt);
    internal abstract string Bind_ParamName(SQLiteStatement stmt, int index);
    internal abstract int Bind_ParamIndex(SQLiteStatement stmt, string paramName);

    internal abstract int ColumnCount(SQLiteStatement stmt);
    internal abstract string ColumnName(SQLiteStatement stmt, int index);
    internal abstract TypeAffinity ColumnAffinity(SQLiteStatement stmt, int index);
    internal abstract string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity);
    internal abstract int ColumnIndex(SQLiteStatement stmt, string columnName);
    internal abstract string ColumnOriginalName(SQLiteStatement stmt, int index);
    internal abstract string ColumnDatabaseName(SQLiteStatement stmt, int index);
    internal abstract string ColumnTableName(SQLiteStatement stmt, int index);
    internal abstract void ColumnMetaData(string dataBase, string table, string column, out string dataType, out string collateSequence, out bool notNull, out bool primaryKey, out bool autoIncrement);
    internal abstract void GetIndexColumnExtendedInfo(string database, string index, string column, out int sortMode, out int onError, out string collationSequence);

    internal abstract double GetDouble(SQLiteStatement stmt, int index);
    internal abstract Int32 GetInt32(SQLiteStatement stmt, int index);
    internal abstract Int64 GetInt64(SQLiteStatement stmt, int index);
    internal abstract string GetText(SQLiteStatement stmt, int index);
    internal abstract long GetBytes(SQLiteStatement stmt, int index, int nDataoffset, byte[] bDest, int nStart, int nLength);
    internal abstract long GetChars(SQLiteStatement stmt, int index, int nDataoffset, char[] bDest, int nStart, int nLength);
    internal abstract DateTime GetDateTime(SQLiteStatement stmt, int index);
    internal abstract bool IsNull(SQLiteStatement stmt, int index);

    internal abstract void CreateCollation(string strCollation, SQLiteCollation func, SQLiteCollation func16);
    internal abstract void CreateFunction(string strFunction, int nArgs, bool needCollSeq, SQLiteCallback func, SQLiteCallback funcstep, SQLiteFinalCallback funcfinal);
    internal abstract CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context);
    internal abstract int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, string s1, string s2);
    internal abstract int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, char[] c1, char[] c2);

    internal abstract int AggregateCount(IntPtr context);
    internal abstract IntPtr AggregateContext(IntPtr context);

    internal abstract long GetParamValueBytes(IntPtr ptr, int nDataOffset, byte[] bDest, int nStart, int nLength);
    internal abstract double GetParamValueDouble(IntPtr ptr);
    internal abstract int GetParamValueInt32(IntPtr ptr);
    internal abstract Int64 GetParamValueInt64(IntPtr ptr);
    internal abstract string GetParamValueText(IntPtr ptr);
    internal abstract TypeAffinity GetParamValueType(IntPtr ptr);

    internal abstract void ReturnBlob(IntPtr context, byte[] value);
    internal abstract void ReturnDouble(IntPtr context, double value);
    internal abstract void ReturnError(IntPtr context, string value);
    internal abstract void ReturnInt32(IntPtr context, Int32 value);
    internal abstract void ReturnInt64(IntPtr context, Int64 value);
    internal abstract void ReturnNull(IntPtr context);
    internal abstract void ReturnText(IntPtr context, string value);

    /// <summary>
    /// Enables or disabled extened result codes returned by SQLite
    /// </summary>
    /// <param name="bOnOff">true to enable extended result codes, false to disable.</param>
    /// <returns></returns>
    internal abstract void SetExtendedResultCodes(bool bOnOff);
    /// <summary>
    /// Returns the numeric result code for the most recent failed SQLite API call 
    /// associated with the database connection. 
    /// </summary>
    /// <returns>Result code</returns>
    internal abstract int ResultCode();
    /// <summary>
    /// Returns the extended numeric result code for the most recent failed SQLite API call 
    /// associated with the database connection. 
    /// </summary>
    /// <returns>Extended result code</returns>
    internal abstract int ExtendedResultCode();

    /// <summary>
    /// Add a log message via the SQLite sqlite3_log interface.
    /// </summary>
    /// <param name="iErrCode">Error code to be logged with the message.</param>
    /// <param name="zMessage">String to be logged.  Unlike the SQLite sqlite3_log() 
    /// interface, this should be pre-formatted.  Consider using the 
    /// String.Format() function.</param>
    /// <returns></returns>
    internal abstract void LogMessage(int iErrCode, string zMessage);

    internal abstract void SetPassword(byte[] passwordBytes);
    internal abstract void ChangePassword(byte[] newPasswordBytes);

    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 int SetLogCallback(SQLiteLogCallback func);
    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, int index, SQLiteType typ);

    internal abstract bool AutoCommit

    {
      get;
    }

    internal abstract int FileControl(string zDbName, int op, IntPtr pArg);

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

    #region IDisposable Members
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteBase).Name);
#endif
    }

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

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            //if (disposing)
            //{
            //    ////////////////////////////////////
            //    // dispose managed resources here...
            //    ////////////////////////////////////
            //}

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

            disposed = true;
        }
    }
    #endregion

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

    #region Destructor
    ~SQLiteBase()
    {
        Dispose(false);
    }
    #endregion

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

    // These statics are here for lack of a better place to put them.
    // They exist here because they are called during the finalization of
    // a SQLiteStatementHandle, SQLiteConnectionHandle, and SQLiteFunctionCookieHandle.
    // Therefore these functions have to be static, and have to be low-level.

    internal static string SQLiteLastError(SQLiteConnectionHandle db)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1);
#endif
    }

    internal static void FinalizeStatement(SQLiteStatementHandle stmt)
    {
      lock (_lock)
      {
#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt);
#else
      int n = UnsafeNativeMethods.sqlite3_finalize(stmt);
#endif
        if (n > 0) throw new SQLiteException(n, null);
      }
    }

    internal static void CloseConnection(SQLiteConnectionHandle db)
    {
      lock (_lock)
      {
#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_close_interop(db);
#else
      ResetConnection(db);
      int n = UnsafeNativeMethods.sqlite3_close(db);
#endif
        if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));
      }
    }

    internal static void ResetConnection(SQLiteConnectionHandle db)
    {
      lock (_lock)
      {
        IntPtr stmt = IntPtr.Zero;
        int n;
        do
        {
          stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt);
          if (stmt != IntPtr.Zero)
          {
#if !SQLITE_STANDARD
            n = UnsafeNativeMethods.sqlite3_reset_interop(stmt);
#else
            n = UnsafeNativeMethods.sqlite3_reset(stmt);
#endif
          }
        } while (stmt != IntPtr.Zero);

        if (IsAutocommit(db) == false) // a transaction is pending on the connection
        {
          n = UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt);
          if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));
        }
      }
    }

    internal static bool IsAutocommit(SQLiteConnectionHandle hdl)
    {
      return (UnsafeNativeMethods.sqlite3_get_autocommit(hdl) == 1);
    }

  }

  internal interface ISQLiteSchemaExtensions
  {
    void BuildTempSchema(SQLiteConnection cnn);
  }

  [Flags]
  internal enum SQLiteOpenFlagsEnum
  {
    None = 0,
    ReadOnly = 0x01,
    ReadWrite = 0x02,
    Create = 0x04,
    SharedCache = 0x01000000,
    Default = 0x06,
  }

  // These are the options to the internal sqlite3_config call.
  internal enum SQLiteConfigOpsEnum
  {
    SQLITE_CONFIG_NONE = 0, // nil 
    SQLITE_CONFIG_SINGLETHREAD = 1, // nil 
    SQLITE_CONFIG_MULTITHREAD = 2, // nil 
    SQLITE_CONFIG_SERIALIZED = 3, // nil 
    SQLITE_CONFIG_MALLOC = 4, // sqlite3_mem_methods* 
    SQLITE_CONFIG_GETMALLOC = 5, // sqlite3_mem_methods* 
    SQLITE_CONFIG_SCRATCH = 6, // void*, int sz, int N 
    SQLITE_CONFIG_PAGECACHE = 7, // void*, int sz, int N 
    SQLITE_CONFIG_HEAP = 8, // void*, int nByte, int min 
    SQLITE_CONFIG_MEMSTATUS = 9, // boolean 
    SQLITE_CONFIG_MUTEX = 10, // sqlite3_mutex_methods* 
    SQLITE_CONFIG_GETMUTEX = 11, // sqlite3_mutex_methods* 
    // previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused
    SQLITE_CONFIG_LOOKASIDE = 13, // int int 
    SQLITE_CONFIG_PCACHE = 14, // sqlite3_pcache_methods* 
    SQLITE_CONFIG_GETPCACHE = 15, // sqlite3_pcache_methods* 
    SQLITE_CONFIG_LOG = 16, // xFunc, void* 
  }

}










>
>
>







|
|
<
<






<
<
<
<


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








<
<
<
|







|




|
>
>
>
>
>
>






<
<
<
<
<



<

|
>
>
>
|




|







>
>
>
>
>




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



<

<





|

|

|

<

|
<
<
<
<
<

|
|
|
|
|
|

|

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

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

|
|
|
|
|
|
>
|
<
<
|
<
|
<
|
<


|
|

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

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

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Runtime.InteropServices;
  using System.Collections.Generic;

  /// <summary>
  /// This internal class provides the foundation of SQLite support.  It defines all the abstract members needed to implement
  /// a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite.
  /// </summary>
  internal abstract class SQLiteBase : SQLiteConvert, IDisposable
  {
    internal SQLiteBase(DateTimeFormat fmt)
      : base(fmt) {}



    /// <summary>
    /// Returns a string representing the active version of SQLite
    /// </summary>
    internal abstract string Version { get; }
    /// <summary>




    /// Returns the number of changes the last executing insert/update caused.
    /// </summary>













    internal abstract int    Changes { get; }





    /// <summary>
    /// Opens a database.
    /// </summary>
    /// <remarks>
    /// Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection
    /// to bind all attributed user-defined functions and collating sequences to the new connection.
    /// </remarks>
    /// <param name="strFilename">The filename of the database to open.  SQLite automatically creates it if it doesn't exist.</param>



    internal abstract void   Open(string strFilename);
    /// <summary>
    /// Closes the currently-open database.
    /// </summary>
    /// <remarks>
    /// After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated
    /// memory associated with the user-defined functions and collating sequences tied to the closed connection.
    /// </remarks>
    internal abstract void   Close();
    /// <summary>
    /// Sets the busy timeout on the connection.  SQLiteCommand will call this before executing any command.
    /// </summary>
    /// <param name="nTimeoutMS">The number of milliseconds to wait before returning SQLITE_BUSY</param>
    internal abstract void   SetTimeout(int nTimeoutMS);
    /// <summary>
    /// Quick execute of a SQL command.  This is only executed internally, usually by SQLiteConnection when the connection
    /// is first opened to set the necessary startup pragmas.
    /// </summary>
    /// <param name="strSql">The SQL command text to execute</param>
    internal abstract void   Execute(string strSql);
    /// <summary>
    /// Returns the text of the last error issued by SQLite
    /// </summary>
    /// <returns></returns>
    internal abstract string SQLiteLastError();






    /// <summary>
    /// Prepares a SQL statement for execution.
    /// </summary>

    /// <param name="strSql">The SQL command text to prepare</param>
    /// <param name="nParamStart">When preparing multiple statements that are tied together into a single command,
    /// this value should be initialized to 0 for the first statement prepared.  On return from this function, the
    /// variable will automatically be incremented by 1 for each unnamed parameter that occurred in the statement.
    /// When implementing this function, one need only pass the nParamStart variable by reference to the SQLiteStatement()
    /// constructor.  SQLiteStatement will take care of it.</param>
    /// <param name="strRemain">The remainder of the statement that was not processed.  Each call to prepare parses the
    /// SQL up to to either the end of the text or to the first semi-colon delimiter.  The remaining text is returned
    /// here for a subsequent call to Prepare() until all the text has been processed.</param>
    /// <returns>Returns an initialized SQLiteStatement.</returns>
    internal abstract SQLiteStatement Prepare(string strSql, ref int nParamStart, out string strRemain);
    /// <summary>
    /// Steps through a prepared statement.
    /// </summary>
    /// <param name="stmt">The SQLiteStatement to step through</param>
    /// <returns>True if a row was returned, False if not.</returns>
    internal abstract bool Step(SQLiteStatement stmt);
    /// <summary>
    /// Finalizes a prepared statement.
    /// </summary>
    /// <param name="stmt">The statement to finalize</param>
    internal abstract void Finalize(SQLiteStatement stmt);
    /// <summary>
    /// Resets a prepared statement so it can be executed again.  If the error returned is SQLITE_SCHEMA, 
    /// transparently attempt to rebuild the SQL statement and throw an error if that was not possible.
    /// </summary>
    /// <param name="stmt">The statement to reset</param>
    /// <returns>Returns true if the schema changed while resetting, or false otherwise.</returns>
    internal abstract bool Reset(SQLiteStatement stmt);

    /// <summary>
    /// An interop-specific function, this call sets an internal flag in the sqlite.interop.dll which causes all column names
    /// of subsequently-prepared statements to return in Database.Table.Column format, ignoring all aliases that may have been applied
    /// to tables or columns in a resultset.
    /// </summary>
    /// <remarks>
    /// All statements prepared on this connection after this flag is changed are affected.  Existing statements are not.
    /// </remarks>
    /// <param name="bOn">Set to True to enable real column names, false to disable them.</param>
    internal abstract void SetRealColNames(bool bOn);

    internal abstract void Bind_Double(SQLiteStatement stmt, int index, double value);
    internal abstract void Bind_Int32(SQLiteStatement stmt, int index, Int32 value);

    internal abstract void Bind_Int64(SQLiteStatement stmt, int index, Int64 value);

    internal abstract void Bind_Text(SQLiteStatement stmt, int index, string value);
    internal abstract void Bind_Blob(SQLiteStatement stmt, int index, byte[] blobData);
    internal abstract void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt);
    internal abstract void Bind_Null(SQLiteStatement stmt, int index);

    internal abstract int    Bind_ParamCount(SQLiteStatement stmt);
    internal abstract string Bind_ParamName(SQLiteStatement stmt, int index);
    internal abstract int    Bind_ParamIndex(SQLiteStatement stmt, string paramName);

    internal abstract int    ColumnCount(SQLiteStatement stmt);
    internal abstract string ColumnName(SQLiteStatement stmt, int index);

    internal abstract string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity);
    internal abstract int    ColumnIndex(SQLiteStatement stmt, string columnName);






    internal abstract double   GetDouble(SQLiteStatement stmt, int index);
    internal abstract Int32    GetInt32(SQLiteStatement stmt, int index);
    internal abstract Int64    GetInt64(SQLiteStatement stmt, int index);
    internal abstract string   GetText(SQLiteStatement stmt, int index);
    internal abstract long     GetBytes(SQLiteStatement stmt, int index, int nDataoffset, byte[] bDest, int nStart, int nLength);
    internal abstract long     GetChars(SQLiteStatement stmt, int index, int nDataoffset, char[] bDest, int nStart, int nLength);
    internal abstract DateTime GetDateTime(SQLiteStatement stmt, int index);
    internal abstract bool     IsNull(SQLiteStatement stmt, int index);

    internal abstract int  CreateCollation(string strCollation, SQLiteCollation func);
    internal abstract int  CreateFunction(string strFunction, int nArgs, SQLiteCallback func, SQLiteCallback funcstep, SQLiteCallback funcfinal);



















    internal abstract void FreeFunction(int nCookie);













    internal abstract int AggregateCount(int context);





    internal abstract int AggregateContext(int context);










    internal abstract long   GetParamValueBytes(int ptr, int nDataOffset, byte[] bDest, int nStart, int nLength);
    internal abstract double GetParamValueDouble(int ptr);
    internal abstract int    GetParamValueInt32(int ptr);
    internal abstract Int64  GetParamValueInt64(int ptr);




    internal abstract string GetParamValueText(int ptr);
    internal abstract TypeAffinity GetParamValueType(int ptr);

    internal abstract void ReturnBlob(int context, byte[] value);
    internal abstract void ReturnDouble(int context, double value);
    internal abstract void ReturnError(int context, string value);
    internal abstract void ReturnInt32(int context, Int32 value);
    internal abstract void ReturnInt64(int context, Int64 value);
    internal abstract void ReturnNull(int context);
    internal abstract void ReturnText(int context, string value);



    protected virtual void Dispose(bool bDisposing)

    {

    }

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }

  }































































































































































}
Deleted System.Data.SQLite/SQLiteCommand.bmp.

cannot compute difference between binary files

Changes to System.Data.SQLite/SQLiteCommand.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;
  using System.ComponentModel;

  /// <summary>
  /// SQLite implementation of DbCommand.
  /// </summary>
#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 command text this command is based on
    /// </summary>
    private string _commandText;
    /// <summary>
    /// The connection the command is associated with
    /// </summary>
    private SQLiteConnection _cnn;
    /// <summary>
    /// The version of the connection the command is associated with
    /// </summary>
    private long _version;
    /// <summary>
    /// Indicates whether or not a DataReader is active on the command.
    /// </summary>
    private WeakReference _activeReader;
    /// <summary>
    /// The timeout for the command, kludged because SQLite doesn't support per-command timeout values
    /// </summary>
    internal int _commandTimeout;
    /// <summary>
    /// Designer support
    /// </summary>
    private bool _designTimeVisible;
    /// <summary>
    /// Used by DbDataAdapter to determine updating behavior
    /// </summary>
    private UpdateRowSource _updateRowSource;
    /// <summary>
    /// The collection of parameters for the command
    /// </summary>
    private SQLiteParameterCollection _parameterCollection;
    /// <summary>
    /// The SQL command text, broken into individual SQL statements as they are executed
    /// </summary>
    internal List<SQLiteStatement> _statementList;
    /// <summary>
    /// Unprocessed SQL text that has not been executed
    /// </summary>
    internal string _remainingText;
    /// <summary>
    /// Transaction associated with this command
    /// </summary>
    private SQLiteTransaction _transaction;

    ///<overloads>
    /// Constructs a new SQLiteCommand
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteCommand() :this(null, null)
    {

    }

    /// <summary>
    /// Initializes the command with the given command text
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    public SQLiteCommand(string commandText) 
      : this(commandText, null, null)
    {

    }

    /// <summary>
    /// Initializes the command with the given SQL command text and attach the command to the specified
    /// connection.
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    /// <param name="connection">The connection to associate with the command</param>
    public SQLiteCommand(string commandText, SQLiteConnection connection)
      : this(commandText, connection, null)
    {

    }

    /// <summary>
    /// Initializes the command and associates it with the specified connection.
    /// </summary>
    /// <param name="connection">The connection to associate with the command</param>
    public SQLiteCommand(SQLiteConnection connection) 
      : this(null, connection, null)
    {

    }

    private SQLiteCommand(SQLiteCommand source) : this(source.CommandText, source.Connection, source.Transaction)
    {
      CommandTimeout = source.CommandTimeout;
      DesignTimeVisible = source.DesignTimeVisible;
      UpdatedRowSource = source.UpdatedRowSource;

      foreach (SQLiteParameter param in source._parameterCollection)
      {
        Parameters.Add(param.Clone());
      }
    }

    /// <summary>
    /// Initializes a command with the given SQL, connection and transaction
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    /// <param name="connection">The connection to associate with the command</param>
    /// <param name="transaction">The transaction the command should be associated with</param>
    public SQLiteCommand(string commandText, SQLiteConnection connection, SQLiteTransaction transaction)
    {
      _commandTimeout = 30;
      _parameterCollection = new SQLiteParameterCollection(this);
      _designTimeVisible = true;
      _updateRowSource = UpdateRowSource.None;

      if (commandText != null)
        CommandText = commandText;

      if (connection != null)
      {
        DbConnection = connection;
        _commandTimeout = connection.DefaultTimeout;
      }

      if (transaction != null)
        Transaction = transaction;
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteCommand).Name);
#endif
    }

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

    /// <summary>
    /// Disposes of the command and clears all member variables
    /// </summary>
    /// <param name="disposing">Whether or not the class is being explicitly or implicitly disposed</param>
    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    // If a reader is active on this command, don't destroy the command, instead let the reader do it
                    SQLiteDataReader reader = null;
                    if (_activeReader != null)
                    {
                        try
                        {
                            reader = _activeReader.Target as SQLiteDataReader;
                        }
                        catch (InvalidOperationException)
                        {
                        }
                    }

                    if (reader != null)
                    {
                        reader._disposeCommand = true;
                        _activeReader = null;
                        return;
                    }

                    Connection = null;
                    _parameterCollection.Clear();
                    _commandText = null;
                }

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

                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
    #endregion

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

    /// <summary>
    /// Clears and destroys all statements currently prepared
    /// </summary>
    internal void ClearCommands()
    {
      if (_activeReader != null)
      {
        SQLiteDataReader reader = null;
        try
        {
          reader = _activeReader.Target as SQLiteDataReader;
        }
        catch(InvalidOperationException)
        {
        }

        if (reader != null)
          reader.Close();

        _activeReader = null;
      }

      if (_statementList == null) return;

      int x = _statementList.Count;
      for (int n = 0; n < x; n++)
        _statementList[n].Dispose();

      _statementList = null;

      _parameterCollection.Unbind();
    }

    /// <summary>

    /// Builds an array of prepared statements for each complete SQL statement in the command text
    /// </summary>
    internal SQLiteStatement BuildNextCommand()
    {

      SQLiteStatement stmt = null;



      try
      {
        if ((_cnn != null) && (_cnn._sql != null))
        {
          if (_statementList == null)
            _remainingText = _commandText;

          stmt = _cnn._sql.Prepare(_cnn, _remainingText, (_statementList == null) ? null : _statementList[_statementList.Count - 1], (uint)(_commandTimeout * 1000), out _remainingText);

          if (stmt != null)
          {
            stmt._command = this;

            if (_statementList == null)
              _statementList = new List<SQLiteStatement>();

            _statementList.Add(stmt);

            _parameterCollection.MapParameters(stmt);
            stmt.BindParameters();
          }
        }
        return stmt;
      }
      catch (Exception)
      {
        if (stmt != null)
        {
          if ((_statementList != null) && _statementList.Contains(stmt))
            _statementList.Remove(stmt);

          stmt.Dispose();
        }

        // If we threw an error compiling the statement, we cannot continue on so set the remaining text to null.
        _remainingText = null;

        throw;
      }
    }

    internal SQLiteStatement GetStatement(int index)
    {
      // Haven't built any statements yet
      if (_statementList == null) return BuildNextCommand();

      // If we're at the last built statement and want the next unbuilt statement, then build it
      if (index == _statementList.Count)
      {
        if (String.IsNullOrEmpty(_remainingText) == false) return BuildNextCommand();
        else return null; // No more commands
      }

      SQLiteStatement stmt = _statementList[index];
      stmt.BindParameters();

      return stmt;
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    public override void Cancel()
    {
      CheckDisposed();

      if (_activeReader != null)
      {
        SQLiteDataReader reader = _activeReader.Target as SQLiteDataReader;
        if (reader != null)
          reader.Cancel();
      }
    }

    /// <summary>
    /// The SQL command text associated with the command
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DefaultValue(""), RefreshProperties(RefreshProperties.All), Editor("Microsoft.VSDesigner.Data.SQL.Design.SqlCommandTextEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
    public override string CommandText
    {
      get
      {
        CheckDisposed();
        return _commandText;
      }
      set
      {
        CheckDisposed();

        if (_commandText == value) return;

        if (_activeReader != null && _activeReader.IsAlive)
        {
          throw new InvalidOperationException("Cannot set CommandText while a DataReader is active");
        }




        ClearCommands();
        _commandText = value;

        if (_cnn == null) return;


      }
    }

    /// <summary>
    /// The amount of time to wait for the connection to become available before erroring out
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DefaultValue((int)30)]
#endif
    public override int CommandTimeout
    {
      get
      {
        CheckDisposed();
        return _commandTimeout;
      }
      set
      {
        CheckDisposed();
        _commandTimeout = value;
      }
    }

    /// <summary>
    /// The type of the command.  SQLite only supports CommandType.Text
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [RefreshProperties(RefreshProperties.All), DefaultValue(CommandType.Text)]
#endif
    public override CommandType CommandType
    {
      get
      {
        CheckDisposed();
        return CommandType.Text;
      }
      set
      {
        CheckDisposed();

        if (value != CommandType.Text)
        {
          throw new NotSupportedException();
        }
      }
    }

    /// <summary>
    /// Forwards to the local CreateParameter() function
    /// </summary>
    /// <returns></returns>
    protected override DbParameter CreateDbParameter()
    {
      return CreateParameter();
    }

    /// <summary>
    /// Create a new parameter
    /// </summary>
    /// <returns></returns>
    public new SQLiteParameter CreateParameter()
    {
      CheckDisposed();
      return new SQLiteParameter();
    }

    /// <summary>
    /// The connection associated with this command
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
    public new SQLiteConnection Connection
    {
      get { CheckDisposed(); return _cnn; }
      set
      {


        CheckDisposed();

        if (_activeReader != null && _activeReader.IsAlive)
          throw new InvalidOperationException("Cannot set Connection while a DataReader is active");

        if (_cnn != null)
        {
          ClearCommands();
          //_cnn.RemoveCommand(this);
        }

        _cnn = value;
        if (_cnn != null)
          _version = _cnn._version;

        //if (_cnn != null)
        //  _cnn.AddCommand(this);
      }
    }

    /// <summary>
    /// Forwards to the local Connection property
    /// </summary>
    protected override DbConnection DbConnection
    {
      get
      {
        return Connection;
      }
      set
      {
        Connection = (SQLiteConnection)value;
      }
    }

    /// <summary>
    /// Returns the SQLiteParameterCollection for the given command
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
#endif
    public new SQLiteParameterCollection Parameters
    {
      get { CheckDisposed(); return _parameterCollection; }
    }

    /// <summary>
    /// Forwards to the local Parameters property
    /// </summary>
    protected override DbParameterCollection DbParameterCollection
    {
      get
      {
        return Parameters;
      }
    }

    /// <summary>
    /// The transaction associated with this command.  SQLite only supports one transaction per connection, so this property forwards to the
    /// command's underlying connection.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public new SQLiteTransaction Transaction
    {
      get { CheckDisposed(); return _transaction; }
      set
      {
        CheckDisposed();

        if (_cnn != null)
        {
          if (_activeReader != null && _activeReader.IsAlive)
            throw new InvalidOperationException("Cannot set Transaction while a DataReader is active");

          if (value != null)
          {
            if (value._cnn != _cnn)
              throw new ArgumentException("Transaction is not associated with the command's connection");
          }
          _transaction = value;
        }
        else
        {
          if (value != null) Connection = value.Connection;
          _transaction = value;
        }
      }
    }

    /// <summary>
    /// Forwards to the local Transaction property
    /// </summary>
    protected override DbTransaction DbTransaction
    {
      get
      {
        return Transaction;
      }
      set
      {
        Transaction = (SQLiteTransaction)value;
      }
    }

    /// <summary>
    /// This function ensures there are no active readers, that we have a valid connection,
    /// that the connection is open, that all statements are prepared and all parameters are assigned
    /// in preparation for allocating a data reader.
    /// </summary>
    private void InitializeForReader()
    {
      if (_activeReader != null && _activeReader.IsAlive)
        throw new InvalidOperationException("DataReader already active on this command");

      if (_cnn == null)
        throw new InvalidOperationException("No connection associated with this command");

      if (_cnn.State != ConnectionState.Open)
        throw new InvalidOperationException("Database is not open");

      // If the version of the connection has changed, clear out any previous commands before starting
      if (_cnn._version != _version)
      {
        _version = _cnn._version;
        ClearCommands();
      }

      // Map all parameters for statements already built
      _parameterCollection.MapParameters(null);

      //// Set the default command timeout
      //_cnn._sql.SetTimeout(_commandTimeout * 1000);
    }


    /// <summary>
    /// Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements
    /// </summary>
    /// <param name="behavior">The behavior the data reader should adopt</param>
    /// <returns>Returns a SQLiteDataReader object</returns>
    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
    {
      return ExecuteReader(behavior);
    }

    /// <summary>
    /// Overrides the default behavior to return a SQLiteDataReader specialization class
    /// </summary>
    /// <param name="behavior">The flags to be associated with the reader</param>
    /// <returns>A SQLiteDataReader</returns>
    public new SQLiteDataReader ExecuteReader(CommandBehavior behavior)


    {
      CheckDisposed();
      InitializeForReader();

      SQLiteDataReader rd = new SQLiteDataReader(this, behavior);
      _activeReader = new WeakReference(rd, false);

      return rd;

    }


    /// <summary>
    /// Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class
    /// </summary>
    /// <returns>A SQLiteDataReader</returns>
    public new SQLiteDataReader ExecuteReader()
    {
      CheckDisposed();
      return ExecuteReader(CommandBehavior.Default);
    }

    /// <summary>
    /// Called by the SQLiteDataReader when the data reader is closed.
    /// </summary>
    internal void ClearDataReader()
    {
      _activeReader = null;
    }

    /// <summary>
    /// Execute the command and return the number of rows inserted/updated affected by it.
    /// </summary>
    /// <returns></returns>
    public override int ExecuteNonQuery()
    {
      CheckDisposed();

      using (SQLiteDataReader reader = ExecuteReader(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>
    public override object ExecuteScalar()
    {
      CheckDisposed();

      using (SQLiteDataReader reader = ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult))
      {
        if (reader.Read())
          return reader[0];
      }
      return null;
    }

    /// <summary>
    /// Does nothing.  Commands are prepared as they are executed the first time, and kept in prepared state afterwards.
    /// </summary>
    public override void Prepare()
    {


      CheckDisposed();

    }

    /// <summary>
    /// Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable.
    /// </summary>
    [DefaultValue(UpdateRowSource.None)]
    public override UpdateRowSource UpdatedRowSource
    {
      get
      {
        CheckDisposed();
        return _updateRowSource;
      }
      set
      {
        CheckDisposed();
        _updateRowSource = value;
      }
    }

    /// <summary>
    /// Determines if the command is visible at design time.  Defaults to True.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DesignOnly(true), Browsable(false), DefaultValue(true), EditorBrowsable(EditorBrowsableState.Never)]
#endif
    public override bool DesignTimeVisible
    {
      get
      {
        CheckDisposed();
        return _designTimeVisible;
      }
      set
      {
        CheckDisposed();

        _designTimeVisible = value;
#if !PLATFORM_COMPACTFRAMEWORK
        TypeDescriptor.Refresh(this);
#endif
      }
    }

    /// <summary>
    /// Clones a command, including all its parameters
    /// </summary>
    /// <returns>A new SQLiteCommand with the same commandtext, connection and parameters</returns>
    public object Clone()
    {
      CheckDisposed();
      return new SQLiteCommand(this);
    }
  }
}













<




<
<
<
|

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

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







|

>





|
|
<

>






|
|
|
<

>





|
|
<

>


|

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



|

|
|

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


|

|


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

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
|







|
>
|
|
|
|
>
|
>
>



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

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

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







<
|
<
<
<
<
<
<





<
<
<




<




<
<


|




>
>
>




>
>






<
<
<




<




<







<
<
<




<




<
<


|


<
<
<
<
<
<
<
<
<






|

<






<
<
<
|

<
|

>
>
|
|
|





|


|
<
|

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






<
<
<
<
<
<
<
<
<
<
<




|







<
<
<
|

<
|

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

<
|





|

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

|



|




<
<
<
<
<
<
|
<
<

<
<
<
>
|
|
<
<
<
<
<
<
<
|

<
<
<
<
<
<
>
>
|
<
<
|
<
<
|
<
>
|
>

<
<
<
<
|
|
<
|


<
<
<


|








<
|
<

|
|




|
<

|


<
|
<

|
|





|



>
>
|
>





<




<




<







<
<
<




<




<
<

<
<
<

<
<
<
<
<
<
<
<
<
<



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

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;


  /// <summary>
  /// SQLite implementation of DbCommand.
  /// </summary>



  public sealed class SQLiteCommand : DbCommand
  {



    private string                    _commandText;



    private SQLiteConnection          _cnn;



    private SQLiteDataReader          _dataReader;







    private int                       _commandTimeout;



    private bool                      _designTimeVisible;



    private UpdateRowSource           _updateRowSource;



    private SQLiteParameterCollection _parameterCollection;



    internal SQLiteStatement[]        _statementList;









    ///<overloads>
    /// Constructs a new SQLiteCommand
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteCommand()
    {
      Initialize(null, null);
    }

    /// <summary>
    /// Initializes the command with the given command text
    /// </summary>
    /// <param name="strSql">The SQL command text</param>
    public SQLiteCommand(string strSql)

    {
      Initialize(strSql, null);
    }

    /// <summary>
    /// Initializes the command with the given SQL command text and attach the command to the specified
    /// connection.
    /// </summary>
    /// <param name="strSql">The SQL command text</param>
    /// <param name="cnn">The connection to associate with the command</param>
    public SQLiteCommand(string strSql, SQLiteConnection cnn)

    {
      Initialize(strSql, cnn);
    }

    /// <summary>
    /// Initializes the command and associates it with the specified connection.
    /// </summary>
    /// <param name="cnn"></param>
    public SQLiteCommand(SQLiteConnection cnn)

    {
      Initialize(null, cnn);
    }

    private void Initialize(string strSql, SQLiteConnection cnn)
    {



      _statementList = null;





      _dataReader = null;








      _commandTimeout = 30;
      _parameterCollection = new SQLiteParameterCollection(this);
      _designTimeVisible = true;
      _updateRowSource = UpdateRowSource.FirstReturnedRecord;

      if (strSql != null)
        CommandText = strSql;

      if (cnn != null)

        DbConnection = cnn;

    }



















    /// <summary>
    /// 
    /// </summary>
    /// <param name="disposing"></param>
    protected override void Dispose(bool disposing)
    {




      base.Dispose(disposing);




      ClearCommands();





















      _parameterCollection.Clear();

    }




















    internal void ClearCommands()
    {

















      if (_statementList == null) return;


      for (int n = 0; n < _statementList.Length; n++)
        _statementList[n].Dispose();

      _statementList = null;

      _parameterCollection.Unbind();
    }

    internal void BuildCommands()
    {
      ClearCommands();

      if (_cnn.State != ConnectionState.Open) return;

      string strRemain = _commandText;
      SQLiteStatement itm;
      int nStart = 0;
      List<SQLiteStatement> lst = new List<SQLiteStatement>();

      try
      {




        while (strRemain.Length > 0)

        {



          itm = _cnn._sql.Prepare(strRemain, ref nStart, out strRemain);


          if (itm != null) lst.Add(itm);

        }


      }



      catch (Exception e)
      {




        ClearCommands();






        throw (e);
      }

      _statementList = new SQLiteStatement[lst.Count];






      lst.CopyTo(_statementList, 0);









    }

    /// <summary>
    /// Not implemented
    /// </summary>
    public override void Cancel()
    {

      throw new NotImplementedException();






    }

    /// <summary>
    /// The SQL command text associated with the command
    /// </summary>



    public override string CommandText
    {
      get
      {

        return _commandText;
      }
      set
      {


        if (_commandText == value) return;

        if (_dataReader != null)
        {
          throw new InvalidOperationException("Cannot set CommandText while a DataReader is active");
        }

//        if (value == null)
//          throw new ArgumentNullException();

        ClearCommands();
        _commandText = value;

        if (_cnn == null) return;

        BuildCommands();
      }
    }

    /// <summary>
    /// The amount of time to wait for the connection to become available before erroring out
    /// </summary>



    public override int CommandTimeout
    {
      get
      {

        return _commandTimeout;
      }
      set
      {

        _commandTimeout = value;
      }
    }

    /// <summary>
    /// The type of the command.  SQLite only supports CommandType.Text
    /// </summary>



    public override CommandType CommandType
    {
      get
      {

        return CommandType.Text;
      }
      set
      {


        if (value != CommandType.Text)
        {
          throw new NotImplementedException();
        }
      }









    }

    /// <summary>
    /// Create a new parameter
    /// </summary>
    /// <returns></returns>
    protected override DbParameter CreateDbParameter()
    {

      return new SQLiteParameter();
    }

    /// <summary>
    /// The connection associated with this command
    /// </summary>



    protected override DbConnection DbConnection
    {

      get
      {
        return _cnn;
      }
      set
      {
        if (_dataReader != null)
          throw new InvalidOperationException("Cannot set Connection while a DataReader is active");

        if (_cnn != null)
        {
          ClearCommands();
          _cnn._commandList.Remove(this);
        }

        _cnn = (SQLiteConnection)value;

        _cnn._commandList.Add(this);

        if (_commandText != null)
          BuildCommands();















      }
    }

    /// <summary>
    /// Returns the SQLiteParameterCollection for the given command
    /// </summary>











    protected override DbParameterCollection DbParameterCollection
    {
      get
      {
        return _parameterCollection;
      }
    }

    /// <summary>
    /// The transaction associated with this command.  SQLite only supports one transaction per connection, so this property forwards to the
    /// command's underlying connection.
    /// </summary>



    protected override DbTransaction DbTransaction
    {

      get
      {

        return _cnn._activeTransaction;




      }
      set
      {
        if (_cnn == null) return;


        if (value != _cnn._activeTransaction && value != null)


        {

          throw new ArgumentOutOfRangeException();
        }
      }
    }

    /// <summary>
    /// 
    /// </summary>











    /// <param name="behavior"></param>
    /// <returns></returns>




    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
    {
      if (_dataReader != null)
        throw new InvalidOperationException("DataReader already active on this command");

      if (_cnn == null)
        throw new InvalidOperationException("No connection associated with this Command");

      if (_cnn.State != ConnectionState.Open)
        throw new InvalidOperationException("Database is not open");







      int n;






      if (_statementList.Length == 0)
      {
        BuildCommands();







      }







      // Make sure all parameters are mapped properly to associated statement(s)
      _parameterCollection.MapParameters();



      // Bind all parameters to their statements


      for (n = 0; n < _statementList.Length; n++)

        _statementList[n].BindParameters();

      _cnn._sql.SetTimeout(_commandTimeout * 1000);





      _dataReader = new SQLiteDataReader(this, behavior);


      return _dataReader;
    }




    internal void ClearDataReader()
    {
      _dataReader = null;
    }

    /// <summary>
    /// Execute the command and return the number of rows inserted/updated affected by it.
    /// </summary>
    /// <returns></returns>
    public override int ExecuteNonQuery()
    {

      using (DbDataReader rd = ExecuteDbDataReader(CommandBehavior.Default))

      {
        rd.Close();
        return rd.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></returns>
    public override object ExecuteScalar()
    {

      using (DbDataReader rd = ExecuteDbDataReader(CommandBehavior.Default))

      {
        if (rd.Read())
          return rd[0];
      }
      return null;
    }

    /// <summary>
    /// Prepares the command for execution.
    /// </summary>
    public override void Prepare()
    {
      if (_statementList.Length == 0)
      {
        BuildCommands();
      }
    }

    /// <summary>
    /// Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable.
    /// </summary>

    public override UpdateRowSource UpdatedRowSource
    {
      get
      {

        return _updateRowSource;
      }
      set
      {

        _updateRowSource = value;
      }
    }

    /// <summary>
    /// Determines if the command is visible at design time.  Defaults to True.
    /// </summary>



    public override bool DesignTimeVisible
    {
      get
      {

        return _designTimeVisible;
      }
      set
      {


        _designTimeVisible = value;



      }










    }
  }
}
Added System.Data.SQLite/SQLiteCommandBase.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
using System;

namespace System.Data.SQLite
{
  internal sealed class SQLiteCommandBase : IDisposable
  {
    internal SQLiteBase _sqlbase;
    internal string     _strCommand;
    internal int        _sqlite_stmt;

    internal SQLiteCommandBase(SQLiteBase sqlbase, int stmt, string strCommand)
    {
      _sqlbase     = sqlbase;
      _sqlite_stmt = stmt;
      _strCommand  = strCommand;
    }

    #region IDisposable Members

    public void Dispose()
    {
      _sqlbase.Finalize(this);
    }

    #endregion
  }
}
Changes to System.Data.SQLite/SQLiteCommandBuilder.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

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

  /// <summary>
  /// SQLite implementation of DbCommandBuilder.
  /// </summary>
  public sealed class SQLiteCommandBuilder : DbCommandBuilder
  {
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteCommandBuilder() : this(null)
    {
    }

    /// <summary>
    /// Initializes the command builder and associates it with the specified data adapter.
    /// </summary>
    /// <param name="adp"></param>
    public SQLiteCommandBuilder(SQLiteDataAdapter adp)
    {
      QuotePrefix = "[";
      QuoteSuffix = "]";
      DataAdapter = adp;
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteCommandBuilder).Name);
#endif
    }

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

    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                //if (disposing)
                //{
                //    ////////////////////////////////////
                //    // dispose managed resources here...
                //    ////////////////////////////////////
                //}

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

                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
    #endregion

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

    /// <summary>
    /// Minimal amount of parameter processing.  Primarily sets the DbType for the parameter equal to the provider type in the schema

    /// </summary>
    /// <param name="parameter">The parameter to use in applying custom behaviors to a row</param>
    /// <param name="row">The row to apply the parameter to</param>
    /// <param name="statementType">The type of statement</param>
    /// <param name="whereClause">Whether the application of the parameter is part of a WHERE clause</param>
    protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause)
    {
      SQLiteParameter param = (SQLiteParameter)parameter;
      param.DbType = (DbType)row[SchemaTableColumn.ProviderType];
    }




    /// <summary>
    /// Returns a valid named parameter
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <returns>Error</returns>
    protected override string GetParameterName(string parameterName)
    {
      return String.Format(CultureInfo.InvariantCulture, "@{0}", parameterName);
    }

    /// <summary>
    /// Returns a named parameter for the given ordinal
    /// </summary>
    /// <param name="parameterOrdinal">The i of the parameter</param>
    /// <returns>Error</returns>
    protected override string GetParameterName(int parameterOrdinal)
    {
      return String.Format(CultureInfo.InvariantCulture, "@param{0}", parameterOrdinal);
    }

    /// <summary>
    /// Returns a placeholder character for the specified parameter i.
    /// </summary>
    /// <param name="parameterOrdinal">The index of the parameter to provide a placeholder for</param>
    /// <returns>Returns a named parameter</returns>
    protected override string GetParameterPlaceholder(int parameterOrdinal)
    {
      return GetParameterName(parameterOrdinal);
    }


    /// <summary>











    /// Sets the handler for receiving row updating events.  Used by the DbCommandBuilder to autogenerate SQL

    /// statements that may not have previously been generated.
    /// </summary>
    /// <param name="adapter">A data adapter to receive events on.</param>
    protected override void SetRowUpdatingHandler(DbDataAdapter adapter)
    {
      if (adapter == base.DataAdapter)
      {
        ((SQLiteDataAdapter)adapter).RowUpdating -= new EventHandler<RowUpdatingEventArgs>(RowUpdatingEventHandler);
      }
      else
      {
        ((SQLiteDataAdapter)adapter).RowUpdating += new EventHandler<RowUpdatingEventArgs>(RowUpdatingEventHandler);
      }
    }

    private void RowUpdatingEventHandler(object sender, RowUpdatingEventArgs e)
    {
      base.RowUpdatingHandler(e);
    }

    /// <summary>
    /// Gets/sets the DataAdapter for this CommandBuilder
    /// </summary>
    public new SQLiteDataAdapter DataAdapter
    {
      get { CheckDisposed(); return (SQLiteDataAdapter)base.DataAdapter; }
      set { CheckDisposed(); base.DataAdapter = value; }
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to delete rows from the database
    /// </summary>
    /// <returns></returns>
    public new SQLiteCommand GetDeleteCommand()
    {
      CheckDisposed();
      return (SQLiteCommand)base.GetDeleteCommand();
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to delete rows from the database
    /// </summary>
    /// <param name="useColumnsForParameterNames"></param>
    /// <returns></returns>
    public new SQLiteCommand GetDeleteCommand(bool useColumnsForParameterNames)
    {
      CheckDisposed();
      return (SQLiteCommand)base.GetDeleteCommand(useColumnsForParameterNames);
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to update rows in the database
    /// </summary>
    /// <returns></returns>
    public new SQLiteCommand GetUpdateCommand()
    {
      CheckDisposed();
      return (SQLiteCommand)base.GetUpdateCommand();
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to update rows in the database
    /// </summary>
    /// <param name="useColumnsForParameterNames"></param>
    /// <returns></returns>
    public new SQLiteCommand GetUpdateCommand(bool useColumnsForParameterNames)
    {
      CheckDisposed();
      return (SQLiteCommand)base.GetUpdateCommand(useColumnsForParameterNames);
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to insert rows into the database
    /// </summary>
    /// <returns></returns>
    public new SQLiteCommand GetInsertCommand()
    {
      CheckDisposed();
      return (SQLiteCommand)base.GetInsertCommand();
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to insert rows into the database
    /// </summary>
    /// <param name="useColumnsForParameterNames"></param>
    /// <returns></returns>
    public new SQLiteCommand GetInsertCommand(bool useColumnsForParameterNames)
    {
      CheckDisposed();
      return (SQLiteCommand)base.GetInsertCommand(useColumnsForParameterNames);
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override CatalogLocation CatalogLocation
    {
      get
      {
        CheckDisposed();
        return base.CatalogLocation;
      }
      set
      {
        CheckDisposed();
        base.CatalogLocation = value;
      }
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override string CatalogSeparator
    {
      get
      {
        CheckDisposed();
        return base.CatalogSeparator;
      }
      set
      {
        CheckDisposed();
        base.CatalogSeparator = value;
      }
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    [DefaultValue("[")]
    public override string QuotePrefix
    {
      get
      {
        CheckDisposed();
        return base.QuotePrefix;
      }
      set
      {
        CheckDisposed();
        base.QuotePrefix = value;
      }
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override string QuoteSuffix
    {
      get
      {
        CheckDisposed();
        return base.QuoteSuffix;
      }
      set
      {
        CheckDisposed();
        base.QuoteSuffix = value;
      }
    }

    /// <summary>
    /// Places brackets around an identifier
    /// </summary>
    /// <param name="unquotedIdentifier">The identifier to quote</param>
    /// <returns>The bracketed identifier</returns>
    public override string QuoteIdentifier(string unquotedIdentifier)
    {
      CheckDisposed();

      if (String.IsNullOrEmpty(QuotePrefix)
        || String.IsNullOrEmpty(QuoteSuffix)
        || String.IsNullOrEmpty(unquotedIdentifier))
        return unquotedIdentifier;

      return QuotePrefix + unquotedIdentifier.Replace(QuoteSuffix, QuoteSuffix + QuoteSuffix) + QuoteSuffix;
    }

    /// <summary>
    /// Removes brackets around an identifier
    /// </summary>
    /// <param name="quotedIdentifier">The quoted (bracketed) identifier</param>
    /// <returns>The undecorated identifier</returns>
    public override string UnquoteIdentifier(string quotedIdentifier)
    {
      CheckDisposed();

      if (String.IsNullOrEmpty(QuotePrefix)
        || String.IsNullOrEmpty(QuoteSuffix)
        || String.IsNullOrEmpty(quotedIdentifier))
        return quotedIdentifier;

      if (quotedIdentifier.StartsWith(QuotePrefix, StringComparison.OrdinalIgnoreCase) == false
        || quotedIdentifier.EndsWith(QuoteSuffix, StringComparison.OrdinalIgnoreCase) == false)
        return quotedIdentifier;

      return quotedIdentifier.Substring(QuotePrefix.Length, quotedIdentifier.Length - (QuotePrefix.Length + QuoteSuffix.Length)).Replace(QuoteSuffix + QuoteSuffix, QuoteSuffix);
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override string SchemaSeparator
    {
      get
      {
        CheckDisposed();
        return base.SchemaSeparator;
      }
      set
      {
        CheckDisposed();
        base.SchemaSeparator = value;
      }
    }

    /// <summary>
    /// Override helper, which can help the base command builder choose the right keys for the given query
    /// </summary>
    /// <param name="sourceCommand"></param>
    /// <returns></returns>
    protected override DataTable GetSchemaTable(DbCommand sourceCommand)
    {
      using (IDataReader reader = sourceCommand.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
      {
        DataTable schema = reader.GetSchemaTable();

        // If the query contains a primary key, turn off the IsUnique property
        // for all the non-key columns
        if (HasSchemaPrimaryKey(schema))
          ResetIsUniqueSchemaColumn(schema);

        // if table has no primary key we use unique columns as a fall back
        return schema;
      }
    }

    private bool HasSchemaPrimaryKey(DataTable schema)
    {
      DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey];
      
      foreach (DataRow schemaRow in schema.Rows)
      {
        if ((bool)schemaRow[IsKeyColumn] == true)
          return true;
      }

      return false;
    }

    private void ResetIsUniqueSchemaColumn(DataTable schema)
    {
      DataColumn IsUniqueColumn = schema.Columns[SchemaTableColumn.IsUnique];
      DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey];

      foreach (DataRow schemaRow in schema.Rows)
      {
        if ((bool)schemaRow[IsKeyColumn] == false)
          schemaRow[IsUniqueColumn] = false;
      }

      schema.AcceptChanges();
    }
  }
}












<
<









|









<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
>







<
<


>
>
>

|





|



|

|



|



|


|


|


>

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




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



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

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



  /// <summary>
  /// SQLite implementation of DbCommandBuilder.
  /// </summary>
  public sealed class SQLiteCommandBuilder : DbCommandBuilder
  {
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteCommandBuilder()
    {
    }

    /// <summary>
    /// Initializes the command builder and associates it with the specified data adapter.
    /// </summary>
    /// <param name="adp"></param>
    public SQLiteCommandBuilder(SQLiteDataAdapter adp)
    {


      DataAdapter = adp;
    }












































    /// <summary>

    /// Not implemented, this function does nothing.
    /// </summary>
    /// <param name="parameter">The parameter to use in applying custom behaviors to a row</param>
    /// <param name="row">The row to apply the parameter to</param>
    /// <param name="statementType">The type of statement</param>
    /// <param name="whereClause">Whether the application of the parameter is part of a WHERE clause</param>
    protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause)
    {


    }

    /// <overloads>
    /// Not implemented.  Throws a NotImplementedException() if called.
    /// </overloads>
    /// <summary>
    /// Not implemented.
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <returns>Error</returns>
    protected override string GetParameterName(string parameterName)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// Not implemented.
    /// </summary>
    /// <param name="parameterOrdinal">The ordinal of the parameter</param>
    /// <returns>Error</returns>
    protected override string GetParameterName(int parameterOrdinal)
    {
      return null;
    }

    /// <summary>
    /// Returns a placeholder character for the specified parameter ordinal.
    /// </summary>
    /// <param name="parameterOrdinal">The index of the parameter to provide a placeholder for</param>
    /// <returns>Returns a "?" character, used for all placeholders.</returns>
    protected override string GetParameterPlaceholder(int parameterOrdinal)
    {
      return "?";
    }

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Obsolete
    /// </summary>
    [Obsolete]
    protected override DbProviderFactory ProviderFactory
    {
      get 
      {
        return new SQLiteFactory();
      }
    }
#endif

    /// <summary>
    /// Not implemented.
    /// </summary>
    /// <param name="adapter">A data adapter to receive events on.</param>
    protected override void SetRowUpdatingHandler(DbDataAdapter adapter)
    {
















































































































































































































































































    }
  }
}
Deleted System.Data.SQLite/SQLiteConnection.bmp.

cannot compute difference between binary files

Changes to System.Data.SQLite/SQLiteConnection.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;
  using System.Globalization;
  using System.ComponentModel;
  using System.Runtime.InteropServices;

  using System.IO;















  /// <summary>
  /// SQLite implentation of DbConnection.
  /// </summary>
  /// <remarks>
  /// The <see cref="ConnectionString">ConnectionString</see> property of the SQLiteConnection class can contain the following parameter(s), delimited with a semi-colon:
  /// <list type="table">













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







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

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;

  /// <summary>
  /// The I/O file cache flushing behavior for the connection
  /// </summary>
  public enum SyncMode
  {
    /// <summary>
    /// Normal file flushing at critical sections of the code
    /// </summary>
    Normal = 0,
    /// <summary>
    /// Full file flushing after every write operation
    /// </summary>
    Full = 1,
    /// <summary>
    /// Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing
    /// </summary>
    Off = 2,
  }

  /// <summary>
  /// SQLite implentation of DbConnection.
  /// </summary>
  /// <remarks>
  /// The <see cref="ConnectionString">ConnectionString</see> property of the SQLiteConnection class can contain the following parameter(s), delimited with a semi-colon:
  /// <list type="table">
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
  /// <item>
  /// <description>DateTimeFormat</description>
  /// <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format</description>
  /// <description>N</description>
  /// <description>ISO8601</description>
  /// </item>
  /// <item>
  /// <description>DateTimeKind</description>
  /// <description><b>Unspecified</b> - Not specified as either UTC or local time.<br/><b>Utc</b> - The time represented is UTC.<br/><b>Local</b> - The time represented is local time.</description>
  /// <description>N</description>
  /// <description>Unspecified</description>
  /// </item>
  /// <item>
  /// <description>BaseSchemaName</description>
  /// <description>Some base data classes in the framework (e.g. those that build SQL queries dynamically)
  /// assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting
  /// alternate schemas as well; however, SQLite does not fit into this model.  Therefore, this value is used
  /// as a placeholder and removed prior to preparing any SQL statements that may contain it.</description>
  /// <description>N</description>
  /// <description>sqlite_default_schema</description>
  /// </item>
  /// <item>
  /// <description>BinaryGUID</description>
  /// <description><b>True</b> - Store GUID columns in binary form<br/><b>False</b> - Store GUID columns as text</description>
  /// <description>N</description>
  /// <description>True</description>
  /// </item>
  /// <item>
  /// <description>Cache Size</description>
  /// <description>{size in bytes}</description>
  /// <description>N</description>
  /// <description>2000</description>
  /// </item>
  /// <item>
  /// <description>Synchronous</description>
  /// <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>
  /// <description>N</description>
  /// <description>Normal</description>
  /// </item>
  /// <item>
  /// <description>Page Size</description>
  /// <description>{size in bytes}</description>
  /// <description>N</description>
  /// <description>1024</description>
  /// </item>
  /// <item>
  /// <description>Password</description>
  /// <description>{password}</description>
  /// <description>N</description>
  /// <description></description>
  /// </item>
  /// <item>
  /// <description>Enlist</description>
  /// <description><b>Y</b> - Automatically enlist in distributed transactions<br/><b>N</b> - No automatic enlistment</description>
  /// <description>N</description>
  /// <description>Y</description>
  /// </item>
  /// <item>
  /// <description>Pooling</description>
  /// <description><b>True</b> - Use connection pooling<br/><b>False</b> - Do not use connection pooling</description>
  /// <description>N</description>
  /// <description>False</description>
  /// </item>
  /// <item>
  /// <description>FailIfMissing</description>
  /// <description><b>True</b> - Don't create the database if it does not exist, throw an error instead<br/><b>False</b> - Automatically create the database if it does not exist</description>
  /// <description>N</description>
  /// <description>False</description>
  /// </item>
  /// <item>
  /// <description>Max Page Count</description>
  /// <description>{size in pages} - Limits the maximum number of pages (limits the size) of the database</description>
  /// <description>N</description>
  /// <description>0</description>
  /// </item>
  /// <item>
  /// <description>Legacy Format</description>
  /// <description><b>True</b> - Use the more compatible legacy 3.x database format<br/><b>False</b> - Use the newer 3.3x database format which compresses numbers more effectively</description>
  /// <description>N</description>
  /// <description>False</description>
  /// </item>
  /// <item>
  /// <description>Default Timeout</description>
  /// <description>{time in seconds}<br/>The default command timeout</description>
  /// <description>N</description>
  /// <description>30</description>
  /// </item>
  /// <item>
  /// <description>Journal Mode</description>
  /// <description><b>Delete</b> - Delete the journal file after a commit<br/><b>Persist</b> - Zero out and leave the journal file on disk after a commit<br/><b>Off</b> - Disable the rollback journal entirely</description>
  /// <description>N</description>
  /// <description>Delete</description>
  /// </item>
  /// <item>
  /// <description>Read Only</description>
  /// <description><b>True</b> - Open the database for read only access<br/><b>False</b> - Open the database for normal read/write access</description>
  /// <description>N</description>
  /// <description>False</description>
  /// </item>
  /// <item>
  /// <description>Max Pool Size</description>
  /// <description>The maximum number of connections for the given connection string that can be in the connection pool</description>
  /// <description>N</description>
  /// <description>100</description>
  /// </item>
  /// <item>
  /// <description>Default IsolationLevel</description>
  /// <description>The default transaciton isolation level</description>
  /// <description>N</description>
  /// <description>Serializable</description>
  /// </item>
  /// <item>
  /// <description>Foreign Keys</description>
  /// <description>Enable foreign key constraints</description>
  /// <description>N</description>
  /// <description>False</description>
  /// </item>
  /// </list>
  /// </remarks>
  public sealed partial class SQLiteConnection : DbConnection, ICloneable
  {
    /// <summary>
    /// The default "stub" (i.e. placeholder) base schema name to use when
    /// returning column schema information.  Used as the initial value of
    /// the BaseSchemaName property.  This should start with "sqlite_*"
    /// because those names are reserved for use by SQLite (i.e. they cannot
    /// be confused with the names of user objects).
    /// </summary>
    internal const string DefaultBaseSchemaName = "sqlite_default_schema";

    private const int SQLITE_FCNTL_WIN32_AV_RETRY = 9;

    private const string _dataDirectory = "|DataDirectory|";
    private const string _masterdb = "sqlite_master";
    private const string _tempmasterdb = "sqlite_temp_master";

    /// <summary>
    /// State of the current connection
    /// </summary>
    private ConnectionState _connectionState;
    /// <summary>
    /// The connection string
    /// </summary>
    private string _connectionString;
    /// <summary>
    /// Nesting level of the transactions open on the connection
    /// </summary>
    internal int _transactionLevel;

    /// <summary>
    /// The default isolation level for new transactions
    /// </summary>
    private IsolationLevel _defaultIsolation;

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Whether or not the connection is enlisted in a distrubuted transaction
    /// </summary>
    internal SQLiteEnlistment _enlistment;
#endif
    /// <summary>
    /// The base SQLite object to interop with
    /// </summary>
    internal SQLiteBase _sql;
    /// <summary>
    /// The database filename minus path and extension
    /// </summary>
    private string _dataSource;
    /// <summary>
    /// Temporary password storage, emptied after the database has been opened
    /// </summary>
    private byte[] _password;

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

    /// <summary>
    /// Default command timeout
    /// </summary>
    private int _defaultTimeout = 30;

    internal bool _binaryGuid;

    internal long _version;

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

    private SQLiteUpdateCallback _updateCallback;
    private SQLiteCommitCallback _commitCallback;
    private SQLiteTraceCallback _traceCallback;
    private SQLiteRollbackCallback _rollbackCallback;

    /// <summary>
    /// This event is raised whenever the database is opened or closed.
    /// </summary>
    public override event StateChangeEventHandler StateChange;


    ///<overloads>
    /// Constructs a new SQLiteConnection object
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteConnection()
      : this("")
    {

    }

    /// <summary>
    /// Initializes the connection with the specified connection string
    /// </summary>
    /// <param name="connectionString">The connection string to use on the connection</param>
    public SQLiteConnection(string connectionString)
    {
#if !PLATFORM_COMPACTFRAMEWORK
      SQLiteLog.Initialize();
#endif

      _connectionState = ConnectionState.Closed;
      _connectionString = "";
      //_commandList = new List<WeakReference>();

      if (connectionString != null)
        ConnectionString = connectionString;
    }

    /// <summary>
    /// Clones the settings and connection string from an existing connection.  If the existing connection is already open, this
    /// function will open its own connection, enumerate any attached databases of the original connection, and automatically
    /// attach to them.
    /// </summary>
    /// <param name="connection"></param>
    public SQLiteConnection(SQLiteConnection connection)
      : this(connection.ConnectionString)
    {
      string str;



      if (connection.State == ConnectionState.Open)
      {
        Open();

        // Reattach all attached databases from the existing connection
        using (DataTable tbl = connection.GetSchema("Catalogs"))
        {
          foreach (DataRow row in tbl.Rows)
          {
            str = row[0].ToString();
            if (String.Compare(str, "main", StringComparison.OrdinalIgnoreCase) != 0
              && String.Compare(str, "temp", StringComparison.OrdinalIgnoreCase) != 0)
            {
              using (SQLiteCommand cmd = CreateCommand())
              {
                cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]);
                cmd.ExecuteNonQuery();
              }
            }
          }
        }
      }
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteConnection).Name);
#endif
    }

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

    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                //if (disposing)
                //{
                //    ////////////////////////////////////
                //    // dispose managed resources here...
                //    ////////////////////////////////////
                //}

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

                Close();

                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
    #endregion

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

#if PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Obsolete
    /// </summary>
    public override int ConnectionTimeout
    {
      get
      {
        return 30;
      }
    }
#endif

    /// <summary>
    /// Creates a clone of the connection.  All attached databases and user-defined functions are cloned.  If the existing connection is open, the cloned connection 
    /// will also be opened.
    /// </summary>
    /// <returns></returns>
    public object Clone()
    {
      return new SQLiteConnection(this);
    }













    /// <summary>
    /// Creates a database file.  This just creates a zero-byte file which SQLite
    /// will turn into a database when the file is opened properly.

    /// </summary>
    /// <param name="databaseFileName">The file to create</param>
    static public void CreateFile(string databaseFileName)
    {
      FileStream fs = File.Create(databaseFileName);
      fs.Close();
    }

    /// <summary>
    /// Raises the state change event when the state of the connection changes
    /// </summary>
    /// <param name="newState">The new state.  If it is different from the previous state, an event is raised.</param>
    internal void OnStateChange(ConnectionState newState)
    {
      ConnectionState oldState = _connectionState;
      _connectionState = newState;


      if (StateChange != null && oldState != newState)
      {
        StateChangeEventArgs e = new StateChangeEventArgs(oldState, newState);
        StateChange(this, e);
      }
    }

    /// <summary>
    /// OBSOLETE.  Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <param name="isolationLevel">This parameter is ignored.</param>
    /// <param name="deferredLock">When TRUE, SQLite defers obtaining a write lock until a write operation is requested.
    /// When FALSE, a writelock is obtained immediately.  The default is TRUE, but in a multi-threaded multi-writer 
    /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>
    /// <returns>Returns a SQLiteTransaction object.</returns>
    [Obsolete("Use one of the standard BeginTransaction methods, this one will be removed soon")]
    public SQLiteTransaction BeginTransaction(IsolationLevel isolationLevel, bool deferredLock)
    {
      return (SQLiteTransaction)BeginDbTransaction(deferredLock == false ? IsolationLevel.Serializable : IsolationLevel.ReadCommitted);
    }

    /// <summary>
    /// OBSOLETE.  Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <param name="deferredLock">When TRUE, SQLite defers obtaining a write lock until a write operation is requested.
    /// When FALSE, a writelock is obtained immediately.  The default is false, but in a multi-threaded multi-writer 
    /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>
    /// <returns>Returns a SQLiteTransaction object.</returns>
    [Obsolete("Use one of the standard BeginTransaction methods, this one will be removed soon")]
    public SQLiteTransaction BeginTransaction(bool deferredLock)
    {
      return (SQLiteTransaction)BeginDbTransaction(deferredLock == false ? IsolationLevel.Serializable : IsolationLevel.ReadCommitted);
    }

    /// <summary>
    /// Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <param name="isolationLevel">Supported isolation levels are Serializable, ReadCommitted and Unspecified.</param>
    /// <remarks>
    /// Unspecified will use the default isolation level specified in the connection string.  If no isolation level is specified in the 
    /// connection string, Serializable is used.
    /// Serializable transactions are the default.  In this mode, the engine gets an immediate lock on the database, and no other threads
    /// may begin a transaction.  Other threads may read from the database, but not write.
    /// With a ReadCommitted isolation level, locks are deferred and elevated as needed.  It is possible for multiple threads to start
    /// a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread
    /// has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached.
    /// </remarks>
    /// <returns>Returns a SQLiteTransaction object.</returns>
    public new SQLiteTransaction BeginTransaction(IsolationLevel isolationLevel)
    {
      return (SQLiteTransaction)BeginDbTransaction(isolationLevel);
    }

    /// <summary>
    /// Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <returns>Returns a SQLiteTransaction object.</returns>
    public new SQLiteTransaction BeginTransaction()
    {
      return (SQLiteTransaction)BeginDbTransaction(_defaultIsolation);
    }

    /// <summary>
    /// Forwards to the local BeginTransaction() function
    /// </summary>
    /// <param name="isolationLevel">Supported isolation levels are Unspecified, Serializable, and ReadCommitted</param>
    /// <returns></returns>
    protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException();

      if (isolationLevel == IsolationLevel.Unspecified) isolationLevel = _defaultIsolation;

      if (isolationLevel != IsolationLevel.Serializable && isolationLevel != IsolationLevel.ReadCommitted)
        throw new ArgumentException("isolationLevel");

      return new SQLiteTransaction(this, isolationLevel != IsolationLevel.Serializable);

    }

    /// <summary>
    /// Not implemented
    /// </summary>
    /// <param name="databaseName"></param>
    public override void ChangeDatabase(string databaseName)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// When the database connection is closed, all commands linked to this connection are automatically reset.
    /// </summary>
    public override void Close()
    {
      if (_sql != null)
      {
#if !PLATFORM_COMPACTFRAMEWORK
        if (_enlistment != null)
        {
          // If the connection is enlisted in a transaction scope and the scope is still active,
          // we cannot truly shut down this connection until the scope has completed.  Therefore make a 
          // hidden connection temporarily to hold open the connection until the scope has completed.
          SQLiteConnection cnn = new SQLiteConnection();
          cnn._sql = _sql;
          cnn._transactionLevel = _transactionLevel;
          cnn._enlistment = _enlistment;
          cnn._connectionState = _connectionState;
          cnn._version = _version;

          cnn._enlistment._transaction._cnn = cnn;
          cnn._enlistment._disposeConnection = true;

          _sql = null;
          _enlistment = null;
        }
#endif
        if (_sql != null)
        {
          _sql.Close();
          _sql = null;
        }
        _transactionLevel = 0;
      }
      OnStateChange(ConnectionState.Closed);
    }

    /// <summary>
    /// Clears the connection pool associated with the connection.  Any other active connections using the same database file
    /// will be discarded instead of returned to the pool when they are closed.
    /// </summary>
    /// <param name="connection"></param>
    public static void ClearPool(SQLiteConnection connection)
    {
      if (connection._sql == null) return;
      connection._sql.ClearPool();
    }

    /// <summary>
    /// Clears all connection pools.  Any active connections will be discarded instead of sent to the pool when they are closed.
    /// </summary>
    public static void ClearAllPools()
    {
      SQLiteConnectionPool.ClearAllPools();
    }

    /// <summary>
    /// The connection string containing the parameters for the connection
    /// </summary>
    /// <remarks>
    /// <list type="table">







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|



|

<
<
<
|
<
<

<
|
<

<
<
<
<
<


|

<
<
<
<
<
<
<
|
<
<
<

<
|
<
<
<
<

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




>








<

>








<
<
<
<
<
|
<
<
<
<







|
|
<



>
>
|




|




|
<

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

<
<
<



















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

<
<
>

|
|

|
|


<
<
<
<





>





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





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

<
<
<
<
<
<
<
<
<
<





<
|
<
|

|
>


















|
<

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

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
  /// <item>
  /// <description>DateTimeFormat</description>
  /// <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format</description>
  /// <description>N</description>
  /// <description>ISO8601</description>
  /// </item>
  /// <item>





















  /// <description>Cache Size</description>
  /// <description>{size in bytes}</description>
  /// <description>N</description>
  /// <description>2000</description>
  /// </item>
  /// <item>
  /// <description>Synchronous</description>
  /// <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>
  /// <description>N</description>
  /// <description>Normal</description>
  /// </item>
  /// <item>
  /// <description>Page Size</description>
  /// <description>{size in bytes}</description>
  /// <description>N</description>
  /// <description>1024</description>
  /// </item>








































































  /// </list>
  /// </remarks>
  public sealed class SQLiteConnection : DbConnection, ICloneable
  {















    /// <summary>
    /// State of the current connection
    /// </summary>
    private ConnectionState     _connectionState;
    /// <summary>
    /// The connection string
    /// </summary>
    private string              _connectionString;
    /// <summary>



    /// One transaction allowed per connection please!


    /// </summary>

    internal DbTransaction       _activeTransaction;

    /// <summary>





    /// The base SQLite object to interop with
    /// </summary>
    internal SQLiteBase          _sql;
    /// <summary>







    /// Commands associated with this connection



    /// </summary>

    internal List<SQLiteCommand> _commandList;






#if !PLATFORM_COMPACTFRAMEWORK

    /// <event/>










    /// <summary>
    /// This event is raised whenever the database is opened or closed.
    /// </summary>
    public override event StateChangeEventHandler StateChange;
#endif

    ///<overloads>
    /// Constructs a new SQLiteConnection object
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteConnection()

    {
      Initialize(null);
    }

    /// <summary>
    /// Initializes the connection with the specified connection string
    /// </summary>
    /// <param name="connectionString">The connection string to use on the connection</param>
    public SQLiteConnection(string connectionString)
    {





      Initialize(connectionString);




    }

    /// <summary>
    /// Clones the settings and connection string from an existing connection.  If the existing connection is already open, this
    /// function will open its own connection, enumerate any attached databases of the original connection, and automatically
    /// attach to them.
    /// </summary>
    /// <param name="cnn"></param>
    public SQLiteConnection(SQLiteConnection cnn)

    {
      string str;

      Initialize(cnn.ConnectionString);

      if (cnn.State == ConnectionState.Open)
      {
        Open();

        // Reattach all attached databases from the existing connection
        using (DataTable tbl = cnn.GetSchema("Catalogs"))
        {
          foreach (DataRow row in tbl.Rows)
          {
            str = row[0].ToString();
            if (String.Compare(str, "MAIN", true) != 0 && String.Compare(str, "TEMP", true) != 0)

            {


              _sql.Execute(String.Format("ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]));

            }
          }
        }
      }
    }















































#if PLATFORM_COMPACTFRAMEWORK



    public override int ConnectionTimeout
    {
      get
      {
        return 30;
      }
    }
#endif

    /// <summary>
    /// Creates a clone of the connection.  All attached databases and user-defined functions are cloned.  If the existing connection is open, the cloned connection 
    /// will also be opened.
    /// </summary>
    /// <returns></returns>
    public object Clone()
    {
      return new SQLiteConnection(this);
    }

    private void Initialize(string connectionString)
    {
      _sql = null;
      _connectionState = ConnectionState.Closed;
      _connectionString = "";
      _activeTransaction = null;
      _commandList = new List<SQLiteCommand>();

      if (connectionString != null)
        ConnectionString = connectionString;
    }

    /// <summary>


    /// Disposes of the SQLiteConnection, closing it if it is active.
    /// </summary>
    /// <param name="bDisposing">True if the connection is being explicitly closed.</param>
    protected override void Dispose(bool bDisposing)
    {
      base.Dispose(bDisposing);
      Close();
    }





    internal void OnStateChange(ConnectionState newState)
    {
      ConnectionState oldState = _connectionState;
      _connectionState = newState;

#if !PLATFORM_COMPACTFRAMEWORK
      if (StateChange != null && oldState != newState)
      {
        StateChangeEventArgs e = new StateChangeEventArgs(oldState, newState);
        StateChange(this, e);
      }

#endif

























    }

    /// <summary>
    /// Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>















    /// <param name="isolationLevel">SQLite doesn't support varying isolation levels, so this parameter is ignored.</param>



    /// <returns>Returns a SQLiteTransaction object.</returns>










    protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException();


      if (_activeTransaction != null)

        throw new ArgumentException("Transaction already pending");

      _activeTransaction = new SQLiteTransaction(this);
      return _activeTransaction;
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    /// <param name="databaseName"></param>
    public override void ChangeDatabase(string databaseName)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// When the database connection is closed, all commands linked to this connection are automatically reset.
    /// </summary>
    public override void Close()
    {
      if (_sql != null)
      {
        for (int n = 0; n < _commandList.Count; n++)

        {









          _commandList[n].ClearCommands();


        }
        _sql.Close();

      }




      _sql = null;



      OnStateChange(ConnectionState.Closed);



















    }

    /// <summary>
    /// The connection string containing the parameters for the connection
    /// </summary>
    /// <remarks>
    /// <list type="table">
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
    /// <description>UseUTF16Encoding</description>
    /// <description><b>True</b><br/><b>False</b></description>
    /// <description>N</description>
    /// <description>False</description>
    /// </item>
    /// <item>
    /// <description>DateTimeFormat</description>
    /// <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format<br/><b>JulianDay</b> - Use JulianDay format</description>
    /// <description>N</description>
    /// <description>ISO8601</description>
    /// </item>
    /// <item>
    /// <description>BinaryGUID</description>
    /// <description><b>Yes/On/1</b> - Store GUID columns in binary form<br/><b>No/Off/0</b> - Store GUID columns as text</description>
    /// <description>N</description>
    /// <description>On</description>
    /// </item>
    /// <item>
    /// <description>Cache Size</description>
    /// <description>{size in bytes}</description>
    /// <description>N</description>
    /// <description>2000</description>
    /// </item>
    /// <item>
    /// <description>Synchronous</description>
    /// <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>
    /// <description>N</description>
    /// <description>Normal</description>
    /// </item>
    /// <item>
    /// <description>Page Size</description>
    /// <description>{size in bytes}</description>
    /// <description>N</description>
    /// <description>1024</description>
    /// </item>
    /// <item>
    /// <description>Password</description>
    /// <description>{password}</description>
    /// <description>N</description>
    /// <description></description>
    /// </item>
    /// <item>
    /// <description>Enlist</description>
    /// <description><B>Y</B> - Automatically enlist in distributed transactions<br/><b>N</b> - No automatic enlistment</description>
    /// <description>N</description>
    /// <description>Y</description>
    /// </item>
    /// <item>
    /// <description>Pooling</description>
    /// <description><b>True</b> - Use connection pooling<br/><b>False</b> - Do not use connection pooling</description>
    /// <description>N</description>
    /// <description>False</description>
    /// </item>
    /// <item>
    /// <description>FailIfMissing</description>
    /// <description><b>True</b> - Don't create the database if it does not exist, throw an error instead<br/><b>False</b> - Automatically create the database if it does not exist</description>
    /// <description>N</description>
    /// <description>False</description>
    /// </item>
    /// <item>
    /// <description>Max Page Count</description>
    /// <description>{size in pages} - Limits the maximum number of pages (limits the size) of the database</description>
    /// <description>N</description>
    /// <description>0</description>
    /// </item>
    /// <item>
    /// <description>Legacy Format</description>
    /// <description><b>True</b> - Use the more compatible legacy 3.x database format<br/><b>False</b> - Use the newer 3.3x database format which compresses numbers more effectively</description>
    /// <description>N</description>
    /// <description>False</description>
    /// </item>
    /// <item>
    /// <description>Default Timeout</description>
    /// <description>{time in seconds}<br/>The default command timeout</description>
    /// <description>N</description>
    /// <description>30</description>
    /// </item>
    /// <item>
    /// <description>Journal Mode</description>
    /// <description><b>Delete</b> - Delete the journal file after a commit<br/><b>Persist</b> - Zero out and leave the journal file on disk after a commit<br/><b>Off</b> - Disable the rollback journal entirely</description>
    /// <description>N</description>
    /// <description>Delete</description>
    /// </item>
    /// <item>
    /// <description>Read Only</description>
    /// <description><b>True</b> - Open the database for read only access<br/><b>False</b> - Open the database for normal read/write access</description>
    /// <description>N</description>
    /// <description>False</description>
    /// </item>
    /// <item>
    /// <description>Max Pool Size</description>
    /// <description>The maximum number of connections for the given connection string that can be in the connection pool</description>
    /// <description>N</description>
    /// <description>100</description>
    /// </item>
    /// <item>
    /// <description>Default IsolationLevel</description>
    /// <description>The default transaciton isolation level</description>
    /// <description>N</description>
    /// <description>Serializable</description>
    /// </item>
    /// </list>
    /// </remarks>
#if !PLATFORM_COMPACTFRAMEWORK
    [RefreshProperties(RefreshProperties.All), DefaultValue("")]
    [Editor("SQLite.Designer.SQLiteConnectionStringEditor, SQLite.Designer, Version=" + SQLite3.DesignerVersion + ", Culture=neutral, PublicKeyToken=db937bc2d44ff139", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
    public override string ConnectionString
    {
      get
      {
        return _connectionString;
      }
      set







|




<
<
<
<
<
<















<
<
<
<
<
|
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<







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
    /// <description>UseUTF16Encoding</description>
    /// <description><b>True</b><br/><b>False</b></description>
    /// <description>N</description>
    /// <description>False</description>
    /// </item>
    /// <item>
    /// <description>DateTimeFormat</description>
    /// <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format</description>
    /// <description>N</description>
    /// <description>ISO8601</description>
    /// </item>
    /// <item>






    /// <description>Cache Size</description>
    /// <description>{size in bytes}</description>
    /// <description>N</description>
    /// <description>2000</description>
    /// </item>
    /// <item>
    /// <description>Synchronous</description>
    /// <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>
    /// <description>N</description>
    /// <description>Normal</description>
    /// </item>
    /// <item>
    /// <description>Page Size</description>
    /// <description>{size in bytes}</description>
    /// <description>N</description>





    /// <description>4096</description>

    /// </item>




























































    /// </list>
    /// </remarks>




    public override string ConnectionString
    {
      get
      {
        return _connectionString;
      }
      set
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
      }
    }

    /// <summary>
    /// Create a new SQLiteCommand and associate it with this connection.
    /// </summary>
    /// <returns>Returns an instantiated SQLiteCommand object already assigned to this connection.</returns>
    public new SQLiteCommand CreateCommand()
    {
      return new SQLiteCommand(this);
    }

    /// <summary>
    /// Forwards to the local CreateCommand() function
    /// </summary>
    /// <returns></returns>
    protected override DbCommand CreateDbCommand()
    {
      return CreateCommand();
    }

    /// <summary>
    /// Returns the filename without extension or path
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public override string DataSource
    {
      get
      {
        return _dataSource;
      }
    }

    /// <summary>
    /// Returns the string "main".
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public override string Database
    {
      get
      {
        return "main";
      }
    }

    internal static string MapUriPath(string path)
    {
        if (path.StartsWith ("file://", StringComparison.OrdinalIgnoreCase))
            return path.Substring (7);
      else if (path.StartsWith ("file:", StringComparison.OrdinalIgnoreCase))
            return path.Substring (5);
      else if (path.StartsWith ("/", StringComparison.OrdinalIgnoreCase))
            return path;
      else
            throw new InvalidOperationException ("Invalid connection string: invalid URI");
    }
    
    /// <summary>
    /// Parses the connection string into component parts
    /// </summary>
    /// <param name="connectionString">The connection string to parse</param>
    /// <returns>An array of key-value pairs representing each parameter of the connection string</returns>
    internal static SortedList<string, string> ParseConnectionString(string connectionString)
    {
      string s = connectionString;
      int n;
      SortedList<string, string> ls = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase);


      // First split into semi-colon delimited values.  The Split() function of SQLiteBase accounts for and properly
      // skips semi-colons in quoted strings
      string[] arParts = SQLiteConvert.Split(s, ';');
      string[] arPiece;

      int x = arParts.Length;
      // For each semi-colon piece, split into key and value pairs by the presence of the = sign
      for (n = 0; n < x; n++)
      {
        arPiece = SQLiteConvert.Split(arParts[n], '=');
        if (arPiece.Length == 2)
        {


          ls.Add(arPiece[0], arPiece[1]);
        }
        else throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for parameter \"{0}\"", (arPiece.Length > 0) ? arPiece[0] : "null"));
      }

      return ls;
    }

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Manual distributed transaction enlistment support
    /// </summary>
    /// <param name="transaction">The distributed transaction to enlist in</param>
    public override void EnlistTransaction(System.Transactions.Transaction transaction)
    {
      if (_enlistment != null && transaction == _enlistment._scope)
        return;
      else if (_enlistment != null)
        throw new ArgumentException("Already enlisted in a transaction");

      if (_transactionLevel > 0 && transaction != null)
        throw new ArgumentException("Unable to enlist in transaction, a local transaction already exists");
      else if (transaction == null)
        throw new ArgumentNullException("Unable to enlist in transaction, it is null");

      _enlistment = new SQLiteEnlistment(this, transaction);
    }
#endif

    /// <summary>
    /// Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value
    /// </summary>
    /// <param name="items">The list to look in</param>
    /// <param name="key">The key to find</param>
    /// <param name="defValue">The default value to return if the key is not found</param>
    /// <returns>The value corresponding to the specified key, or the default value if not found.</returns>
    static internal string FindKey(SortedList<string, string> items, string key, string defValue)
    {


      string ret;

      if (items.TryGetValue(key, out ret)) return ret;


      return defValue;
    }

    /// <summary>
    /// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>
    /// </summary>
    public override void Open()
    {
      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      SortedList<string, string> opts = ParseConnectionString(_connectionString);
      string fileName;

      if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3)
        throw new NotSupportedException("Only SQLite Version 3 is supported at this time");

      fileName = FindKey(opts, "Data Source", "");

      if (String.IsNullOrEmpty(fileName))
      {
        fileName = FindKey(opts, "Uri", "");
        if (String.IsNullOrEmpty(fileName))
          throw new ArgumentException("Data Source cannot be empty.  Use :memory: to open an in-memory database");
        else
          fileName = MapUriPath(fileName);
      }

      if (String.Compare(fileName, ":MEMORY:", StringComparison.OrdinalIgnoreCase) == 0)
        fileName = ":memory:";
      else
      {
#if PLATFORM_COMPACTFRAMEWORK
       if (fileName.StartsWith("./") || fileName.StartsWith(".\\"))
         fileName = Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase) + fileName.Substring(1);
#endif
       fileName = ExpandFileName(fileName);
      }
      try
      {
        bool usePooling = (SQLiteConvert.ToBoolean(FindKey(opts, "Pooling", Boolean.FalseString)) == true);
        int maxPoolSize = Convert.ToInt32(FindKey(opts, "Max Pool Size", "100"), CultureInfo.InvariantCulture);

        _defaultTimeout = Convert.ToInt32(FindKey(opts, "Default Timeout", "30"), CultureInfo.CurrentCulture);

        _defaultIsolation = (IsolationLevel)Enum.Parse(typeof(IsolationLevel), FindKey(opts, "Default IsolationLevel", "Serializable"), true);
        if (_defaultIsolation != IsolationLevel.Serializable && _defaultIsolation != IsolationLevel.ReadCommitted)
          throw new NotSupportedException("Invalid Default IsolationLevel specified");

        _baseSchemaName = FindKey(opts, "BaseSchemaName", DefaultBaseSchemaName);

        //string temp = FindKey(opts, "DateTimeFormat", "ISO8601");
        //if (String.Compare(temp, "ticks", StringComparison.OrdinalIgnoreCase) == 0) dateFormat = SQLiteDateFormats.Ticks;
        //else if (String.Compare(temp, "julianday", StringComparison.OrdinalIgnoreCase) == 0) dateFormat = SQLiteDateFormats.JulianDay;

        if (_sql == null)
        {
          bool bUTF16 = (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding", Boolean.FalseString)) == true);
          SQLiteDateFormats dateFormat = (SQLiteDateFormats)Enum.Parse(typeof(SQLiteDateFormats),
                                                                       FindKey(opts, "DateTimeFormat", "ISO8601"),
                                                                       true);

          DateTimeKind kind = (DateTimeKind)Enum.Parse(typeof(DateTimeKind),
              FindKey(opts, "DateTimeKind", "Unspecified"), true);

          if (bUTF16) // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
            _sql = new SQLite3_UTF16(dateFormat, kind);
          else
            _sql = new SQLite3(dateFormat, kind);
        }

        SQLiteOpenFlagsEnum flags = SQLiteOpenFlagsEnum.None;

        if (SQLiteConvert.ToBoolean(FindKey(opts, "FailIfMissing", Boolean.FalseString)) == false)
          flags |= SQLiteOpenFlagsEnum.Create;

        if (SQLiteConvert.ToBoolean(FindKey(opts, "Read Only", Boolean.FalseString)) == true)
        {
          flags |= SQLiteOpenFlagsEnum.ReadOnly;
          // SQLite will return SQLITE_MISUSE on ReadOnly and Create
          flags &= ~SQLiteOpenFlagsEnum.Create;
        }
        else
        {
          flags |= SQLiteOpenFlagsEnum.ReadWrite;
        }

        _sql.Open(fileName, flags, maxPoolSize, usePooling);

        _binaryGuid = (SQLiteConvert.ToBoolean(FindKey(opts, "BinaryGUID", Boolean.TrueString)) == true);

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

        if (String.IsNullOrEmpty(password) == false)
          _sql.SetPassword(System.Text.UTF8Encoding.UTF8.GetBytes(password));
        else if (_password != null)
          _sql.SetPassword(_password);
        _password = null;

        _dataSource = Path.GetFileNameWithoutExtension(fileName);

        _version++;

        ConnectionState oldstate = _connectionState;
        _connectionState = ConnectionState.Open;
        try
        {
          using (SQLiteCommand cmd = CreateCommand())
          {
            string defValue;

            if (fileName != ":memory:")
            {
              defValue = FindKey(opts, "Page Size", "1024");
              if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 1024)
              {
                cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA page_size={0}", defValue);
                cmd.ExecuteNonQuery();
              }
            }

            defValue = FindKey(opts, "Max Page Count", "0");
            if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 0)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA max_page_count={0}", defValue);
              cmd.ExecuteNonQuery();
            }

            defValue = FindKey(opts, "Legacy Format", Boolean.FalseString);
            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA legacy_file_format={0}", SQLiteConvert.ToBoolean(defValue) == true ? "ON" : "OFF");
            cmd.ExecuteNonQuery();

            defValue = FindKey(opts, "Synchronous", "Normal");
            if (String.Compare(defValue, "Full", StringComparison.OrdinalIgnoreCase) != 0)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA synchronous={0}", defValue);
              cmd.ExecuteNonQuery();
            }

            defValue = FindKey(opts, "Cache Size", "2000");
            if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 2000)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA cache_size={0}", defValue);
              cmd.ExecuteNonQuery();
            }

            defValue = FindKey(opts, "Journal Mode", "Default");
            if (String.Compare(defValue, "Default", StringComparison.OrdinalIgnoreCase) != 0)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA journal_mode={0}", defValue);
              cmd.ExecuteNonQuery();
            }

            defValue = FindKey(opts, "Foreign Keys", Boolean.FalseString);
            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA foreign_keys={0}", SQLiteConvert.ToBoolean(defValue) == true ? "ON" : "OFF");
            cmd.ExecuteNonQuery();
          }

          if (_commitHandler != null)
            _sql.SetCommitHook(_commitCallback);

          if (_updateHandler != null)
            _sql.SetUpdateHook(_updateCallback);

          if (_rollbackHandler != null)
            _sql.SetRollbackHook(_rollbackCallback);

#if !PLATFORM_COMPACTFRAMEWORK
          if (Transactions.Transaction.Current != null && SQLiteConvert.ToBoolean(FindKey(opts, "Enlist", Boolean.TrueString)) == true)
            EnlistTransaction(Transactions.Transaction.Current);
#endif

          _connectionState = oldstate;
          OnStateChange(ConnectionState.Open);
        }
        catch
        {
          _connectionState = oldstate;
          throw;
        }
      }
      catch (SQLiteException)
      {
        Close();
        throw;
      }
    }

    /// <summary>
    /// Gets/sets the default command timeout for newly-created commands.  This is especially useful for 
    /// commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible.
    /// This can also be set in the ConnectionString with "Default Timeout"
    /// </summary>
    public int DefaultTimeout
    {
      get { return _defaultTimeout; }
      set { _defaultTimeout = value; }
    }

    /// <summary>
    /// Returns the version of the underlying SQLite database engine
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public override string ServerVersion
    {
      get
      {
        return SQLiteVersion;
        //if (_connectionState != ConnectionState.Open)
        //  throw new InvalidOperationException();

        //return _sql.Version;
      }
    }

    /// <summary>
    /// Returns the rowid of the most recent successful INSERT into the database from this connection.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public long LastInsertRowId
    {
      get
      {
        if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for getting last insert rowid.");

        return _sql.LastInsertRowId;
      }
    }

    /// <summary>
    /// Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on
    /// this connection.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public int Changes
    {
      get
      {
        if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for getting number of changes.");

        return _sql.Changes;
      }
    }

    /// <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
    public long MemoryUsed
    {
      get
      {
        if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for getting memory used.");

        return _sql.MemoryUsed;
      }
    }

    /// <summary>
    /// Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public long MemoryHighwater
    {
      get
      {
        if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for getting maximum memory used.");

          return _sql.MemoryHighwater;
      }
    }

    /// <summary>
    /// Returns the version of the underlying SQLite database engine
    /// </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>
    /// Returns the state of the connection.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public override ConnectionState State
    {
      get
      {
        return _connectionState;
      }
    }

    /// Passes a shutdown request off to SQLite.
    public int Shutdown()
    {
        // make sure we have an instance of the base class
        if (_sql == null)
        {
            SortedList<string, string> opts = ParseConnectionString(_connectionString);

            bool bUTF16 = (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding", Boolean.FalseString)) == true);
            SQLiteDateFormats dateFormat = (SQLiteDateFormats)Enum.Parse(typeof(SQLiteDateFormats),
                                                                         FindKey(opts, "DateTimeFormat", "ISO8601"),
                                                                         true);

            DateTimeKind kind = (DateTimeKind)Enum.Parse(typeof(DateTimeKind),
                FindKey(opts, "DateTimeKind", "Unspecified"), true);

            if (bUTF16) // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
                _sql = new SQLite3_UTF16(dateFormat, kind);
            else
                _sql = new SQLite3(dateFormat, kind);
        }
        if (_sql != null) return _sql.Shutdown();
        throw new InvalidOperationException("Database connection not active.");
    }

    /// Enables or disabled extended result codes returned by SQLite
    public void SetExtendedResultCodes(bool bOnOff)
    {
      if (_sql != null) _sql.SetExtendedResultCodes(bOnOff);
    }
    /// Enables or disabled extended result codes returned by SQLite
    public int ResultCode()
    {
      if (_sql == null) 
        throw new InvalidOperationException("Database connection not valid for getting result code.");
      return _sql.ResultCode();
    }
    /// Enables or disabled extended result codes returned by SQLite
    public int ExtendedResultCode()
    {
      if (_sql == null)
        throw new InvalidOperationException("Database connection not valid for getting extended result code.");
      return _sql.ExtendedResultCode();
    }

    /// Add a log message via the SQLite sqlite3_log interface.
    public void LogMessage(int iErrCode, string zMessage)
    {
      _sql.LogMessage(iErrCode, zMessage);
    }

    /// <summary>
    /// Change the password (or assign a password) to an open database.
    /// </summary>
    /// <remarks>
    /// No readers or writers may be active for this process.  The database must already be open
    /// and if it already was password protected, the existing password must already have been supplied.
    /// </remarks>
    /// <param name="newPassword">The new password to assign to the database</param>
    public void ChangePassword(string newPassword)
    {
      ChangePassword(String.IsNullOrEmpty(newPassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(newPassword));
    }

    /// <summary>
    /// Change the password (or assign a password) to an open database.
    /// </summary>
    /// <remarks>
    /// No readers or writers may be active for this process.  The database must already be open
    /// and if it already was password protected, the existing password must already have been supplied.
    /// </remarks>
    /// <param name="newPassword">The new password to assign to the database</param>
    public void ChangePassword(byte[] newPassword)
    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException("Database must be opened before changing the password.");

      _sql.ChangePassword(newPassword);
    }

    /// <summary>
    /// Sets the password for a password-protected database.  A password-protected database is
    /// unusable for any operation until the password has been set.
    /// </summary>
    /// <param name="databasePassword">The password for the database</param>
    public void SetPassword(string databasePassword)
    {
      SetPassword(String.IsNullOrEmpty(databasePassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(databasePassword));
    }

    /// <summary>
    /// Sets the password for a password-protected database.  A password-protected database is
    /// unusable for any operation until the password has been set.
    /// </summary>
    /// <param name="databasePassword">The password for the database</param>
    public void SetPassword(byte[] databasePassword)
    {
      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException("Password can only be set before the database is opened.");

      if (databasePassword != null)
        if (databasePassword.Length == 0) databasePassword = null;

      _password = databasePassword;
    }

    /// <summary>
    /// Queries or modifies the number of retries or the retry interval (in milliseconds) for
    /// certain I/O operations that may fail due to anti-virus software.
    /// </summary>
    /// <param name="count">The number of times to retry the I/O operation.  A negative value
    /// will cause the current count to be queried and replace that negative value.</param>
    /// <param name="interval">The number of milliseconds to wait before retrying the I/O
    /// operation.  This number is multiplied by the number of retry attempts so far to come
    /// up with the final number of milliseconds to wait.  A negative value will cause the
    /// current interval to be queried and replace that negative value.</param>
    /// <returns>Zero for success, non-zero for error.</returns>
    public int SetAvRetry(ref int count, ref int interval)
    {
        if (_connectionState != ConnectionState.Open)
            throw new InvalidOperationException(
                "Database must be opened before changing the AV retry parameters.");

        int rc;
        IntPtr pArg = IntPtr.Zero;

        try
        {
            pArg = Marshal.AllocHGlobal(sizeof(int) * 2);

            Marshal.WriteInt32(pArg, 0, count);
            Marshal.WriteInt32(pArg, sizeof(int), interval);

            rc = _sql.FileControl(null, SQLITE_FCNTL_WIN32_AV_RETRY, pArg);

            if (rc == 0)
            {
                count = Marshal.ReadInt32(pArg, 0);
                interval = Marshal.ReadInt32(pArg, sizeof(int));
            }
        }
        finally
        {
            if (pArg != IntPtr.Zero)
                Marshal.FreeHGlobal(pArg);
        }

        return rc;
    }

    /// <summary>
    /// Expand the filename of the data source, resolving the |DataDirectory| macro as appropriate.
    /// </summary>
    /// <param name="sourceFile">The database filename to expand</param>
    /// <returns>The expanded path and filename of the filename</returns>
    private string ExpandFileName(string sourceFile)
    {
      if (String.IsNullOrEmpty(sourceFile)) return sourceFile;

      if (sourceFile.StartsWith(_dataDirectory, StringComparison.OrdinalIgnoreCase))
      {
        string dataDirectory;

#if PLATFORM_COMPACTFRAMEWORK
        dataDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase);
#else
        dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
        if (String.IsNullOrEmpty(dataDirectory))
          dataDirectory = AppDomain.CurrentDomain.BaseDirectory;
#endif

        if (sourceFile.Length > _dataDirectory.Length)
        {
          if (sourceFile[_dataDirectory.Length] == Path.DirectorySeparatorChar ||
              sourceFile[_dataDirectory.Length] == Path.AltDirectorySeparatorChar)
            sourceFile = sourceFile.Remove(_dataDirectory.Length, 1);
        }
        sourceFile = Path.Combine(dataDirectory, sourceFile.Substring(_dataDirectory.Length));
      }

#if !PLATFORM_COMPACTFRAMEWORK
      sourceFile = Path.GetFullPath(sourceFile);
#endif

      return sourceFile;
    }

    ///<overloads>
    /// The following commands are used to extract schema information out of the database.  Valid schema types are:
    /// <list type="bullet">
    /// <item>
    /// <description>MetaDataCollections</description>
    /// </item>
    /// <item>
    /// <description>DataSourceInformation</description>
    /// </item>
    /// <item>
    /// <description>Catalogs</description>
    /// </item>
    /// <item>
    /// <description>Columns</description>
    /// </item>
    /// <item>
    /// <description>ForeignKeys</description>
    /// </item>
    /// <item>
    /// <description>Indexes</description>
    /// </item>
    /// <item>
    /// <description>IndexColumns</description>
    /// </item>
    /// <item>
    /// <description>Tables</description>
    /// </item>
    /// <item>
    /// <description>Views</description>
    /// </item>
    /// <item>
    /// <description>ViewColumns</description>
    /// </item>
    /// </list>
    /// </overloads>
    /// <summary>
    /// Returns the MetaDataCollections schema
    /// </summary>
    /// <returns>A DataTable of the MetaDataCollections schema</returns>







|





<
<
<
<
<
<
<
|
<
<

<
<
<


<
<
|
<



|

<
<
<


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

|



<

|

|

|
>






<

|




>
>
|

<

>
|
|
|
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<

<
<
<
<



|



|

>
>
|
|
|
|
>













|
<

|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


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

<
<
|
<
|
|
<
<
|
<

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





<
<
<




<
|
|

|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<
<
<


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












<
<
<



<
<
<



<
<
<






|







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
      }
    }

    /// <summary>
    /// Create a new SQLiteCommand and associate it with this connection.
    /// </summary>
    /// <returns>Returns an instantiated SQLiteCommand object already assigned to this connection.</returns>
    protected override DbCommand CreateDbCommand()
    {
      return new SQLiteCommand(this);
    }

    /// <summary>







    /// Not implemented.  Returns null.


    /// </summary>



    public override string DataSource
    {


      get { return null; }

    }

    /// <summary>
    /// Not implemented.  Returns null.
    /// </summary>



    public override string Database
    {













      get { return null; }


    }

    /// <summary>
    /// Parses the connection string into component parts
    /// </summary>

    /// <returns>An array of key-value pairs representing each parameter of the connection string</returns>
    internal KeyValuePair<string, string>[] ParseConnectionString()
    {
      string s = _connectionString;
      int n;
      KeyValuePair<string, string> kv;
      List<KeyValuePair<string, string>> ls = new List<KeyValuePair<string, string>>();

      // First split into semi-colon delimited values.  The Split() function of SQLiteBase accounts for and properly
      // skips semi-colons in quoted strings
      string[] arParts = SQLiteConvert.Split(s, ';');
      string[] arPiece;


      // For each semi-colon piece, split into key and value pairs by the presence of the = sign
      for (n = 0; n < arParts.Length; n++)
      {
        arPiece = SQLiteConvert.Split(arParts[n], '=');
        if (arPiece.Length == 2)
        {
          kv.Key = arPiece[0];
          kv.Value = arPiece[1];
          ls.Add(kv);
        }

      }
      KeyValuePair<string, string>[] ar = new KeyValuePair<string, string>[ls.Count];
      ls.CopyTo(ar, 0);

      // Return the array of key-value pairs








      return ar;


    }









    /// <summary>
    /// Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value
    /// </summary>
    /// <param name="opts">The Key/Value pair array to look in</param>
    /// <param name="key">The key to find</param>
    /// <param name="defValue">The default value to return if the key is not found</param>
    /// <returns>The value corresponding to the specified key, or the default value if not found.</returns>
    internal string FindKey(KeyValuePair<string, string>[] opts, string key, string defValue)
    {
      for (int n = 0; n < opts.Length; n++)
      {
        if (String.Compare(opts[n].Key, key, true) == 0)
        {
          return opts[n].Value;
        }
      }
      return defValue;
    }

    /// <summary>
    /// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>
    /// </summary>
    public override void Open()
    {
      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      KeyValuePair<string, string>[] opts = ParseConnectionString();


      if (Convert.ToInt32(FindKey(opts, "Version", "3")) != 3)
        throw new NotImplementedException("Only SQLite Version 3 is supported at this time");






















      try
      {











        string strFile = FindKey(opts, "Data Source", "");





        bool bUTF16 = (Convert.ToBoolean(FindKey(opts, "UseUTF16Encoding", "False")) == true);






        if (bUTF16)

          _sql = new SQLite3_UTF16(String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "TICKS") == 0 ? DateTimeFormat.Ticks : DateTimeFormat.ISO8601);
        else


          _sql = new SQLite3(String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "TICKS") == 0 ? DateTimeFormat.Ticks : DateTimeFormat.ISO8601);
















        _sql.Open(strFile);






















        if (bUTF16 == true)









          _sql.Execute("PRAGMA encoding = 'UTF-16'");






        else



          _sql.Execute("PRAGMA encoding = 'UTF-8'");




















        _sql.Execute(String.Format("PRAGMA Synchronous={0}", FindKey(opts, "Synchronous", "Normal")));
        _sql.Execute(String.Format("PRAGMA Cache_Size={0}", FindKey(opts, "Cache Size", "2000")));



        if (String.Compare(strFile, ":MEMORY:", true) != 0)


          _sql.Execute(String.Format("PRAGMA Page_Size={0}", FindKey(opts, "Page Size", "1024")));


      }


      catch (SQLiteException e)




      {

        OnStateChange(ConnectionState.Broken);




        throw (e);
      }







      OnStateChange(ConnectionState.Open);









    }

    /// <summary>
    /// Returns the version of the underlying SQLite database engine
    /// </summary>



    public override string ServerVersion
    {
      get
      {

        if (_connectionState != ConnectionState.Open)
          throw new InvalidOperationException();

        return _sql.Version;
      }























































































    }

    /// <summary>
    /// Returns the state of the connection.
    /// </summary>



    public override ConnectionState State
    {


      get { return _connectionState; }




























































































































































































    }

    ///<overloads>
    /// The following commands are used to extract schema information out of the database.  Valid schema types are:
    /// <list type="bullet">
    /// <item>
    /// <description>MetaDataCollections</description>
    /// </item>
    /// <item>
    /// <description>DataSourceInformation</description>
    /// </item>
    /// <item>



    /// <description>Columns</description>
    /// </item>
    /// <item>



    /// <description>Indexes</description>
    /// </item>
    /// <item>



    /// <description>Tables</description>
    /// </item>
    /// <item>
    /// <description>Views</description>
    /// </item>
    /// <item>
    /// <description>Catalogs</description>
    /// </item>
    /// </list>
    /// </overloads>
    /// <summary>
    /// Returns the MetaDataCollections schema
    /// </summary>
    /// <returns>A DataTable of the MetaDataCollections schema</returns>
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
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
1749
1750
1751

1752


1753

1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
    public override DataTable GetSchema(string collectionName, string[] restrictionValues)
    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException();

      string[] parms = new string[5];

      if (restrictionValues == null) restrictionValues = new string[0];
      restrictionValues.CopyTo(parms, 0);


      switch (collectionName.ToUpper(CultureInfo.InvariantCulture))
      {
        case "METADATACOLLECTIONS":
          return Schema_MetaDataCollections();
        case "DATASOURCEINFORMATION":
          return Schema_DataSourceInformation();
        case "DATATYPES":
          return Schema_DataTypes();
        case "COLUMNS":
        case "TABLECOLUMNS":
          return Schema_Columns(parms[0], parms[2], parms[3]);
        case "INDEXES":
          return Schema_Indexes(parms[0], parms[2], parms[3]);
        case "TRIGGERS":
          return Schema_Triggers(parms[0], parms[2], parms[3]);
        case "INDEXCOLUMNS":
          return Schema_IndexColumns(parms[0], parms[2], parms[3], parms[4]);
        case "TABLES":
          return Schema_Tables(parms[0], parms[2], parms[3]);
        case "VIEWS":
          return Schema_Views(parms[0], parms[2]);
        case "VIEWCOLUMNS":
          return Schema_ViewColumns(parms[0], parms[2], parms[3]);
        case "FOREIGNKEYS":
          return Schema_ForeignKeys(parms[0], parms[2], parms[3]);
        case "CATALOGS":
          return Schema_Catalogs(parms[0]);
        case "RESERVEDWORDS":
          return Schema_ReservedWords();
      }
      throw new NotSupportedException();
    }

    private static DataTable Schema_ReservedWords()
    {
      DataTable tbl = new DataTable("MetaDataCollections");

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("ReservedWord", typeof(string));
      tbl.Columns.Add("MaximumVersion", typeof(string));
      tbl.Columns.Add("MinimumVersion", typeof(string));

      tbl.BeginLoadData();
      DataRow row;
      foreach (string word in SR.Keywords.Split(new char[] { ',' }))
      {
        row = tbl.NewRow();
        row[0] = word;
        tbl.Rows.Add(row);
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Builds a MetaDataCollections schema datatable
    /// </summary>
    /// <returns>DataTable</returns>
    private static DataTable Schema_MetaDataCollections()
    {
      DataTable tbl = new DataTable("MetaDataCollections");


      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CollectionName", typeof(string));
      tbl.Columns.Add("NumberOfRestrictions", typeof(int));
      tbl.Columns.Add("NumberOfIdentifierParts", typeof(int));

      tbl.BeginLoadData();




      StringReader reader = new StringReader(SR.MetaDataCollections);



      tbl.ReadXml(reader);



      reader.Close();
















      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Builds a DataSourceInformation datatable
    /// </summary>
    /// <returns>DataTable</returns>
    private DataTable Schema_DataSourceInformation()
    {
      DataTable tbl = new DataTable("DataSourceInformation");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add(DbMetaDataColumnNames.CompositeIdentifierSeparatorPattern, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductName, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductVersion, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductVersionNormalized, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.GroupByBehavior, typeof(int));
      tbl.Columns.Add(DbMetaDataColumnNames.IdentifierPattern, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.IdentifierCase, typeof(int));
      tbl.Columns.Add(DbMetaDataColumnNames.OrderByColumnsInSelect, typeof(bool));
      tbl.Columns.Add(DbMetaDataColumnNames.ParameterMarkerFormat, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.ParameterMarkerPattern, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.ParameterNameMaxLength, typeof(int));
      tbl.Columns.Add(DbMetaDataColumnNames.ParameterNamePattern, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.QuotedIdentifierPattern, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.QuotedIdentifierCase, typeof(int));
      tbl.Columns.Add(DbMetaDataColumnNames.StatementSeparatorPattern, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.StringLiteralPattern, typeof(string));
      tbl.Columns.Add(DbMetaDataColumnNames.SupportedJoinOperators, typeof(int));

      tbl.BeginLoadData();



      row = tbl.NewRow();
      row.ItemArray = new object[] {
        null,
        "SQLite",
        _sql.Version,
        _sql.Version,
        3,
        @"(^\[\p{Lo}\p{Lu}\p{Ll}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Nd}@$#_]*$)|(^\[[^\]\0]|\]\]+\]$)|(^\""[^\""\0]|\""\""+\""$)",
        1,
        false,


        "{0}",
        @"@[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$)",
        255,
        @"^[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$)",
        @"(([^\[]|\]\])*)",
        1,
        ";",
        @"'(([^']|'')*)'",
        15



      };
      tbl.Rows.Add(row);

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Build a Columns schema
    /// </summary>
    /// <param name="strCatalog">The catalog (attached database) to query, can be null</param>
    /// <param name="strTable">The table to retrieve schema information for, must not be null</param>
    /// <param name="strColumn">The column to retrieve schema information for, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Columns(string strCatalog, string strTable, string strColumn)
    {
      DataTable tbl = new DataTable("Columns");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool));
      tbl.Columns.Add("COLUMN_DEFAULT", typeof(string));
      tbl.Columns.Add("COLUMN_FLAGS", typeof(long));
      tbl.Columns.Add("IS_NULLABLE", typeof(bool));
      tbl.Columns.Add("DATA_TYPE", typeof(string));
      tbl.Columns.Add("TYPE_GUID", typeof(Guid));
      tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(int));
      tbl.Columns.Add("CHARACTER_OCTET_LENGTH", typeof(int));
      tbl.Columns.Add("NUMERIC_PRECISION", typeof(int));
      tbl.Columns.Add("NUMERIC_SCALE", typeof(int));
      tbl.Columns.Add("DATETIME_PRECISION", typeof(long));
      tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string));
      tbl.Columns.Add("COLLATION_CATALOG", typeof(string));
      tbl.Columns.Add("COLLATION_SCHEMA", typeof(string));
      tbl.Columns.Add("COLLATION_NAME", typeof(string));
      tbl.Columns.Add("DOMAIN_CATALOG", typeof(string));
      tbl.Columns.Add("DOMAIN_NAME", typeof(string));
      tbl.Columns.Add("DESCRIPTION", typeof(string));
      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));
      tbl.Columns.Add("EDM_TYPE", typeof(string));
      tbl.Columns.Add("AUTOINCREMENT", typeof(bool));
      tbl.Columns.Add("UNIQUE", typeof(bool));

      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;

      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table' OR [type] LIKE 'view'", strCatalog, master), this))
      using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
      {
        while (rdTables.Read())
        {
          if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), StringComparison.OrdinalIgnoreCase) == 0)
          {
            try
            {
              using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))
              using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))
              using (DataTable tblSchema = rd.GetSchemaTable(true, true))
              {
                foreach (DataRow schemaRow in tblSchema.Rows)
                {
                  if (String.Compare(schemaRow[SchemaTableColumn.ColumnName].ToString(), strColumn, StringComparison.OrdinalIgnoreCase) == 0
                    || strColumn == null)
                  {
                    row = tbl.NewRow();


                    row["NUMERIC_PRECISION"] = schemaRow[SchemaTableColumn.NumericPrecision];
                    row["NUMERIC_SCALE"] = schemaRow[SchemaTableColumn.NumericScale];
                    row["TABLE_NAME"] = rdTables.GetString(2);
                    row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName];
                    row["TABLE_CATALOG"] = strCatalog;
                    row["ORDINAL_POSITION"] = schemaRow[SchemaTableColumn.ColumnOrdinal];
                    row["COLUMN_HASDEFAULT"] = (schemaRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value);
                    row["COLUMN_DEFAULT"] = schemaRow[SchemaTableOptionalColumn.DefaultValue];
                    row["IS_NULLABLE"] = schemaRow[SchemaTableColumn.AllowDBNull];
                    row["DATA_TYPE"] = schemaRow["DataTypeName"].ToString().ToLower(CultureInfo.InvariantCulture);
                    row["EDM_TYPE"] = SQLiteConvert.DbTypeToTypeName((DbType)schemaRow[SchemaTableColumn.ProviderType]).ToString().ToLower(CultureInfo.InvariantCulture);
                    row["CHARACTER_MAXIMUM_LENGTH"] = schemaRow[SchemaTableColumn.ColumnSize];
                    row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName];
                    row["PRIMARY_KEY"] = schemaRow[SchemaTableColumn.IsKey];
                    row["AUTOINCREMENT"] = schemaRow[SchemaTableOptionalColumn.IsAutoIncrement];
                    row["COLLATION_NAME"] = schemaRow["CollationType"];
                    row["UNIQUE"] = schemaRow[SchemaTableColumn.IsUnique];
                    tbl.Rows.Add(row);
                  }
                }
              }
            }
            catch(SQLiteException)
            {
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Returns index information for the given database and catalog
    /// </summary>
    /// <param name="strCatalog">The catalog (attached database) to query, can be null</param>
    /// <param name="strIndex">The name of the index to retrieve information for, can be null</param>
    /// <param name="strTable">The table to retrieve index information for, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Indexes(string strCatalog, string strTable, string strIndex)
    {
      DataTable tbl = new DataTable("Indexes");
      DataRow row;
      List<int> primaryKeys = new List<int>();
      bool maybeRowId;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("INDEX_CATALOG", typeof(string));
      tbl.Columns.Add("INDEX_SCHEMA", typeof(string));
      tbl.Columns.Add("INDEX_NAME", typeof(string));
      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));
      tbl.Columns.Add("UNIQUE", typeof(bool));
      tbl.Columns.Add("CLUSTERED", typeof(bool));
      tbl.Columns.Add("TYPE", typeof(int));
      tbl.Columns.Add("FILL_FACTOR", typeof(int));
      tbl.Columns.Add("INITIAL_SIZE", typeof(int));
      tbl.Columns.Add("NULLS", typeof(int));
      tbl.Columns.Add("SORT_BOOKMARKS", typeof(bool));
      tbl.Columns.Add("AUTO_UPDATE", typeof(bool));
      tbl.Columns.Add("NULL_COLLATION", typeof(int));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
      tbl.Columns.Add("COLLATION", typeof(short));
      tbl.Columns.Add("CARDINALITY", typeof(Decimal));
      tbl.Columns.Add("PAGES", typeof(int));
      tbl.Columns.Add("FILTER_CONDITION", typeof(string));
      tbl.Columns.Add("INTEGRATED", typeof(bool));































































































      tbl.Columns.Add("INDEX_DEFINITION", typeof(string));






      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
      
      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
      using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
      {
        while (rdTables.Read())
        {
          maybeRowId = false;
          primaryKeys.Clear();
          if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, StringComparison.OrdinalIgnoreCase) == 0)
          {
            // First, look for any rowid indexes -- which sqlite defines are INTEGER PRIMARY KEY columns.
            // Such indexes are not listed in the indexes list but count as indexes just the same.
            try
            {
              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))
              using (SQLiteDataReader rdTable = cmdTable.ExecuteReader())
              {
                while (rdTable.Read())
                {
                  if (rdTable.GetInt32(5) == 1)
                  {
                    primaryKeys.Add(rdTable.GetInt32(0));

                    // If the primary key is of type INTEGER, then its a rowid and we need to make a fake index entry for it.
                    if (String.Compare(rdTable.GetString(2), "INTEGER", StringComparison.OrdinalIgnoreCase) == 0)
                      maybeRowId = true;
                  }
                }
              }
            }
            catch (SQLiteException)
            {
            }
            if (primaryKeys.Count == 1 && maybeRowId == true)
            {
              row = tbl.NewRow();

              row["TABLE_CATALOG"] = strCatalog;
              row["TABLE_NAME"] = rdTables.GetString(2);
              row["INDEX_CATALOG"] = strCatalog;
              row["PRIMARY_KEY"] = true;
              row["INDEX_NAME"] = String.Format(CultureInfo.InvariantCulture, "{1}_PK_{0}", rdTables.GetString(2), master);
              row["UNIQUE"] = true;

              if (String.Compare((string)row["INDEX_NAME"], strIndex, StringComparison.OrdinalIgnoreCase) == 0
              || strIndex == null)
              {
                tbl.Rows.Add(row);
              }

              primaryKeys.Clear();
            }

            // Now fetch all the rest of the indexes.
            try
            {
              using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_list([{1}])", strCatalog, rdTables.GetString(2)), this))
              using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
              {
                while (rd.Read())
                {
                  if (String.Compare(rd.GetString(1), strIndex, StringComparison.OrdinalIgnoreCase) == 0

                  || strIndex == null)


                  {

                    row = tbl.NewRow();

                    row["TABLE_CATALOG"] = strCatalog;
                    row["TABLE_NAME"] = rdTables.GetString(2);
                    row["INDEX_CATALOG"] = strCatalog;
                    row["INDEX_NAME"] = rd.GetString(1);
                    row["UNIQUE"] = rd.GetBoolean(2);
                    row["PRIMARY_KEY"] = false;

                    // get the index definition
                    using (SQLiteCommand cmdIndexes = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{2}] WHERE [type] LIKE 'index' AND [name] LIKE '{1}'", strCatalog, rd.GetString(1).Replace("'", "''"), master), this))
                    using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader())
                    {
                      while (rdIndexes.Read())
                      {
                        if (rdIndexes.IsDBNull(4) == false)
                          row["INDEX_DEFINITION"] = rdIndexes.GetString(4);
                        break;
                      }
                    }

                    // Now for the really hard work.  Figure out which index is the primary key index.
                    // The only way to figure it out is to check if the index was an autoindex and if we have a non-rowid
                    // primary key, and all the columns in the given index match the primary key columns
                    if (primaryKeys.Count > 0 && rd.GetString(1).StartsWith("sqlite_autoindex_" + rdTables.GetString(2), StringComparison.InvariantCultureIgnoreCase) == true)
                    {
                      using (SQLiteCommand cmdDetails = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rd.GetString(1)), this))
                      using (SQLiteDataReader rdDetails = cmdDetails.ExecuteReader())
                      {
                        int nMatches = 0;
                        while (rdDetails.Read())
                        {
                          if (primaryKeys.Contains(rdDetails.GetInt32(1)) == false)
                          {
                            nMatches = 0;
                            break;
                          }
                          nMatches++;
                        }
                        if (nMatches == primaryKeys.Count)
                        {
                          row["PRIMARY_KEY"] = true;
                          primaryKeys.Clear();
                        }
                      }
                    }

                    tbl.Rows.Add(row);
                  }
                }
              }
            }
            catch (SQLiteException)
            {
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    private DataTable Schema_Triggers(string catalog, string table, string triggerName)
    {
      DataTable tbl = new DataTable("Triggers");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("TRIGGER_NAME", typeof(string));
      tbl.Columns.Add("TRIGGER_DEFINITION", typeof(string));

      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(table)) table = null;
      if (String.IsNullOrEmpty(catalog)) catalog = "main";
      string master = (String.Compare(catalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[{1}] WHERE [type] LIKE 'trigger'", catalog, master), this))
      using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
      {
        while (rd.Read())
        {
          if (String.Compare(rd.GetString(1), triggerName, StringComparison.OrdinalIgnoreCase) == 0
            || triggerName == null)
          {
            if (table == null || String.Compare(table, rd.GetString(2), StringComparison.OrdinalIgnoreCase) == 0)
            {
              row = tbl.NewRow();

              row["TABLE_CATALOG"] = catalog;
              row["TABLE_NAME"] = rd.GetString(2);
              row["TRIGGER_NAME"] = rd.GetString(1);
              row["TRIGGER_DEFINITION"] = rd.GetString(4);

              tbl.Rows.Add(row);
            }
          }
        }
      }
      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Retrieves table schema information for the database and catalog
    /// </summary>
    /// <param name="strCatalog">The catalog (attached database) to retrieve tables on</param>
    /// <param name="strTable">The table to retrieve, can be null</param>
    /// <param name="strType">The table type, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Tables(string strCatalog, string strTable, string strType)
    {
      DataTable tbl = new DataTable("Tables");
      DataRow row;
      string strItem;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("TABLE_TYPE", typeof(string));
      tbl.Columns.Add("TABLE_ID", typeof(long));
      tbl.Columns.Add("TABLE_ROOTPAGE", typeof(int));
      tbl.Columns.Add("TABLE_DEFINITION", typeof(string));
      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
      using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
      {
        while (rd.Read())
        {
          strItem = rd.GetString(0);
          if (String.Compare(rd.GetString(2), 0, "SQLITE_", 0, 7, StringComparison.OrdinalIgnoreCase) == 0)
            strItem = "SYSTEM_TABLE";

          if (String.Compare(strType, strItem, StringComparison.OrdinalIgnoreCase) == 0
            || strType == null)
          {
            if (String.Compare(rd.GetString(2), strTable, StringComparison.OrdinalIgnoreCase) == 0
              || strTable == null)
            {
              row = tbl.NewRow();

              row["TABLE_CATALOG"] = strCatalog;
              row["TABLE_NAME"] = rd.GetString(2);
              row["TABLE_TYPE"] = strItem;
              row["TABLE_ID"] = rd.GetInt64(5);
              row["TABLE_ROOTPAGE"] = rd.GetInt32(3);
              row["TABLE_DEFINITION"] = rd.GetString(4);

              tbl.Rows.Add(row);
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Retrieves view schema information for the database
    /// </summary>
    /// <param name="strCatalog">The catalog (attached database) to retrieve views on</param>
    /// <param name="strView">The view name, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Views(string strCatalog, string strView)
    {
      DataTable tbl = new DataTable("Views");
      DataRow row;
      string strItem;
      int nPos;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("VIEW_DEFINITION", typeof(string));
      tbl.Columns.Add("CHECK_OPTION", typeof(bool));
      tbl.Columns.Add("IS_UPDATABLE", typeof(bool));
      tbl.Columns.Add("DESCRIPTION", typeof(string));
      tbl.Columns.Add("DATE_CREATED", typeof(DateTime));
      tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime));

      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this))
      using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
      {
        while (rd.Read())
        {
          if (String.Compare(rd.GetString(1), strView, StringComparison.OrdinalIgnoreCase) == 0
            || String.IsNullOrEmpty(strView))
          {
            strItem = rd.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ');
            nPos = CultureInfo.InvariantCulture.CompareInfo.IndexOf(strItem, " AS ", CompareOptions.IgnoreCase);
            if (nPos > -1)
            {
              strItem = strItem.Substring(nPos + 4).Trim();
              row = tbl.NewRow();

              row["TABLE_CATALOG"] = strCatalog;
              row["TABLE_NAME"] = rd.GetString(2);
              row["IS_UPDATABLE"] = false;
              row["VIEW_DEFINITION"] = strItem;

              tbl.Rows.Add(row);
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Retrieves catalog (attached databases) schema information for the database
    /// </summary>
    /// <param name="strCatalog">The catalog to retrieve, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Catalogs(string strCatalog)
    {
      DataTable tbl = new DataTable("Catalogs");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CATALOG_NAME", typeof(string));
      tbl.Columns.Add("DESCRIPTION", typeof(string));
      tbl.Columns.Add("ID", typeof(long));

      tbl.BeginLoadData();

      using (SQLiteCommand cmd = new SQLiteCommand("PRAGMA database_list", this))
      using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
      {
        while (rd.Read())
        {
          if (String.Compare(rd.GetString(1), strCatalog, StringComparison.OrdinalIgnoreCase) == 0
            || strCatalog == null)
          {
            row = tbl.NewRow();

            row["CATALOG_NAME"] = rd.GetString(1);
            row["DESCRIPTION"] = rd.GetString(2);
            row["ID"] = rd.GetInt64(0);

            tbl.Rows.Add(row);
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    private DataTable Schema_DataTypes()
    {
      DataTable tbl = new DataTable("DataTypes");

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TypeName", typeof(String));
      tbl.Columns.Add("ProviderDbType", typeof(int));
      tbl.Columns.Add("ColumnSize", typeof(long));
      tbl.Columns.Add("CreateFormat", typeof(String));
      tbl.Columns.Add("CreateParameters", typeof(String));
      tbl.Columns.Add("DataType", typeof(String));
      tbl.Columns.Add("IsAutoIncrementable", typeof(bool));
      tbl.Columns.Add("IsBestMatch", typeof(bool));
      tbl.Columns.Add("IsCaseSensitive", typeof(bool));
      tbl.Columns.Add("IsFixedLength", typeof(bool));
      tbl.Columns.Add("IsFixedPrecisionScale", typeof(bool));
      tbl.Columns.Add("IsLong", typeof(bool));
      tbl.Columns.Add("IsNullable", typeof(bool));
      tbl.Columns.Add("IsSearchable", typeof(bool));
      tbl.Columns.Add("IsSearchableWithLike", typeof(bool));
      tbl.Columns.Add("IsLiteralSupported", typeof(bool));
      tbl.Columns.Add("LiteralPrefix", typeof(String));
      tbl.Columns.Add("LiteralSuffix", typeof(String));
      tbl.Columns.Add("IsUnsigned", typeof(bool));
      tbl.Columns.Add("MaximumScale", typeof(short));
      tbl.Columns.Add("MinimumScale", typeof(short));
      tbl.Columns.Add("IsConcurrencyType", typeof(bool));

      tbl.BeginLoadData();

      StringReader reader = new StringReader(SR.DataTypes);
      tbl.ReadXml(reader);
      reader.Close();

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Returns the base column information for indexes in a database
    /// </summary>
    /// <param name="strCatalog">The catalog to retrieve indexes for (can be null)</param>
    /// <param name="strTable">The table to restrict index information by (can be null)</param>
    /// <param name="strIndex">The index to restrict index information by (can be null)</param>
    /// <param name="strColumn">The source column to restrict index information by (can be null)</param>
    /// <returns>A DataTable containing the results</returns>
    private DataTable Schema_IndexColumns(string strCatalog, string strTable, string strIndex, string strColumn)
    {
      DataTable tbl = new DataTable("IndexColumns");
      DataRow row;
      List<KeyValuePair<int, string>> primaryKeys = new List<KeyValuePair<int, string>>();
      bool maybeRowId;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string));
      tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string));
      tbl.Columns.Add("CONSTRAINT_NAME", typeof(string));
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("INDEX_NAME", typeof(string));
      tbl.Columns.Add("COLLATION_NAME", typeof(string));
      tbl.Columns.Add("SORT_MODE", typeof(string));
      tbl.Columns.Add("CONFLICT_OPTION", typeof(int));

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;

      tbl.BeginLoadData();

      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
      using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
      {
        while (rdTables.Read())
        {
          maybeRowId = false;
          primaryKeys.Clear();
          if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, StringComparison.OrdinalIgnoreCase) == 0)
          {
            try
            {
              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))
              using (SQLiteDataReader rdTable = cmdTable.ExecuteReader())
              {
                while (rdTable.Read())
                {
                  if (rdTable.GetInt32(5) == 1) // is a primary key
                  {
                    primaryKeys.Add(new KeyValuePair<int, string>(rdTable.GetInt32(0), rdTable.GetString(1)));
                    // Is an integer -- could be a rowid if no other primary keys exist in the table
                    if (String.Compare(rdTable.GetString(2), "INTEGER", StringComparison.OrdinalIgnoreCase) == 0)
                      maybeRowId = true;
                  }
                }
              }
            }
            catch (SQLiteException)
            {
            }
            // This is a rowid row
            if (primaryKeys.Count == 1 && maybeRowId == true)
            {
              row = tbl.NewRow();
              row["CONSTRAINT_CATALOG"] = strCatalog;
              row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "{1}_PK_{0}", rdTables.GetString(2), master);
              row["TABLE_CATALOG"] = strCatalog;
              row["TABLE_NAME"] = rdTables.GetString(2);
              row["COLUMN_NAME"] = primaryKeys[0].Value;
              row["INDEX_NAME"] = row["CONSTRAINT_NAME"];
              row["ORDINAL_POSITION"] = 0; // primaryKeys[0].Key;
              row["COLLATION_NAME"] = "BINARY";
              row["SORT_MODE"] = "ASC";
              row["CONFLICT_OPTION"] = 2;

              if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, (string)row["INDEX_NAME"], StringComparison.OrdinalIgnoreCase) == 0)
                tbl.Rows.Add(row);
            }

            using (SQLiteCommand cmdIndexes = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{2}] WHERE [type] LIKE 'index' AND [tbl_name] LIKE '{1}'", strCatalog, rdTables.GetString(2).Replace("'", "''"), master), this))
            using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader())
            {
              while (rdIndexes.Read())
              {
                int ordinal = 0;
                if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, rdIndexes.GetString(1), StringComparison.OrdinalIgnoreCase) == 0)
                {
                  try
                  {
                    using (SQLiteCommand cmdIndex = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rdIndexes.GetString(1)), this))
                    using (SQLiteDataReader rdIndex = cmdIndex.ExecuteReader())
                    {
                      while (rdIndex.Read())
                      {
                        row = tbl.NewRow();
                        row["CONSTRAINT_CATALOG"] = strCatalog;
                        row["CONSTRAINT_NAME"] = rdIndexes.GetString(1);
                        row["TABLE_CATALOG"] = strCatalog;
                        row["TABLE_NAME"] = rdIndexes.GetString(2);
                        row["COLUMN_NAME"] = rdIndex.GetString(2);
                        row["INDEX_NAME"] = rdIndexes.GetString(1);
                        row["ORDINAL_POSITION"] = ordinal; // rdIndex.GetInt32(1);

                        string collationSequence;
                        int sortMode;
                        int onError;
                        _sql.GetIndexColumnExtendedInfo(strCatalog, rdIndexes.GetString(1), rdIndex.GetString(2), out sortMode, out onError, out collationSequence);

                        if (String.IsNullOrEmpty(collationSequence) == false)
                          row["COLLATION_NAME"] = collationSequence;

                        row["SORT_MODE"] = (sortMode == 0) ? "ASC" : "DESC";
                        row["CONFLICT_OPTION"] = onError;

                        ordinal++;

                        if (String.IsNullOrEmpty(strColumn) || String.Compare(strColumn, row["COLUMN_NAME"].ToString(), StringComparison.OrdinalIgnoreCase) == 0)
                          tbl.Rows.Add(row);
                      }
                    }
                  }
                  catch (SQLiteException)
                  {
                  }
                }
              }
            }
          }
        }
      }

      tbl.EndLoadData();
      tbl.AcceptChanges();

      return tbl;
    }

    /// <summary>
    /// Returns detailed column information for a specified view
    /// </summary>
    /// <param name="strCatalog">The catalog to retrieve columns for (can be null)</param>
    /// <param name="strView">The view to restrict column information by (can be null)</param>
    /// <param name="strColumn">The source column to restrict column information by (can be null)</param>
    /// <returns>A DataTable containing the results</returns>
    private DataTable Schema_ViewColumns(string strCatalog, string strView, string strColumn)
    {
      DataTable tbl = new DataTable("ViewColumns");
      DataRow row;
      string strSql;
      int n;
      DataRow schemaRow;
      DataRow viewRow;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("VIEW_CATALOG", typeof(string));
      tbl.Columns.Add("VIEW_SCHEMA", typeof(string));
      tbl.Columns.Add("VIEW_NAME", typeof(string));
      tbl.Columns.Add("VIEW_COLUMN_NAME", typeof(String));
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool));
      tbl.Columns.Add("COLUMN_DEFAULT", typeof(string));
      tbl.Columns.Add("COLUMN_FLAGS", typeof(long));
      tbl.Columns.Add("IS_NULLABLE", typeof(bool));
      tbl.Columns.Add("DATA_TYPE", typeof(string));
      tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(int));
      tbl.Columns.Add("NUMERIC_PRECISION", typeof(int));
      tbl.Columns.Add("NUMERIC_SCALE", typeof(int));
      tbl.Columns.Add("DATETIME_PRECISION", typeof(long));
      tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string));
      tbl.Columns.Add("COLLATION_CATALOG", typeof(string));
      tbl.Columns.Add("COLLATION_SCHEMA", typeof(string));
      tbl.Columns.Add("COLLATION_NAME", typeof(string));
      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));
      tbl.Columns.Add("EDM_TYPE", typeof(string));
      tbl.Columns.Add("AUTOINCREMENT", typeof(bool));
      tbl.Columns.Add("UNIQUE", typeof(bool));

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
      
      tbl.BeginLoadData();

      using (SQLiteCommand cmdViews = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this))
      using (SQLiteDataReader rdViews = cmdViews.ExecuteReader())
      {
        while (rdViews.Read())
        {
          if (String.IsNullOrEmpty(strView) || String.Compare(strView, rdViews.GetString(2), StringComparison.OrdinalIgnoreCase) == 0)
          {
            using (SQLiteCommand cmdViewSelect = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdViews.GetString(2)), this))
            {
              strSql = rdViews.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ');
              n = CultureInfo.InvariantCulture.CompareInfo.IndexOf(strSql, " AS ", CompareOptions.IgnoreCase);
              if (n < 0)
                continue;

              strSql = strSql.Substring(n + 4);

              using (SQLiteCommand cmd = new SQLiteCommand(strSql, this))
              using (SQLiteDataReader rdViewSelect = cmdViewSelect.ExecuteReader(CommandBehavior.SchemaOnly))
              using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))
              using (DataTable tblSchemaView = rdViewSelect.GetSchemaTable(false, false))
              using (DataTable tblSchema = rd.GetSchemaTable(false, false))
              {
                for (n = 0; n < tblSchema.Rows.Count; n++)
                {
                  viewRow = tblSchemaView.Rows[n];
                  schemaRow = tblSchema.Rows[n];

                  if (String.Compare(viewRow[SchemaTableColumn.ColumnName].ToString(), strColumn, StringComparison.OrdinalIgnoreCase) == 0
                    || strColumn == null)
                  {
                    row = tbl.NewRow();

                    row["VIEW_CATALOG"] = strCatalog;
                    row["VIEW_NAME"] = rdViews.GetString(2);
                    row["TABLE_CATALOG"] = strCatalog;
                    row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName];
                    row["TABLE_NAME"] = schemaRow[SchemaTableColumn.BaseTableName];
                    row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.BaseColumnName];
                    row["VIEW_COLUMN_NAME"] = viewRow[SchemaTableColumn.ColumnName];
                    row["COLUMN_HASDEFAULT"] = (viewRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value);
                    row["COLUMN_DEFAULT"] = viewRow[SchemaTableOptionalColumn.DefaultValue];
                    row["ORDINAL_POSITION"] = viewRow[SchemaTableColumn.ColumnOrdinal];
                    row["IS_NULLABLE"] = viewRow[SchemaTableColumn.AllowDBNull];
                    row["DATA_TYPE"] = viewRow["DataTypeName"]; // SQLiteConvert.DbTypeToType((DbType)viewRow[SchemaTableColumn.ProviderType]).ToString();
                    row["EDM_TYPE"] = SQLiteConvert.DbTypeToTypeName((DbType)viewRow[SchemaTableColumn.ProviderType]).ToString().ToLower(CultureInfo.InvariantCulture);
                    row["CHARACTER_MAXIMUM_LENGTH"] = viewRow[SchemaTableColumn.ColumnSize];
                    row["TABLE_SCHEMA"] = viewRow[SchemaTableColumn.BaseSchemaName];
                    row["PRIMARY_KEY"] = viewRow[SchemaTableColumn.IsKey];
                    row["AUTOINCREMENT"] = viewRow[SchemaTableOptionalColumn.IsAutoIncrement];
                    row["COLLATION_NAME"] = viewRow["CollationType"];
                    row["UNIQUE"] = viewRow[SchemaTableColumn.IsUnique];
                    tbl.Rows.Add(row);
                  }
                }
              }
            }
          }
        }
      }

      tbl.EndLoadData();
      tbl.AcceptChanges();

      return tbl;
    }

    /// <summary>
    /// Retrieves foreign key information from the specified set of filters
    /// </summary>
    /// <param name="strCatalog">An optional catalog to restrict results on</param>
    /// <param name="strTable">An optional table to restrict results on</param>
    /// <param name="strKeyName">An optional foreign key name to restrict results on</param>
    /// <returns>A DataTable with the results of the query</returns>
    private DataTable Schema_ForeignKeys(string strCatalog, string strTable, string strKeyName)
    {
      DataTable tbl = new DataTable("ForeignKeys");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string));
      tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string));
      tbl.Columns.Add("CONSTRAINT_NAME", typeof(string));
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("CONSTRAINT_TYPE", typeof(string));
      tbl.Columns.Add("IS_DEFERRABLE", typeof(bool));
      tbl.Columns.Add("INITIALLY_DEFERRED", typeof(bool));
      tbl.Columns.Add("FKEY_FROM_COLUMN", typeof(string));
      tbl.Columns.Add("FKEY_FROM_ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("FKEY_TO_CATALOG", typeof(string));
      tbl.Columns.Add("FKEY_TO_SCHEMA", typeof(string));
      tbl.Columns.Add("FKEY_TO_TABLE", typeof(string));
      tbl.Columns.Add("FKEY_TO_COLUMN", typeof(string));
      tbl.Columns.Add("FKEY_ON_UPDATE", typeof(string));
      tbl.Columns.Add("FKEY_ON_DELETE", typeof(string));
      tbl.Columns.Add("FKEY_MATCH", typeof(string));

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;

      tbl.BeginLoadData();

      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
      using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
      {
        while (rdTables.Read())
        {
          if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), StringComparison.OrdinalIgnoreCase) == 0)
          {
            try
            {
              using (SQLiteCommandBuilder builder = new SQLiteCommandBuilder())
              //using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))
              //using (SQLiteDataReader rdTable = cmdTable.ExecuteReader(CommandBehavior.SchemaOnly))
              using (SQLiteCommand cmdKey = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].foreign_key_list([{1}])", strCatalog, rdTables.GetString(2)), this))
              using (SQLiteDataReader rdKey = cmdKey.ExecuteReader())
              {
                while (rdKey.Read())
                {
                  row = tbl.NewRow();
                  row["CONSTRAINT_CATALOG"] = strCatalog;
                  row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}", rdTables[2], rdKey.GetInt32(0));
                  row["TABLE_CATALOG"] = strCatalog;
                  row["TABLE_NAME"] = builder.UnquoteIdentifier(rdTables.GetString(2));
                  row["CONSTRAINT_TYPE"] = "FOREIGN KEY";
                  row["IS_DEFERRABLE"] = false;
                  row["INITIALLY_DEFERRED"] = false;
                  row["FKEY_FROM_COLUMN"] = builder.UnquoteIdentifier(rdKey[3].ToString());
                  row["FKEY_TO_CATALOG"] = strCatalog;
                  row["FKEY_TO_TABLE"] = builder.UnquoteIdentifier(rdKey[2].ToString());
                  row["FKEY_TO_COLUMN"] = builder.UnquoteIdentifier(rdKey[4].ToString());
                  row["FKEY_FROM_ORDINAL_POSITION"] = rdKey[1];
                  row["FKEY_ON_UPDATE"] = (rdKey.FieldCount > 5) ? rdKey[5] : String.Empty;
                  row["FKEY_ON_DELETE"] = (rdKey.FieldCount > 6) ? rdKey[6] : String.Empty;
                  row["FKEY_MATCH"] = (rdKey.FieldCount > 7) ? rdKey[7] : String.Empty;

                  if (String.IsNullOrEmpty(strKeyName) || String.Compare(strKeyName, row["CONSTRAINT_NAME"].ToString(), StringComparison.OrdinalIgnoreCase) == 0)
                    tbl.Rows.Add(row);
                }
              }
            }
            catch (SQLiteException)
            {
            }
          }
        }
      }

      tbl.EndLoadData();
      tbl.AcceptChanges();

      return tbl;
    }

    /// <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
    {
      add
      {
        if (_updateHandler == null)
        {
          _updateCallback = new SQLiteUpdateCallback(UpdateCallback);
          if (_sql != null) _sql.SetUpdateHook(_updateCallback);
        }
        _updateHandler += value;
      }
      remove
      {
        _updateHandler -= value;
        if (_updateHandler == null)
        {
          if (_sql != null) _sql.SetUpdateHook(null);
          _updateCallback = null;
        }
      }
    }

    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,
        rowid));
    }

    /// <summary>
    /// This event is raised whenever SQLite is committing a transaction.
    /// Return non-zero to trigger a rollback
    /// </summary>
    public event SQLiteCommitHandler Commit
    {
      add
      {
        if (_commitHandler == null)
        {
          _commitCallback = new SQLiteCommitCallback(CommitCallback);
          if (_sql != null) _sql.SetCommitHook(_commitCallback);
        }
        _commitHandler += value;
      }
      remove
      {
        _commitHandler -= value;
        if (_commitHandler == null)
        {
          if (_sql != null) _sql.SetCommitHook(null);
          _commitCallback = null;
        }
      }
    }

    /// <summary>
    /// This event is raised whenever SQLite statement first begins executing on
    /// this connection.  It only applies to the given connection.
    /// </summary>
    public event SQLiteTraceEventHandler Trace
    {
      add
      {
        if (_traceHandler == null)
        {
          _traceCallback = new SQLiteTraceCallback(TraceCallback);
          if (_sql != null) _sql.SetTraceCallback(_traceCallback);
        }
        _traceHandler += value;
      }
      remove
      {
        _traceHandler -= value;
        if (_traceHandler == null)
        {
          if (_sql != null) _sql.SetTraceCallback(null);
            _traceCallback = null;
        }
      }
    }

    private void TraceCallback(IntPtr puser, IntPtr statement)
    {
      _traceHandler(this, new TraceEventArgs(
        SQLiteBase.UTF8ToString(statement, -1)));
    }

    /// <summary>
    /// This event is raised whenever SQLite is committing a transaction.
    /// Return non-zero to trigger a rollback
    /// </summary>
    public event EventHandler RollBack
    {
      add
      {
        if (_rollbackHandler == null)
        {
          _rollbackCallback = new SQLiteRollbackCallback(RollbackCallback);
          if (_sql != null) _sql.SetRollbackHook(_rollbackCallback);
        }
        _rollbackHandler += value;
      }
      remove
      {
        _rollbackHandler -= value;
        if (_rollbackHandler == null)
        {
          if (_sql != null) _sql.SetRollbackHook(null);
          _rollbackCallback = null;
        }
      }
    }


    private int CommitCallback(IntPtr parg)
    {
      CommitEventArgs e = new CommitEventArgs();
      _commitHandler(this, e);
      return (e.AbortTransaction == true) ? 1 : 0;
    }

    private void RollbackCallback(IntPtr parg)
    {
      _rollbackHandler(this, EventArgs.Empty);
    }

  }

  /// <summary>
  /// The I/O file cache flushing behavior for the connection
  /// </summary>
  public enum SynchronizationModes
  {
    /// <summary>
    /// Normal file flushing at critical sections of the code
    /// </summary>
    Normal = 0,
    /// <summary>
    /// Full file flushing after every write operation
    /// </summary>
    Full = 1,
    /// <summary>
    /// 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 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 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);

  /// <summary>
  /// Raised when data is inserted, updated and deleted on a given connection
  /// </summary>
  /// <param name="sender">The connection committing the transaction</param>
  /// <param name="e">The event parameters which triggered the event</param>
  public delegate void SQLiteUpdateEventHandler(object sender, UpdateEventArgs e);

  /// <summary>
  /// Raised when a statement first begins executing on a given connection
  /// </summary>
  /// <param name="sender">The connection executing the statement</param>
  /// <param name="e">Event arguments of the trace</param>
  public delegate void SQLiteTraceEventHandler(object sender, TraceEventArgs e);

  /// <summary>
  /// Whenever an update event is triggered on a connection, this enum will indicate
  /// exactly what type of operation is being performed.
  /// </summary>
  public enum UpdateEventType
  {
    /// <summary>
    /// A row is being deleted from the given database and table
    /// </summary>
    Delete = 9,
    /// <summary>
    /// A row is being inserted into the table.
    /// </summary>
    Insert = 18,
    /// <summary>
    /// A row is being updated in the table.
    /// </summary>
    Update = 23,
  }

  /// <summary>
  /// Passed during an Update callback, these event arguments detail the type of update operation being performed
  /// on the given connection.
  /// </summary>
  public class UpdateEventArgs : EventArgs
  {
    /// <summary>
    /// The name of the database being updated (usually "main" but can be any attached or temporary database)
    /// </summary>
    public readonly string Database;

    /// <summary>
    /// The name of the table being updated
    /// </summary>
    public readonly string Table;

    /// <summary>
    /// The type of update being performed (insert/update/delete)
    /// </summary>
    public readonly UpdateEventType Event;

    /// <summary>
    /// The RowId affected by this update.
    /// </summary>
    public readonly Int64 RowId;

    internal UpdateEventArgs(string database, string table, UpdateEventType eventType, Int64 rowid)
    {
      Database = database;
      Table = table;
      Event = eventType;
      RowId = rowid;
    }
  }

  /// <summary>
  /// Event arguments raised when a transaction is being committed
  /// </summary>
  public class CommitEventArgs : EventArgs
  {
    internal CommitEventArgs()
    {
    }

    /// <summary>
    /// Set to true to abort the transaction and trigger a rollback
    /// </summary>
    public bool AbortTransaction;
  }

  /// <summary>
  /// Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text
  /// </summary>
  public class TraceEventArgs : EventArgs
  {
    /// <summary>
    /// SQL statement text as the statement first begins executing
    /// </summary>
    public readonly string Statement;

    internal TraceEventArgs(string statement)
    {
      Statement = statement;
    }
  }

}







<


>
|





<
<

<


|
<
<
<
<




<
<
<
<


<
<

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


<
<
<
<
|


>

<






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







<
<
<
<





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



>
>


|




|

|
>
>
|
<
<
|
|

<
<
<
>
>
>









<
<
<
<
<
<
<





<






|




|

|
|

|










<
<
<
<



|

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

>
<
<
<
|
|
|
|
|
|
<
|
|
|
<
<
<
<
|
|
<
<
<
<
<











<
<
<
<
<
<
<
|



<
<

<
















|








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



|

<
|
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
>
|
>
>
|
>
|
<
|
|
<
<
<
|
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<











|

|


<
<
<
|
<
|


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


<
<
|
<
<
<
<
<











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

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
    public override DataTable GetSchema(string collectionName, string[] restrictionValues)
    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException();

      string[] parms = new string[5];


      restrictionValues.CopyTo(parms, 0);

      if (restrictionValues == null) restrictionValues = new string[0];
      switch (collectionName.ToUpper())
      {
        case "METADATACOLLECTIONS":
          return Schema_MetaDataCollections();
        case "DATASOURCEINFORMATION":
          return Schema_DataSourceInformation();


        case "COLUMNS":

          return Schema_Columns(parms[0], parms[2], parms[3]);
        case "INDEXES":
          return Schema_Indexes(parms[0], parms[2], parms[4]);




        case "TABLES":
          return Schema_Tables(parms[0], parms[2], parms[3]);
        case "VIEWS":
          return Schema_Views(parms[0], parms[2]);




        case "CATALOGS":
          return Schema_Catalogs(parms[0]);


      }
























      return null;
    }





    private DataTable Schema_MetaDataCollections()
    {
      DataTable tbl = new DataTable("MetaDataCollections");
      DataRow row;


      tbl.Columns.Add("CollectionName", typeof(string));
      tbl.Columns.Add("NumberOfRestrictions", typeof(int));
      tbl.Columns.Add("NumberOfIdentifierParts", typeof(int));

      tbl.BeginLoadData();

      row = tbl.NewRow();
      row.ItemArray = new object[] { "MetaDataCollections", 0, 0 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "DataSourceInformation", 0, 0 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Catalogs", 1, 1 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Columns", 4, 4 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Indexes", 5, 4 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Tables", 4, 3 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Views", 3, 3 };
      tbl.Rows.Add(row);

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }





    private DataTable Schema_DataSourceInformation()
    {
      DataTable tbl = new DataTable("DataSourceInformation");
      DataRow row;


      tbl.Columns.Add("CompositeIdentifierSeparatorPattern", typeof(string));
      tbl.Columns.Add("DataSourceProductName", typeof(string));
      tbl.Columns.Add("DataSourceProductVersion", typeof(string));
      tbl.Columns.Add("DataSourceProductVersionNormalized", typeof(string));
      tbl.Columns.Add("GroupByBehavior", typeof(int));
      tbl.Columns.Add("IdentifierPattern", typeof(string));
      tbl.Columns.Add("IdentifierCase", typeof(int));
      tbl.Columns.Add("OrderByColumnsInSelect", typeof(bool));
      tbl.Columns.Add("ParameterMarkerFormat", typeof(string));
      tbl.Columns.Add("ParameterMarkerPattern", typeof(string));
      tbl.Columns.Add("ParameterNameMaxLength", typeof(int));
      tbl.Columns.Add("ParameterNamePattern", typeof(string));
      tbl.Columns.Add("QuotedIdentifierPattern", typeof(string));
      tbl.Columns.Add("QuotedIdentifierCase", typeof(int));
      tbl.Columns.Add("StatementSeparatorPattern", typeof(string));
      tbl.Columns.Add("StringLiteralPattern", typeof(string));
      tbl.Columns.Add("SupportedJoinOperators", typeof(int));

      tbl.BeginLoadData();

      // TODO: Fixup the regular expressions to support only the SQLite stuff, they were originally cloned
      // from JET's DataSourceInformation return result.
      row = tbl.NewRow();
      row.ItemArray = new object[] {
        DBNull.Value,
        "SQLite",
        _sql.Version,
        _sql.Version,
        3,
        @"[^ ][^\.!`\[\]]*",
        1,
        DBNull.Value,
        "?",
        "?",
        0,


        DBNull.Value,
        @"`(([^`]|``)*)`",
        1,



        DBNull.Value,
        DBNull.Value,
        DBNull.Value
      };
      tbl.Rows.Add(row);

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }








    private DataTable Schema_Columns(string strCatalog, string strTable, string strColumn)
    {
      DataTable tbl = new DataTable("Columns");
      DataRow row;


      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(long));
      tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool));
      tbl.Columns.Add("COLUMN_DEFAULT", typeof(string));
      tbl.Columns.Add("COLUMN_FLAGS", typeof(long));
      tbl.Columns.Add("IS_NULLABLE", typeof(bool));
      tbl.Columns.Add("DATA_TYPE", typeof(int));
      tbl.Columns.Add("TYPE_GUID", typeof(Guid));
      tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(long));
      tbl.Columns.Add("CHARACTER_OCTET_LENGTH", typeof(long));
      tbl.Columns.Add("NUMERIC_PRECISION", typeof(int));
      tbl.Columns.Add("NUMERIC_SCALE", typeof(short));
      tbl.Columns.Add("DATETIME_PRECISION", typeof(long));
      tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string));
      tbl.Columns.Add("COLLATION_CATALOG", typeof(string));
      tbl.Columns.Add("COLLATION_SCHEMA", typeof(string));
      tbl.Columns.Add("COLLATION_NAME", typeof(string));
      tbl.Columns.Add("DOMAIN_CATALOG", typeof(string));
      tbl.Columns.Add("DOMAIN_NAME", typeof(string));
      tbl.Columns.Add("DESCRIPTION", typeof(string));





      tbl.BeginLoadData();

      if (strCatalog == null || strCatalog == "") strCatalog = "main";

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format("SELECT * FROM [{0}].[{1}]", strCatalog, strTable), this))
      {

        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {








          using (DataTable tblSchema = rd.GetSchemaTable())
          {
            foreach (DataRow schemaRow in tblSchema.Rows)
            {
              if (String.Compare(schemaRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true) == 0 || strColumn == null)

              {
                row = tbl.NewRow();

                row["TABLE_NAME"] = strTable;



                row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName];
                row["TABLE_CATALOG"] = schemaRow[SchemaTableOptionalColumn.BaseCatalogName];
                row["ORDINAL_POSITION"] = schemaRow[SchemaTableColumn.ColumnOrdinal];
                row["COLUMN_HASDEFAULT"] = (schemaRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value);
                row["COLUMN_DEFAULT"] = schemaRow[SchemaTableOptionalColumn.DefaultValue];
                row["IS_NULLABLE"] = schemaRow[SchemaTableColumn.AllowDBNull];

                row["DATA_TYPE"] = schemaRow[SchemaTableColumn.ProviderType];
                row["CHARACTER_MAXIMUM_LENGTH"] = schemaRow[SchemaTableColumn.ColumnSize];





                tbl.Rows.Add(row);
              }





            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }








    private DataTable Schema_Indexes(string strCatalog, string strIndex, string strTable)
    {
      DataTable tbl = new DataTable("Indexes");
      DataRow row;




      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("INDEX_CATALOG", typeof(string));
      tbl.Columns.Add("INDEX_SCHEMA", typeof(string));
      tbl.Columns.Add("INDEX_NAME", typeof(string));
      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));
      tbl.Columns.Add("UNIQUE", typeof(bool));
      tbl.Columns.Add("CLUSTERED", typeof(bool));
      tbl.Columns.Add("TYPE", typeof(int));
      tbl.Columns.Add("FILL_FACTOR", typeof(int));
      tbl.Columns.Add("INITIAL_SIZE", typeof(int));
      tbl.Columns.Add("NULLS", typeof(int));
      tbl.Columns.Add("SORT_BOOKMARKS", typeof(bool));
      tbl.Columns.Add("AUTO_UPDATE", typeof(bool));
      tbl.Columns.Add("NULL_COLLATION", typeof(int));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(long));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
      tbl.Columns.Add("COLLATION", typeof(short));
      tbl.Columns.Add("CARDINALITY", typeof(Decimal));
      tbl.Columns.Add("PAGES", typeof(int));
      tbl.Columns.Add("FILTER_CONDITION", typeof(string));
      tbl.Columns.Add("INTEGRATED", typeof(bool));

      tbl.BeginLoadData();

      if (strCatalog == null || strCatalog == "") strCatalog = "main";

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format("SELECT * FROM [{0}].[sqlite_master] WHERE [type] = 'index'", strCatalog), this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            if (String.Compare(rd.GetString(1), strIndex, true) == 0 || strIndex == null)
            {
              if (String.Compare(rd.GetString(2), strTable, true) == 0 || strTable == null)
              {
                row = tbl.NewRow();
                row["TABLE_CATALOG"] = strCatalog;
                row["TABLE_NAME"] = rd.GetString(2);
                row["INDEX_NAME"] = rd.GetString(1);

                tbl.Rows.Add(row);
              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    private DataTable Schema_Tables(string strCatalog, string strTable, string strType)
    {
      DataTable tbl = new DataTable("Tables");
      DataRow row;
      string strItem;

      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("TABLE_TYPE", typeof(string));
      tbl.Columns.Add("TABLE_GUID", typeof(Guid));
      tbl.Columns.Add("DESCRIPTION", typeof(string));
      tbl.Columns.Add("TABLE_PROPID", typeof(long));
      tbl.Columns.Add("DATE_CREATED", typeof(DateTime));
      tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime));

      tbl.BeginLoadData();

      if (strCatalog == null || strCatalog == "") strCatalog = "main";

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format("SELECT * FROM [{0}].[sqlite_master] WHERE [type] NOT LIKE 'index'", strCatalog), this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            strItem = rd.GetString(0).ToUpper();
            if (rd.GetString(2).ToUpper().IndexOf("SQLITE_") == 0)
              strItem = "SYSTEM TABLE";

            if (String.Compare(strItem, strType, true) == 0 || strType == null)
            {
              if (String.Compare(rd.GetString(2), strTable, true) == 0 || strTable == null)
              {
                row = tbl.NewRow();
                row["TABLE_CATALOG"] = strCatalog;
                row["TABLE_NAME"] = rd.GetString(2);
                row["TABLE_TYPE"] = strItem;

                tbl.Rows.Add(row);
              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    private DataTable Schema_Views(string strCatalog, string strView)
    {
      DataTable tbl = new DataTable("Views");
      DataRow row;
      string strItem;
      int nPos;

      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("VIEW_DEFINITION", typeof(string));
      tbl.Columns.Add("CHECK_OPTION", typeof(bool));
      tbl.Columns.Add("IS_UPDATEABLE", typeof(bool));
      tbl.Columns.Add("DESCRIPTION", typeof(string));
      tbl.Columns.Add("DATE_CREATED", typeof(DateTime));
      tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime));

      tbl.BeginLoadData();

      if (strCatalog == null || strCatalog == "") strCatalog = "main";


      using (SQLiteCommand cmd = new SQLiteCommand(String.Format("SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'view'", strCatalog), this))


      {





















































        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            if (String.Compare(rd.GetString(1), strView, true) == 0 || strView == null)
            {
              strItem = rd.GetString(4);
              nPos = Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(strItem, " AS ");
              if (nPos > -1)
              {
                strItem = strItem.Substring(nPos + 4);
                row = tbl.NewRow();

                row["TABLE_CATALOG"] = strCatalog;
                row["TABLE_NAME"] = rd.GetString(2);



                row["IS_UPDATEABLE"] = false;








                row["VIEW_DEFINITION"] = strItem;






























                tbl.Rows.Add(row);
              }





            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    private DataTable Schema_Catalogs(string strCatalog)
    {
      DataTable tbl = new DataTable("Catalogs");
      DataRow row;




      tbl.Columns.Add("CATALOG_NAME", typeof(string));

      tbl.Columns.Add("DESCRIPTION", typeof(string));

      tbl.BeginLoadData();













































      using (SQLiteCommand cmd = new SQLiteCommand("PRAGMA database_list", this))









      {





        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {







            if (strCatalog == null || String.Compare(rd.GetString(1), strCatalog, true) == 0)

            {
              row = tbl.NewRow();


              row["CATALOG_NAME"] = rd.GetString(1);





              tbl.Rows.Add(row);
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }
  }






































































































































































































































































































































































































































































































































































































































































































































































































}
Deleted System.Data.SQLite/SQLiteConnectionPool.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;

  internal static class SQLiteConnectionPool
  {
    /// <summary>
    /// Keeps track of connections made on a specified file.  The PoolVersion dictates whether old objects get
    /// returned to the pool or discarded when no longer in use.
    /// </summary>
    internal class Pool
    {
      internal readonly Queue<WeakReference> Queue = new Queue<WeakReference>();
      internal int PoolVersion;
      internal int MaxPoolSize;

      internal Pool(int version, int maxSize)
      {
        PoolVersion = version;
        MaxPoolSize = maxSize;
      }
    }

    /// <summary>
    /// The connection pool object
    /// </summary>
    private static SortedList<string, Pool> _connections = new SortedList<string, Pool>(StringComparer.OrdinalIgnoreCase);

    /// <summary>
    /// The default version number new pools will get
    /// </summary>
    private static int _poolVersion = 1;

    /// <summary>
    /// Attempt to pull a pooled connection out of the queue for active duty
    /// </summary>
    /// <param name="fileName">The filename for a desired connection</param>
    /// <param name="maxPoolSize">The maximum size the connection pool for the filename can be</param>
    /// <param name="version">The pool version the returned connection will belong to</param>
    /// <returns>Returns NULL if no connections were available.  Even if none are, the poolversion will still be a valid pool version</returns>
    internal static SQLiteConnectionHandle Remove(string fileName, int maxPoolSize, out int version)
    {
      lock (_connections)
      {
        Pool queue;

        // Default to the highest pool version
        version = _poolVersion;

        // If we didn't find a pool for this file, create one even though it will be empty.
        // We have to do this here because otherwise calling ClearPool() on the file will not work for active connections
        // that have never seen the pool yet.
        if (_connections.TryGetValue(fileName, out queue) == false)
        {
          queue = new Pool(_poolVersion, maxPoolSize);
          _connections.Add(fileName, queue);

          return null;
        }

        // We found a pool for this file, so use its version number
        version = queue.PoolVersion;
        queue.MaxPoolSize = maxPoolSize;

        ResizePool(queue, false);

        // Try and get a pooled connection from the queue
        while (queue.Queue.Count > 0)
        {
          WeakReference cnn = queue.Queue.Dequeue();
          SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle;
          if (hdl != null)
          {
            return hdl;
          }
        }
        return null;
      }
    }

    /// <summary>
    /// Clears out all pooled connections and rev's up the default pool version to force all old active objects
    /// not in the pool to get discarded rather than returned to their pools.
    /// </summary>
    internal static void ClearAllPools()
    {
      lock (_connections)
      {
        foreach (KeyValuePair<string, Pool> pair in _connections)
        {
          while (pair.Value.Queue.Count > 0)
          {
            WeakReference cnn = pair.Value.Queue.Dequeue();
            SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle;
            if (hdl != null)
            {
              hdl.Dispose();
            }
          }
          
          // Keep track of the highest revision so we can go one higher when we're finished
          if (_poolVersion <= pair.Value.PoolVersion)
            _poolVersion = pair.Value.PoolVersion + 1;
        }
        // All pools are cleared and we have a new highest version number to force all old version active items to get discarded
        // instead of going back to the queue when they are closed.
        // We can get away with this because we've pumped up the _poolVersion out of range of all active connections, so they
        // will all get discarded when they try to put themselves back in their pool.
        _connections.Clear();
      }
    }

    /// <summary>
    /// Clear a given pool for a given filename.  Discards anything in the pool for the given file, and revs the pool
    /// version so current active objects on the old version of the pool will get discarded rather than be returned to the pool.
    /// </summary>
    /// <param name="fileName">The filename of the pool to clear</param>
    internal static void ClearPool(string fileName)
    {
      lock (_connections)
      {
        Pool queue;
        if (_connections.TryGetValue(fileName, out queue) == true)
        {
          queue.PoolVersion++;
          while (queue.Queue.Count > 0)
          {
            WeakReference cnn = queue.Queue.Dequeue();
            SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle;
            if (hdl != null)
            {
              hdl.Dispose();
            }
          }
        }
      }
    }

    /// <summary>
    /// Return a connection to the pool for someone else to use.
    /// </summary>
    /// <param name="fileName">The filename of the pool to use</param>
    /// <param name="hdl">The connection handle to pool</param>
    /// <param name="version">The pool version the handle was created under</param>
    /// <remarks>
    /// If the version numbers don't match between the connection and the pool, then the handle is discarded.
    /// </remarks>
    internal static void Add(string fileName, SQLiteConnectionHandle hdl, int version)
    {
      lock (_connections)
      {
        // If the queue doesn't exist in the pool, then it must've been cleared sometime after the connection was created.
        Pool queue;
        if (_connections.TryGetValue(fileName, out queue) == true && version == queue.PoolVersion)
        {
          ResizePool(queue, true);
          queue.Queue.Enqueue(new WeakReference(hdl, false));
          GC.KeepAlive(hdl);
        }
        else
        {
          hdl.Close();
        }
      }
    }

    /// <summary>
    /// We don't have to thread-lock anything in this function, because it's only called by other functions above
    /// which already have a thread-safe lock.
    /// </summary>
    /// <param name="queue">The queue to resize</param>
    /// <param name="forAdding">If a function intends to add to the pool, this is true, which forces the resize
    /// to take one more than it needs from the pool</param>
    private static void ResizePool(Pool queue, bool forAdding)
    {
      int target = queue.MaxPoolSize;

      if (forAdding && target > 0) target--;

      while (queue.Queue.Count > target)
      {
        WeakReference cnn = queue.Queue.Dequeue();
        SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle;
        if (hdl != null)
        {
          hdl.Dispose();
        }
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































Changes to System.Data.SQLite/SQLiteConnectionStringBuilder.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

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

#if !PLATFORM_COMPACTFRAMEWORK
  /// <summary>
  /// SQLite implementation of DbConnectionStringBuilder.
  /// </summary>
  [DefaultProperty("DataSource")]
  [DefaultMember("Item")]
  public sealed class SQLiteConnectionStringBuilder : DbConnectionStringBuilder
  {
    /// <summary>
    /// Properties of this class
    /// </summary>
    private Hashtable _properties;

    /// <overloads>
    /// Constructs a new instance of the class
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteConnectionStringBuilder()
    {
      Initialize(null);
    }

    /// <summary>
    /// Constructs a new instance of the class using the specified connection string.
    /// </summary>
    /// <param name="connectionString">The connection string to parse</param>
    public SQLiteConnectionStringBuilder(string connectionString)
    {
      Initialize(connectionString);
    }

    /// <summary>
    /// Private initializer, which assigns the connection string and resets the builder
    /// </summary>
    /// <param name="cnnString">The connection string to assign</param>
    private void Initialize(string cnnString)
    {
      _properties = new Hashtable(StringComparer.OrdinalIgnoreCase);


      try

      {

        base.GetProperties(_properties);
      }
      catch(NotImplementedException)

      {


        FallbackGetProperties(_properties);


      }



      if (String.IsNullOrEmpty(cnnString) == false)
        ConnectionString = cnnString;
    }

    /// <summary>
    /// Gets/Sets the default version of the SQLite engine to instantiate.  Currently the only valid value is 3, indicating version 3 of the sqlite library.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(3)]
    public int Version
    {
      get
      {
        object value;
        TryGetValue("version", out value);
        return Convert.ToInt32(value, CultureInfo.CurrentCulture);
      }
      set
      {
        if (value != 3)
          throw new NotSupportedException();

        this["version"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the synchronization mode (file flushing) of the connection string.  Default is "Normal".
    /// </summary>
    [DisplayName("Synchronous")]
    [Browsable(true)]
    [DefaultValue(SynchronizationModes.Normal)]
    public SynchronizationModes SyncMode
    {
      get
      {
        object value;
        TryGetValue("synchronous", out value);
        if (value is string)


          return (SynchronizationModes)TypeDescriptor.GetConverter(typeof(SynchronizationModes)).ConvertFrom(value);

        else return (SynchronizationModes)value;



      }
      set
      {




        this["synchronous"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the encoding for the connection string.  The default is "False" which indicates UTF-8 encoding.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(false)]
    public bool UseUTF16Encoding
    {
      get
      {
        object value;
        TryGetValue("useutf16encoding", out value);
        return SQLiteConvert.ToBoolean(value);
      }
      set
      {
        this["useutf16encoding"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets whether or not to use connection pooling.  The default is "False"
    /// </summary>
    [Browsable(true)]
    [DefaultValue(false)]
    public bool Pooling
    {
      get
      {
        object value;
        TryGetValue("pooling", out value);
        return SQLiteConvert.ToBoolean(value);
      }
      set
      {
        this["pooling"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets whethor not to store GUID's in binary format.  The default is True
    /// which saves space in the database.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(true)]
    public bool BinaryGUID
    {
      get
      {
        object value;
        TryGetValue("binaryguid", out value);
        return SQLiteConvert.ToBoolean(value);
      }
      set
      {
        this["binaryguid"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the filename to open on the connection string.
    /// </summary>
    [DisplayName("Data Source")]
    [Browsable(true)]
    [DefaultValue("")]
    public string DataSource
    {
      get
      {
        object value;
        TryGetValue("data source", out value);
        return value.ToString();
      }
      set
      {
        this["data source"] = value;
      }
    }

    /// <summary>
    /// An alternate to the data source property
    /// </summary>
    [Browsable(false)]
    public string Uri
    {
      get
      {
        object value;
        TryGetValue("uri", out value);
        return value.ToString();
      }
      set
      {
        this["uri"] = value;
      }
    }

    /// <summary>
    /// Gets/sets the default command timeout for newly-created commands.  This is especially useful for 
    /// commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible.
    /// </summary>
    [DisplayName("Default Timeout")]
    [Browsable(true)]
    [DefaultValue(30)]
    public int DefaultTimeout
    {
      get
      {
        object value;
        TryGetValue("default timeout", out value);
        return Convert.ToInt32(value, CultureInfo.CurrentCulture);
      }
      set
      {
        this["default timeout"] = value;
      }
    }

    /// <summary>
    /// Determines whether or not the connection will automatically participate
    /// in the current distributed transaction (if one exists)
    /// </summary>
    [Browsable(true)]
    [DefaultValue(true)]
    public bool Enlist
    {
      get
      {
        object value;
        TryGetValue("enlist", out value);
        return SQLiteConvert.ToBoolean(value);
      }
      set
      {
        this["enlist"] = value;
      }
    }

    /// <summary>
    /// If set to true, will throw an exception if the database specified in the connection
    /// string does not exist.  If false, the database will be created automatically.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(false)]
    public bool FailIfMissing
    {
      get
      {
        object value;
        TryGetValue("failifmissing", out value);
        return SQLiteConvert.ToBoolean(value);
      }
      set
      {
        this["failifmissing"] = value;
      }
    }

    /// <summary>
    /// If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger
    /// database sizes.
    /// </summary>
    [DisplayName("Legacy Format")]
    [Browsable(true)]
    [DefaultValue(false)]
    public bool LegacyFormat
    {
      get
      {
        object value;
        TryGetValue("legacy format", out value);
        return SQLiteConvert.ToBoolean(value);
      }
      set
      {
        this["legacy format"] = value;
      }
    }

    /// <summary>
    /// When enabled, the database will be opened for read-only access and writing will be disabled.
    /// </summary>
    [DisplayName("Read Only")]
    [Browsable(true)]
    [DefaultValue(false)]
    public bool ReadOnly
    {
      get
      {
        object value;
        TryGetValue("read only", out value);
        return SQLiteConvert.ToBoolean(value);
      }
      set
      {
        this["read only"] = value;
      }
    }

    /// <summary>
    /// Gets/sets the database encryption password
    /// </summary>
    [Browsable(true)]
    [PasswordPropertyText(true)]
    [DefaultValue("")]
    public string Password
    {
      get
      {
        object value;
        TryGetValue("password", out value);
        return value.ToString();
      }
      set
      {
        this["password"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the page size for the connection.
    /// </summary>
    [DisplayName("Page Size")]
    [Browsable(true)]
    [DefaultValue(1024)]
    public int PageSize
    {
      get
      {
        object value;
        TryGetValue("page size", out value);
        return Convert.ToInt32(value, CultureInfo.CurrentCulture);
      }
      set
      {
        this["page size"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the maximum number of pages the database may hold
    /// </summary>
    [DisplayName("Max Page Count")]
    [Browsable(true)]
    [DefaultValue(0)]
    public int MaxPageCount
    {
      get
      {
        object value;
        TryGetValue("max page count", out value);
        return Convert.ToInt32(value, CultureInfo.CurrentCulture);
      }
      set
      {
        this["max page count"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the cache size for the connection.
    /// </summary>
    [DisplayName("Cache Size")]
    [Browsable(true)]
    [DefaultValue(2000)]
    public int CacheSize
    {
      get
      {
        object value;
        TryGetValue("cache size", out value);
        return Convert.ToInt32(value, CultureInfo.CurrentCulture);
      }
      set
      {
        this["cache size"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the DateTime format for the connection.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(SQLiteDateFormats.Default)]
    public SQLiteDateFormats DateTimeFormat
    {
        get
        {
            object value;

            if (TryGetValue("datetimeformat", out value))
            {
                if (value is SQLiteDateFormats)
                    return (SQLiteDateFormats)value;
                else if (value != null)
                    return (SQLiteDateFormats)TypeDescriptor.GetConverter(
                        typeof(SQLiteDateFormats)).ConvertFrom(value);
            }

            return SQLiteDateFormats.Default;
        }
        set
        {
            this["datetimeformat"] = value;
        }
    }

    /// <summary>
    /// Gets/Sets the DateTime kind for the connection.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(DateTimeKind.Unspecified)]
    public DateTimeKind DateTimeKind
    {
        get
        {
            object value;

            if (TryGetValue("datetimekind", out value))
            {
                if (value is DateTimeKind)
                    return (DateTimeKind)value;
                else if (value != null)
                    return (DateTimeKind)TypeDescriptor.GetConverter(
                        typeof(DateTimeKind)).ConvertFrom(value);
            }

            return DateTimeKind.Unspecified;
        }
        set
        {
            this["datetimekind"] = value;
        }
    }

    /// <summary>
    /// Gets/Sets the placeholder base schema name used for
    /// .NET Framework compatibility purposes.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(SQLiteConnection.DefaultBaseSchemaName)]
    public string BaseSchemaName
    {
        get
        {
            object value;

            if (TryGetValue("baseschemaname", out value))
            {
                if (value is string)
                    return (string)value;
                else if (value != null)
                    return value.ToString();
            }

            return null;
        }
        set
        {
            this["baseschemaname"] = value;
        }
    }

    /// <summary>
    /// Determines how SQLite handles the transaction journal file.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(SQLiteJournalModeEnum.Delete)]
    [DisplayName("Journal Mode")]
    public SQLiteJournalModeEnum JournalMode
    {
      get
      {
        object value;
        TryGetValue("journal mode", out value);
        if (value is string)
          return (SQLiteJournalModeEnum)TypeDescriptor.GetConverter(typeof(SQLiteJournalModeEnum)).ConvertFrom(value);
        else
          return (SQLiteJournalModeEnum)value;
      }
      set
      {
        this["journal mode"] = value;
      }
    }

    /// <summary>
    /// Sets the default isolation level for transactions on the connection.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(IsolationLevel.Serializable)]
    [DisplayName("Default Isolation Level")]
    public IsolationLevel DefaultIsolationLevel
    {
      get
      {
        object value;
        TryGetValue("default isolationlevel", out value);
        if (value is string)
          return (IsolationLevel)TypeDescriptor.GetConverter(typeof(IsolationLevel)).ConvertFrom(value);
        else
          return (IsolationLevel)value;
      }
      set

      {
        this["default isolationlevel"] = value;
      }
    }

    /// <summary>
    /// If enabled, use foreign key constraints
    /// </summary>
    [DisplayName("Foreign Keys")]
    [Browsable(true)]
    [DefaultValue(false)]
    public bool ForeignKeys
    {
        get
        {
            object value;
            TryGetValue("foreign keys", out value);
            return SQLiteConvert.ToBoolean(value);
        }

        set
        {
            this["foreign keys"] = value;
        }
    }

    /// <summary>
    /// Helper function for retrieving values from the connectionstring
    /// </summary>
    /// <param name="keyword">The keyword to retrieve settings for</param>
    /// <param name="value">The resulting parameter value</param>
    /// <returns>Returns true if the value was found and returned</returns>
    public override bool TryGetValue(string keyword, out object value)
    {
      bool b = base.TryGetValue(keyword, out value);

      if (!_properties.ContainsKey(keyword)) return b;

      PropertyDescriptor pd = _properties[keyword] as PropertyDescriptor;

      if (pd == null) return b;

      // Attempt to coerce the value into something more solid
      if (b)
      {
        if (pd.PropertyType == typeof(Boolean))
          value = SQLiteConvert.ToBoolean(value);
        else
          value = TypeDescriptor.GetConverter(pd.PropertyType).ConvertFrom(value);
      }
      else
      {
        DefaultValueAttribute att = pd.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
        if (att != null)
        {
          value = att.Value;
          b = true;
        }
      }
      return b;
    }

    /// <summary>
    /// Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties()
    /// </summary>
    /// <param name="propertyList">The hashtable to fill with property descriptors</param>
    private void FallbackGetProperties(Hashtable propertyList)
    {
      foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(this, true))
      {
        if (descriptor.Name != "ConnectionString" && propertyList.ContainsKey(descriptor.DisplayName) == false)
        {
          propertyList.Add(descriptor.DisplayName, descriptor);
        }
      }
    }
  }
#endif
}











<
<
<
<





<
<


<
<
<
<
<














|
|

|


<
<
<
<


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

|
|





<
<




<
<
|




|

|




|

<
<
<
|



<
|
|
>
>
|
>
|
>
>
>



>
>
>
>
|






<
<




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



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

<
<
<
|
|
<



<
<
<




<
<
|



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






<
<
<




<
<
|



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






<
<
<




<
<
|



|


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

|

<
<
<
|



<
<
<
<
<
<
<
<
>
|
<
<
<
|
<
<
<
|
<
|
<
<
<
<
<
<
|

>
|
|
<
<
<
|
<
<
<
<
<
<
<
|
<
|
<
|
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<






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

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





#if !PLATFORM_COMPACTFRAMEWORK
  /// <summary>
  /// SQLite implementation of DbConnectionStringBuilder.
  /// </summary>


  public sealed class SQLiteConnectionStringBuilder : DbConnectionStringBuilder
  {





    /// <overloads>
    /// Constructs a new instance of the class
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteConnectionStringBuilder()
    {
      Initialize(null);
    }

    /// <summary>
    /// Constructs a new instance of the class using the specified connection string.
    /// </summary>
    /// <param name="cnnString">The connection string to parse</param>
    public SQLiteConnectionStringBuilder(string cnnString)
    {
      Initialize(cnnString);
    }





    private void Initialize(string cnnString)
    {
      ConnectionString = cnnString;
      Reset();
    }

    internal void Reset()
    {
      if (this.ContainsKey("Version") == false)
        Version = 3;

      if (ContainsKey("UseUTF16Encoding") == false)
        UseUTF16Encoding = false;

      if (ContainsKey("Cache Size") == false)
        CacheSize = 2000;

      if (ContainsKey("Synchronous") == false)
        SyncMode = SyncMode.Normal;

      if (ContainsKey("DateTimeFormat") == false)
        DateTimeFormat = DateTimeFormat.ISO8601;

      if (ContainsKey("Page Size") == false)
        PageSize = 4096;
    }

    /// <summary>
    /// Gets/Sets the default version of the SQLite engine to instantiate.  Currently the only valid value is 3, indicating version 3 of the sqlite library.
    /// </summary>


    public int Version
    {
      get
      {


        return Convert.ToInt32(this["Version"]);
      }
      set
      {
        if (value != 3)
          throw new NotImplementedException();

        this["Version"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the synchronous mode of the connection string.  Default is "Normal".
    /// </summary>



    public SyncMode SyncMode
    {
      get
      {

        string s = this["Synchronous"].ToString().ToUpper();
        switch (s)
        {
          case "FULL":
            return SyncMode.Full;
          case "OFF":
            return SyncMode.Off;
          default:
            return SyncMode.Normal;
        }
      }
      set
      {
        string s = "Normal";
        if (value == SyncMode.Full) s = "Full";
        else if (value == SyncMode.Off) s = "Off";

        this["Synchronous"] = s;
      }
    }

    /// <summary>
    /// Gets/Sets the encoding for the connection string.  The default is "False" which indicates UTF-8 encoding.
    /// </summary>


    public bool UseUTF16Encoding
    {
      get
      {









        return (this["UseUTF16Encoding"].ToString().ToUpper() == "TRUE");












      }
      set
      {



        this["UseUTF16Encoding"] = ((value == true) ? "True" : "False");













      }



    }


    /// <summary>
    /// Gets/Sets the filename to open on the connection string.
    /// </summary>



    public string DataSource
    {
      get
      {


        return this["Data Source"].ToString();
      }
      set
      {
        this["Data Source"] = value;












































































































































      }
    }

    /// <summary>
    /// Gets/Sets the page size for the connection.
    /// </summary>



    public int PageSize
    {
      get
      {


        return Convert.ToInt32(this["Page Size"]);
      }
      set
      {
        this["Page Size"] = value;




















      }
    }

    /// <summary>
    /// Gets/Sets the cache size for the connection.
    /// </summary>



    public int CacheSize
    {
      get
      {


        return Convert.ToInt32(this["Cache Size"]);
      }
      set
      {
        this["Cache Size"] = value;
      }
    }












































































































    /// <summary>
    /// Gets/Sets the datetime format for the connection.
    /// </summary>



    public DateTimeFormat DateTimeFormat
    {
      get
      {








        switch(this["DateTimeFormat"].ToString().ToUpper())
        {



          case "TICKS":



            return DateTimeFormat.Ticks;

          default:






            return DateTimeFormat.ISO8601;
        }
      }
      set
      {



        switch (value)







        {

          case DateTimeFormat.Ticks:

            this["DateTimeFormat"] = "Ticks";

            break;

          case DateTimeFormat.ISO8601:














            this["DateTimeFormat"] = "ISO8601";




            break;











        }
      }
    }
  }
#endif
}
Changes to System.Data.SQLite/SQLiteConvert.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Runtime.InteropServices;
  using System.Collections.Generic;
  using System.Globalization;



































  using System.Text;



















  /// <summary>
  /// This base class provides datatype conversion services for the SQLite provider.
  /// </summary>
  public abstract class SQLiteConvert
  {
    /// <summary>
    /// The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC).
    /// </summary>
    protected static readonly DateTime UnixEpoch =
        new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    /// <summary>
    /// The value of the OLE Automation epoch represented as a Julian day.
    /// </summary>
    private static readonly double OleAutomationEpochAsJulianDay = 2415018.5;

    /// <summary>
    /// The format string for DateTime values when using the InvariantCulture or CurrentCulture formats.
    /// </summary>
    private const string FullFormat = "yyyy-MM-ddTHH:mm:ss.fffffffK";

    /// <summary>
    /// An array of ISO8601 datetime formats we support conversion from
    /// </summary>
    private static string[] _datetimeFormats = new string[] {
      "THHmmssK",
      "THHmmK",
      "HH:mm:ss.FFFFFFFK",
      "HH:mm:ssK",
      "HH:mmK",
      "yyyy-MM-dd HH:mm:ss.FFFFFFFK", /* NOTE: UTC default (5). */
      "yyyy-MM-dd HH:mm:ssK",
      "yyyy-MM-dd HH:mmK",
      "yyyy-MM-ddTHH:mm:ss.FFFFFFFK",
      "yyyy-MM-ddTHH:mmK",
      "yyyy-MM-ddTHH:mm:ssK",
      "yyyyMMddHHmmssK",
      "yyyyMMddHHmmK",
      "yyyyMMddTHHmmssFFFFFFFK",
      "THHmmss",
      "THHmm",
      "HH:mm:ss.FFFFFFF",
      "HH:mm:ss",
      "HH:mm",
      "yyyy-MM-dd HH:mm:ss.FFFFFFF", /* NOTE: Non-UTC default (19). */
      "yyyy-MM-dd HH:mm:ss",
      "yyyy-MM-dd HH:mm",
      "yyyy-MM-ddTHH:mm:ss.FFFFFFF",
      "yyyy-MM-ddTHH:mm",
      "yyyy-MM-ddTHH:mm:ss",
      "yyyyMMddHHmmss",
      "yyyyMMddHHmm",
      "yyyyMMddTHHmmssFFFFFFF",
      "yyyy-MM-dd",
      "yyyyMMdd",
      "yy-MM-dd"
    };

    /// <summary>
    /// An UTF-8 Encoding instance, so we can convert strings to and from UTF-8
    /// </summary>
    private static Encoding _utf8 = new UTF8Encoding();
    /// <summary>
    /// The default DateTime format for this instance
    /// </summary>
    internal SQLiteDateFormats _datetimeFormat;

    /// <summary>
    /// The default DateTimeKind for this instance.

    /// </summary>


    internal DateTimeKind _datetimeKind;





    /// <summary>
    /// Initializes the conversion class
    /// </summary>


    /// <param name="fmt">The default date/time format to use for this instance</param>
    /// <param name="kind">The DateTimeKind to use.</param>
    internal SQLiteConvert(SQLiteDateFormats fmt, DateTimeKind kind)
    {
      _datetimeFormat = fmt;
      _datetimeKind = kind;
    }

    #region UTF-8 Conversion Functions
    /// <summary>
    /// Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character.
    /// </summary>
    /// <param name="sourceText">The string to convert to UTF-8</param>
    /// <returns>A byte array containing the converted string plus an extra 0 terminating byte at the end of the array.</returns>
    public static byte[] ToUTF8(string sourceText)
    {
      Byte[] byteArray;
      int nlen = _utf8.GetByteCount(sourceText) + 1;

      byteArray = new byte[nlen];
      nlen = _utf8.GetBytes(sourceText, 0, sourceText.Length, byteArray, 0);
      byteArray[nlen] = 0;

      return byteArray;
    }

    /// <summary>
    /// Convert a DateTime to a UTF-8 encoded, zero-terminated byte array.
    /// </summary>
    /// <remarks>
    /// This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the
    /// string result.
    /// </remarks>
    /// <param name="dateTimeValue">The DateTime to convert.</param>
    /// <returns>The UTF-8 encoded string, including a 0 terminating byte at the end of the array.</returns>
    public byte[] ToUTF8(DateTime dateTimeValue)
    {
      return ToUTF8(ToString(dateTimeValue));
    }

    /// <summary>
    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
    /// </summary>
    /// <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>
    /// <param name="nativestringlen">The number of bytes to decode</param>
    /// <returns>A string containing the translated character(s)</returns>
    public virtual string ToString(IntPtr nativestring, int nativestringlen)
    {
      return UTF8ToString(nativestring, nativestringlen);
    }

    /// <summary>
    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
    /// </summary>
    /// <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>
    /// <param name="nativestringlen">The number of bytes to decode</param>
    /// <returns>A string containing the translated character(s)</returns>
    public static string UTF8ToString(IntPtr nativestring, int nativestringlen)
    {
      if (nativestringlen == 0 || nativestring == IntPtr.Zero) return "";
      if (nativestringlen == -1)
      {
        do
        {
          nativestringlen++;
        } while (Marshal.ReadByte(nativestring, nativestringlen) != 0);
      }

      byte[] byteArray = new byte[nativestringlen];
      
      Marshal.Copy(nativestring, byteArray, 0, nativestringlen);

      return _utf8.GetString(byteArray, 0, nativestringlen);
    }


    #endregion

    #region DateTime Conversion Functions
    /// <summary>
    /// Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <remarks>
    /// Acceptable ISO8601 DateTime formats are:
    /// <list type="bullet">
    /// <item><description>THHmmssK</description></item>
    /// <item><description>THHmmK</description></item>
    /// <item><description>HH:mm:ss.FFFFFFFK</description></item>
    /// <item><description>HH:mm:ssK</description></item>
    /// <item><description>HH:mmK</description></item>
    /// <item><description>yyyy-MM-dd HH:mm:ss.FFFFFFFK</description></item>
    /// <item><description>yyyy-MM-dd HH:mm:ssK</description></item>
    /// <item><description>yyyy-MM-dd HH:mmK</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm:ss.FFFFFFFK</description></item>
    /// <item><description>yyyy-MM-ddTHH:mmK</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm:ssK</description></item>
    /// <item><description>yyyyMMddHHmmssK</description></item>
    /// <item><description>yyyyMMddHHmmK</description></item>
    /// <item><description>yyyyMMddTHHmmssFFFFFFFK</description></item>
    /// <item><description>THHmmss</description></item>
    /// <item><description>THHmm</description></item>
    /// <item><description>HH:mm:ss.FFFFFFF</description></item>
    /// <item><description>HH:mm:ss</description></item>
    /// <item><description>HH:mm</description></item>
    /// <item><description>yyyy-MM-dd HH:mm:ss.FFFFFFF</description></item>
    /// <item><description>yyyy-MM-dd HH:mm:ss</description></item>
    /// <item><description>yyyy-MM-dd HH:mm</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm:ss.FFFFFFF</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm:ss</description></item>
    /// <item><description>yyyyMMddHHmmss</description></item>
    /// <item><description>yyyyMMddHHmm</description></item>
    /// <item><description>yyyyMMddTHHmmssFFFFFFF</description></item>
    /// <item><description>yyyy-MM-dd</description></item>
    /// <item><description>yyyyMMdd</description></item>
    /// <item><description>yy-MM-dd</description></item>
    /// </list>
    /// If the string cannot be matched to one of the above formats, an exception will be thrown.
    /// </remarks>
    /// <param name="dateText">The string containing either a long integer number of 100-nanosecond units since
    /// System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a
    /// culture-independent formatted date and time string, a formatted date and time string in the current
    /// culture, or an ISO8601-format string.</param>
    /// <returns>A DateTime value</returns>
    public DateTime ToDateTime(string dateText)
    {
      return ToDateTime(dateText, _datetimeFormat, _datetimeKind);





    }

    /// <summary>
    /// Converts a string into a DateTime, using the specified DateTimeFormat and DateTimeKind.
    /// </summary>
    /// <remarks>
    /// Acceptable ISO8601 DateTime formats are:
    /// <list type="bullet">
    /// <item><description>THHmmssK</description></item>
    /// <item><description>THHmmK</description></item>
    /// <item><description>HH:mm:ss.FFFFFFFK</description></item>
    /// <item><description>HH:mm:ssK</description></item>
    /// <item><description>HH:mmK</description></item>
    /// <item><description>yyyy-MM-dd HH:mm:ss.FFFFFFFK</description></item>
    /// <item><description>yyyy-MM-dd HH:mm:ssK</description></item>
    /// <item><description>yyyy-MM-dd HH:mmK</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm:ss.FFFFFFFK</description></item>
    /// <item><description>yyyy-MM-ddTHH:mmK</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm:ssK</description></item>
    /// <item><description>yyyyMMddHHmmssK</description></item>
    /// <item><description>yyyyMMddHHmmK</description></item>
    /// <item><description>yyyyMMddTHHmmssFFFFFFFK</description></item>
    /// <item><description>THHmmss</description></item>
    /// <item><description>THHmm</description></item>
    /// <item><description>HH:mm:ss.FFFFFFF</description></item>
    /// <item><description>HH:mm:ss</description></item>
    /// <item><description>HH:mm</description></item>
    /// <item><description>yyyy-MM-dd HH:mm:ss.FFFFFFF</description></item>
    /// <item><description>yyyy-MM-dd HH:mm:ss</description></item>
    /// <item><description>yyyy-MM-dd HH:mm</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm:ss.FFFFFFF</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm</description></item>
    /// <item><description>yyyy-MM-ddTHH:mm:ss</description></item>
    /// <item><description>yyyyMMddHHmmss</description></item>
    /// <item><description>yyyyMMddHHmm</description></item>
    /// <item><description>yyyyMMddTHHmmssFFFFFFF</description></item>
    /// <item><description>yyyy-MM-dd</description></item>
    /// <item><description>yyyyMMdd</description></item>
    /// <item><description>yy-MM-dd</description></item>
    /// </list>
    /// If the string cannot be matched to one of the above formats, an exception will be thrown.
    /// </remarks>
    /// <param name="dateText">The string containing either a long integer number of 100-nanosecond units since
    /// System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a
    /// culture-independent formatted date and time string, a formatted date and time string in the current

    /// culture, or an ISO8601-format string.</param>
    /// <param name="format">The SQLiteDateFormats to use.</param>
    /// <param name="kind">The DateTimeKind to use.</param>
    /// <returns>A DateTime value</returns>
    public DateTime ToDateTime(string dateText, SQLiteDateFormats format, DateTimeKind kind)
    {
        switch (format)
        {
            case SQLiteDateFormats.Ticks:
                {
                    return new DateTime(Convert.ToInt64(
                        dateText, CultureInfo.InvariantCulture), kind);
                }
            case SQLiteDateFormats.JulianDay:
                {
                    return ToDateTime(Convert.ToDouble(
                        dateText, CultureInfo.InvariantCulture), kind);
                }
            case SQLiteDateFormats.UnixEpoch:

                {
                    return DateTime.SpecifyKind(
                        UnixEpoch.AddSeconds(Convert.ToInt32(
                        dateText, CultureInfo.InvariantCulture)), kind);
                }
            case SQLiteDateFormats.InvariantCulture:
                {
                    return DateTime.SpecifyKind(DateTime.Parse(
                        dateText, DateTimeFormatInfo.InvariantInfo,
                        kind == DateTimeKind.Utc ?
                            DateTimeStyles.AdjustToUniversal :
                            DateTimeStyles.None),
                        kind);
                }
            case SQLiteDateFormats.CurrentCulture:
                {
                    return DateTime.SpecifyKind(DateTime.Parse(
                        dateText, DateTimeFormatInfo.CurrentInfo,
                        kind == DateTimeKind.Utc ?
                            DateTimeStyles.AdjustToUniversal :
                            DateTimeStyles.None),
                        kind);
                }
            default:
                {
                    return DateTime.SpecifyKind(DateTime.ParseExact(
                        dateText, _datetimeFormats,
                        DateTimeFormatInfo.InvariantInfo,
                        kind == DateTimeKind.Utc ?
                            DateTimeStyles.AdjustToUniversal :
                            DateTimeStyles.None),
                        kind);
                }
        }
    }

    /// <summary>
    /// Converts a julianday value into a DateTime
    /// </summary>
    /// <param name="julianDay">The value to convert</param>
    /// <returns>A .NET DateTime</returns>
    public DateTime ToDateTime(double julianDay)
    {
      return ToDateTime(julianDay, _datetimeKind);
    }

    /// <summary>
    /// Converts a julianday value into a DateTime
    /// </summary>
    /// <param name="julianDay">The value to convert</param>
    /// <param name="kind">The DateTimeKind to use.</param>
    /// <returns>A .NET DateTime</returns>
    public DateTime ToDateTime(double julianDay, DateTimeKind kind)
    {
        return DateTime.SpecifyKind(
            DateTime.FromOADate(julianDay - OleAutomationEpochAsJulianDay), kind);
    }

    /// <summary>
    /// Converts a DateTime struct to a JulianDay double
    /// </summary>
    /// <param name="value">The DateTime to convert</param>
    /// <returns>The JulianDay value the Datetime represents</returns>
    public double ToJulianDay(DateTime value)
    {
      return value.ToOADate() + OleAutomationEpochAsJulianDay;
    }

    /// <summary>
    /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <param name="dateValue">The DateTime value to convert</param>
    /// <returns>Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a
    /// Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time
    /// string, a formatted date and time string in the current culture, or an ISO8601-format date/time string.</returns>
    public string ToString(DateTime dateValue)
    {
      switch (_datetimeFormat)
      {
        case SQLiteDateFormats.Ticks:
          return dateValue.Ticks.ToString(CultureInfo.InvariantCulture);
        case SQLiteDateFormats.JulianDay:
          return ToJulianDay(dateValue).ToString(CultureInfo.InvariantCulture);
        case SQLiteDateFormats.UnixEpoch:
          return ((long)(dateValue.Subtract(UnixEpoch).Ticks / TimeSpan.TicksPerSecond)).ToString();
        case SQLiteDateFormats.InvariantCulture:
          return dateValue.ToString(FullFormat, CultureInfo.InvariantCulture);
        case SQLiteDateFormats.CurrentCulture:
          return dateValue.ToString(FullFormat, CultureInfo.CurrentCulture);
        default:
          return (dateValue.Kind == DateTimeKind.Utc) ?
              dateValue.ToString(_datetimeFormats[5], CultureInfo.InvariantCulture) : // include "Z"
              dateValue.ToString(_datetimeFormats[19], CultureInfo.InvariantCulture);
      }
    }

    /// <summary>
    /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.
    /// </summary>
    /// <remarks>
    /// This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls
    /// ToDateTime() on the string to return a DateTime.
    /// </remarks>
    /// <param name="ptr">A pointer to the UTF-8 encoded string</param>
    /// <param name="len">The length in bytes of the string</param>
    /// <returns>The parsed DateTime value</returns>
    internal DateTime ToDateTime(IntPtr ptr, int len)
    {
      return ToDateTime(ToString(ptr, len));
    }

    #endregion

    /// <summary>
    /// Smart method of splitting a string.  Skips quoted elements, removes the quotes.
    /// </summary>
    /// <remarks>
    /// This split function works somewhat like the String.Split() function in that it breaks apart a string into












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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


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


|

|



|
>

<
>

>
>
|
>
>
>
>
>
|
<
|
>
>
|
<
|


|






|

|

|
|

|
|
|

|









|

|

|





|
|

|

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

|

<









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

|
<
<
<

|

|
>
>
>
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
>
|
|
|
|
|

|
|
<
<
|
|
<
|
|
|
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
|

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





|
|
<
<
|



|
|
<
<
<
<
<
<
<
<

<
<
|

















<







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

namespace System.Data.SQLite
{
  using System;
  using System.Runtime.InteropServices;
  using System.Collections.Generic;

  /// <summary>
  /// SQLite has very limited types, and is inherently text-based.  The first 5 types below represent the sum of all types SQLite
  /// understands.  The DateTime extension to the spec is for internal use only.
  /// </summary>
  public enum TypeAffinity
  {
    /// <summary>
    /// All integers in SQLite default to Int64
    /// </summary>
    Int64 = 1,
    /// <summary>
    /// All floating point numbers in SQLite default to double
    /// </summary>
    Double = 2,
    /// <summary>
    /// The default data type of SQLite is text
    /// </summary>
    Text = 3,
    /// <summary>
    /// Typically blob types are only seen when returned from a function
    /// </summary>
    Blob = 4,
    /// <summary>
    /// Null types can be returned from functions
    /// </summary>
    Null = 5,
    /// <summary>
    /// Used internally by this provider
    /// </summary>
    DateTime = 128,
    /// <summary>
    /// Used internally by this provider
    /// </summary>
    None=256,
  }

  /// <summary>
  /// This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of two formats.  Ticks and ISO8601.
  /// Ticks is inherently more accurate, but less compatible with 3rd party tools that query the database, and renders the DateTime field
  /// unreadable without post-processing.
  /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.
  /// </summary>
  public enum DateTimeFormat
  {
    /// <summary>
    /// Using ticks is more accurate but less compatible with other viewers and utilities that access your database.
    /// </summary>
    Ticks = 0,
    /// <summary>
    /// The default format for this provider.  More compatible with SQLite's intended usage of datetimes, but overall less accurate than Ticks as it doesn't
    /// natively support times down to fractions of a second.
    /// </summary>
    ISO8601 = 1,
  }

  /// <summary>
  /// This base class provides datatype conversion services for the SQLite provider.
  /// </summary>
  public abstract class SQLiteConvert
  {
    /// <summary>
















    /// An array of ISO8601 datetime formats we support conversion from
    /// </summary>
    private static string[] _datetimeFormats;

































    /// <summary>
    /// An UTF-8 Encoding instance, so we can convert strings to and from UTF8
    /// </summary>
    private Text.UTF8Encoding _utf8;
    /// <summary>
    /// The default DateTime format for this instance
    /// </summary>
    private DateTimeFormat _datetimeFormat;

    /// <summary>

    /// Static constructor, initializes the supported ISO8601 date time formats
    /// </summary>
    static SQLiteConvert()
    {
      _datetimeFormats = new string[] {"yyyy-MM-dd HH:mm:ss",
																	  "yyyyMMddHHmmss",
																	  "yyyyMMddTHHmmssfffffff",
																	  "yyyy-MM-dd",
																	  "yy-MM-dd",
																	  "yyyyMMdd",
																	  "HH:mm:ss",

																	  "THHmmss"
															 };
    }


    internal SQLiteConvert(DateTimeFormat fmt)
    {
      _datetimeFormat = fmt;
      _utf8 = new System.Text.UTF8Encoding();
    }

    #region UTF-8 Conversion Functions
    /// <summary>
    /// Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character.
    /// </summary>
    /// <param name="strSrc">The string to convert to UTF-8</param>
    /// <returns>A byte array containing the converted string plus an extra 0 terminating byte at the end of the array.</returns>
    public byte[] ToUTF8(string strSrc)
    {
      Byte[] b;
      int nlen = _utf8.GetByteCount(strSrc) + 1;

      b = new byte[nlen];
      nlen = _utf8.GetBytes(strSrc, 0, strSrc.Length, b, 0);
      b[nlen] = 0;

      return b;
    }

    /// <summary>
    /// Convert a DateTime to a UTF-8 encoded, zero-terminated byte array.
    /// </summary>
    /// <remarks>
    /// This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the
    /// string result.
    /// </remarks>
    /// <param name="dtSrc">The DateTime to convert.</param>
    /// <returns>The UTF-8 encoded string, including a 0 terminating byte at the end of the array.</returns>
    public byte[] ToUTF8(DateTime dtSrc)
    {
      return ToUTF8(ToString(dtSrc));
    }

    /// <summary>
    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
    /// </summary>
    /// <param name="b">The pointer to the memory where the UTF-8 string is encoded</param>
    /// <param name="nlen">The number of bytes to decode</param>
    /// <returns>A string containing the translated character(s)</returns>
    public virtual string ToString(IntPtr b, int nlen)
    {
      if (nlen == 0) return "";

      byte[] byt;

















      byt = new byte[nlen];
      Marshal.Copy(b, byt, 0, nlen);


      return _utf8.GetString(byt, 0, nlen);
    }


    #endregion

    #region DateTime Conversion Functions
    /// <summary>
    /// Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <remarks>
    /// Acceptable ISO8601 DateTime formats are:







    ///   yyyy-MM-dd HH:mm:ss




    ///   yyyyMMddHHmmss

    ///   yyyyMMddTHHmmssfffffff






    ///   yyyy-MM-dd







    ///   yy-MM-dd
    ///   yyyyMMdd
    ///   HH:mm:ss
    ///   THHmmss

    /// </remarks>
    /// <param name="strSrc">The string containing either a Tick value or an ISO8601-format string</param>



    /// <returns>A DateTime value</returns>
    public DateTime ToDateTime(string strSrc)
    {
      switch (_datetimeFormat)
      {
        case DateTimeFormat.Ticks:
          return new DateTime(Convert.ToInt64(strSrc));
        default:
          return DateTime.ParseExact(strSrc, _datetimeFormats, System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None);
      }
    }










































    /// <summary>
    /// Attempt to convert the specified string to a datetime value.
    /// </summary>
    /// <param name="strSrc">The string to parse into a datetime</param>
    /// <param name="result">If successful, a valid datetime structure</param>
    /// <returns>Returns true if the string was a valid ISO8601 datetime, false otherwise.</returns>
    public bool TryToDateTime(string strSrc, out DateTime result)
    {
      switch (_datetimeFormat)
      {


        case DateTimeFormat.ISO8601:
          return DateTime.TryParseExact(strSrc, _datetimeFormats, System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None, out result);

        case DateTimeFormat.Ticks:
          {
            long n;



            if (long.TryParse(strSrc, out n) == true)
            {










              result = new DateTime(n);




              return true;





            }









          }


          break;








      }






      result = DateTime.Now;


      return false;











    }

    /// <summary>
    /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <param name="dtSrc">The DateTime value to convert</param>
    /// <returns>Either a string consisting of the tick count for DateTimeFormat.Ticks, or a date/time in ISO8601 format.</returns>


    public string ToString(DateTime dtSrc)
    {
      switch (_datetimeFormat)
      {
        case DateTimeFormat.Ticks:
          return dtSrc.Ticks.ToString();








        default:


          return dtSrc.ToString(_datetimeFormats[0]);
      }
    }

    /// <summary>
    /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.
    /// </summary>
    /// <remarks>
    /// This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls
    /// ToDateTime() on the string to return a DateTime.
    /// </remarks>
    /// <param name="ptr">A pointer to the UTF-8 encoded string</param>
    /// <param name="len">The length in bytes of the string</param>
    /// <returns>The parsed DateTime value</returns>
    internal DateTime ToDateTime(IntPtr ptr, int len)
    {
      return ToDateTime(ToString(ptr, len));
    }

    #endregion

    /// <summary>
    /// Smart method of splitting a string.  Skips quoted elements, removes the quotes.
    /// </summary>
    /// <remarks>
    /// This split function works somewhat like the String.Split() function in that it breaks apart a string into
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
    /// [0] One<br/>
    /// [1] Two<br/>
    /// [2] Three, Four<br/>
    /// [3] Five<br/>
    /// <br/>
    /// Note that the leading and trailing spaces were removed from each item during the split.
    /// </remarks>
    /// <param name="source">Source string to split apart</param>
    /// <param name="separator">Separator character</param>
    /// <returns>A string array of the split up elements</returns>
    public static string[] Split(string source, char separator)
    {
      char[] toks = new char[2] { '\"', separator };
      char[] quot = new char[1] { '\"' };
      int n = 0;
      List<string> ls = new List<string>();
      string s;

      while (source.Length > 0)
      {
        n = source.IndexOfAny(toks, n);
        if (n == -1) break;
        if (source[n] == toks[0])
        {
          //source = source.Remove(n, 1);
          n = source.IndexOfAny(quot, n + 1);
          if (n == -1)
          {
            //source = "\"" + source;
            break;
          }
          n++;
          //source = source.Remove(n, 1);
        }
        else
        {
          s = source.Substring(0, n).Trim();
          if (s.Length > 1 && s[0] == quot[0] && s[s.Length - 1] == s[0])
            s = s.Substring(1, s.Length - 2);

          source = source.Substring(n + 1).Trim();
          if (s.Length > 0) ls.Add(s);
          n = 0;
        }
      }
      if (source.Length > 0)
      {
        s = source.Trim();
        if (s.Length > 1 && s[0] == quot[0] && s[s.Length - 1] == s[0])
          s = s.Substring(1, s.Length - 2);
        ls.Add(s);
      }

      string[] ar = new string[ls.Count];
      ls.CopyTo(ar, 0);

      return ar;
    }

    /// <summary>
    /// Convert a value to true or false.
    /// </summary>
    /// <param name="source">A string or number representing true or false</param>
    /// <returns></returns>
    public static bool ToBoolean(object source)
    {
      if (source is bool) return (bool)source;

      return ToBoolean(source.ToString());
    }

    /// <summary>
    /// Convert a string to true or false.
    /// </summary>
    /// <param name="source">A string representing true or false</param>
    /// <returns></returns>
    /// <remarks>
    /// "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be
    /// converted to a proper boolean value.
    /// </remarks>
    public static bool ToBoolean(string source)
    {
      if (String.Compare(source, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0) return true;
      else if (String.Compare(source, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0) return false;

      switch(source.ToLower(CultureInfo.InvariantCulture))
      {
        case "yes":
        case "y":
        case "1":
        case "on":
          return true;
        case "no":
        case "n":
        case "0":
        case "off":
          return false;
        default:
          throw new ArgumentException("source");
      }
    }

    #region Type Conversions
    /// <summary>
    /// Determines the data type of a column in a statement
    /// </summary>
    /// <param name="stmt">The statement to retrieve information for</param>
    /// <param name="i">The column to retrieve type information on</param>
    /// <param name="typ">The SQLiteType to receive the affinity for the given column</param>
    internal static void ColumnToType(SQLiteStatement stmt, int i, SQLiteType typ)
    {
      typ.Type = TypeNameToDbType(stmt._sql.ColumnType(stmt, i, out typ.Affinity));
    }

    /// <summary>
    /// Converts a SQLiteType to a .NET Type object
    /// </summary>
    /// <param name="t">The SQLiteType to convert</param>
    /// <returns>Returns a .NET Type object</returns>
    internal static Type SQLiteTypeToType(SQLiteType t)
    {
      if (t.Type == DbType.Object)
        return _affinitytotype[(int)t.Affinity];
      else
        return SQLiteConvert.DbTypeToType(t.Type);
    }

    private static Type[] _affinitytotype = {
      typeof(object),
      typeof(Int64),
      typeof(Double),
      typeof(string),
      typeof(byte[]),
      typeof(object),
      typeof(DateTime),
      typeof(object)
    };

    /// <summary>
    /// For a given intrinsic type, return a DbType
    /// </summary>
    /// <param name="typ">The native type to convert</param>
    /// <returns>The corresponding (closest match) DbType</returns>
    internal static DbType TypeToDbType(Type typ)
    {
      TypeCode tc = Type.GetTypeCode(typ);
      if (tc == TypeCode.Object)
      {
        if (typ == typeof(byte[])) return DbType.Binary;
        if (typ == typeof(Guid)) return DbType.Guid;
        return DbType.String;
      }
      return _typetodbtype[(int)tc];
    }

    private static DbType[] _typetodbtype = {
      DbType.Object,
      DbType.Binary,
      DbType.Object,
      DbType.Boolean,
      DbType.SByte,
      DbType.SByte,
      DbType.Byte,
      DbType.Int16, // 7
      DbType.UInt16,
      DbType.Int32,
      DbType.UInt32,
      DbType.Int64, // 11
      DbType.UInt64,
      DbType.Single,
      DbType.Double,
      DbType.Decimal,
      DbType.DateTime,
      DbType.Object,
      DbType.String,
    };

    /// <summary>
    /// Returns the ColumnSize for the given DbType
    /// </summary>
    /// <param name="typ">The DbType to get the size of</param>
    /// <returns></returns>
    internal static int DbTypeToColumnSize(DbType typ)
    {
      return _dbtypetocolumnsize[(int)typ];
    }

    private static int[] _dbtypetocolumnsize = {
      2147483647,   // 0
      2147483647,   // 1
      1,     // 2
      1,     // 3
      8,  // 4
      8, // 5
      8, // 6
      8,  // 7
      8,   // 8
      16,     // 9
      2,
      4,
      8,
      2147483647,
      1,
      4,
      2147483647,
      8,
      2,
      4,
      8,
      8,
      2147483647,
      2147483647,
      2147483647,
      2147483647,   // 25 (Xml)
    };

    internal static object DbTypeToNumericPrecision(DbType typ)
    {

      return _dbtypetonumericprecision[(int)typ];
    }

    private static object[] _dbtypetonumericprecision = {
      DBNull.Value, // 0
      DBNull.Value, // 1
      3,
      DBNull.Value,
      19,
      DBNull.Value, // 5
      DBNull.Value, // 6
      53,
      53,


      DBNull.Value,
      5,
      10,
      19,



      DBNull.Value,
      3,
      24,
      DBNull.Value,
      DBNull.Value,
      5,
      10,
      19,
      53,
      DBNull.Value,
      DBNull.Value,
      DBNull.Value
    };

    internal static object DbTypeToNumericScale(DbType typ)
    {


      return _dbtypetonumericscale[(int)typ];
    }

    private static object[] _dbtypetonumericscale = {
      DBNull.Value, // 0
      DBNull.Value, // 1
      0,
      DBNull.Value,
      4,
      DBNull.Value, // 5
      DBNull.Value, // 6
      DBNull.Value,
      DBNull.Value,
      DBNull.Value,
      0,
      0,
      0,
      DBNull.Value,
      0,
      DBNull.Value,
      DBNull.Value,
      DBNull.Value,
      0,
      0,
      0,
      0,
      DBNull.Value,
      DBNull.Value,
      DBNull.Value
    };

    internal static string DbTypeToTypeName(DbType typ)
    {
      for (int n = 0; n < _dbtypeNames.Length; n++)
      {
        if (_dbtypeNames[n].dataType == typ)
          return _dbtypeNames[n].typeName;
      }

      return String.Empty;
    }

    private static SQLiteTypeNames[] _dbtypeNames = {
      new SQLiteTypeNames("INTEGER", DbType.Int64),
      new SQLiteTypeNames("TINYINT", DbType.Byte),
      new SQLiteTypeNames("INT", DbType.Int32),
      new SQLiteTypeNames("VARCHAR", DbType.AnsiString),
      new SQLiteTypeNames("NVARCHAR", DbType.String),
      new SQLiteTypeNames("CHAR", DbType.AnsiStringFixedLength),
      new SQLiteTypeNames("NCHAR", DbType.StringFixedLength),
      new SQLiteTypeNames("FLOAT", DbType.Double),
      new SQLiteTypeNames("REAL", DbType.Double),
      new SQLiteTypeNames("BIT", DbType.Boolean),
      new SQLiteTypeNames("DECIMAL", DbType.Decimal),
      new SQLiteTypeNames("DATETIME", DbType.DateTime),
      new SQLiteTypeNames("BLOB", DbType.Binary),
      new SQLiteTypeNames("UNIQUEIDENTIFIER", DbType.Guid),
      new SQLiteTypeNames("SMALLINT", DbType.Int16),
    };
    /// <summary>
    /// Convert a DbType to a Type
    /// </summary>
    /// <param name="typ">The DbType to convert from</param>
    /// <returns>The closest-match .NET type</returns>
    internal static Type DbTypeToType(DbType typ)
    {
      return _dbtypeToType[(int)typ];
    }

    private static Type[] _dbtypeToType = {
      typeof(string),   // 0

      typeof(byte[]),   // 1

      typeof(byte),     // 2
      typeof(bool),     // 3

      typeof(decimal),  // 4
      typeof(DateTime), // 5
      typeof(DateTime), // 6
      typeof(decimal),  // 7
      typeof(double),   // 8

      typeof(Guid),     // 9


      typeof(Int16),


      typeof(Int32),
      typeof(Int64),
      typeof(object),
      typeof(sbyte),
      typeof(float),
      typeof(string),
      typeof(DateTime),
      typeof(UInt16),
      typeof(UInt32),
      typeof(UInt64),
      typeof(double),

      typeof(string),
      typeof(string),
      typeof(string),
      typeof(string),   // 25 (Xml)
    };


    /// <summary>
    /// For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types.
    /// </summary>
    /// <param name="typ">The type to evaluate</param>
    /// <returns>The SQLite type affinity for that type.</returns>
    internal static TypeAffinity TypeToAffinity(Type typ)
    {
      TypeCode tc = Type.GetTypeCode(typ);
      if (tc == TypeCode.Object)
      {
        if (typ == typeof(byte[]) || typ == typeof(Guid))

          return TypeAffinity.Blob;
        else
          return TypeAffinity.Text;
      }
      return _typecodeAffinities[(int)tc];
    }

    private static TypeAffinity[] _typecodeAffinities = {
      TypeAffinity.Null,
      TypeAffinity.Blob,
      TypeAffinity.Null,
      TypeAffinity.Int64,
      TypeAffinity.Int64,
      TypeAffinity.Int64,
      TypeAffinity.Int64,
      TypeAffinity.Int64, // 7
      TypeAffinity.Int64,
      TypeAffinity.Int64,

      TypeAffinity.Int64,
      TypeAffinity.Int64, // 11
      TypeAffinity.Int64,
      TypeAffinity.Double,
      TypeAffinity.Double,
      TypeAffinity.Double,
      TypeAffinity.DateTime,
      TypeAffinity.Null,

      TypeAffinity.Text,
    };


    /// <summary>
    /// For a given type name, return a closest-match .NET type
    /// </summary>
    /// <param name="Name">The name of the type to match</param>
    /// <returns>The .NET DBType the text evaluates to.</returns>
    internal static DbType TypeNameToDbType(string Name)
    {
      if (String.IsNullOrEmpty(Name)) return DbType.Object;

      lock (_syncRoot)
      {
        if (_typeNames == null)
        {
          _typeNames = new Dictionary<string, SQLiteTypeNames>(
              new TypeNameStringComparer());

          foreach (SQLiteTypeNames typeName in new SQLiteTypeNames[] {
              new SQLiteTypeNames("COUNTER", DbType.Int64),
              new SQLiteTypeNames("AUTOINCREMENT", DbType.Int64),
              new SQLiteTypeNames("IDENTITY", DbType.Int64),
              new SQLiteTypeNames("LONGTEXT", DbType.String),
              new SQLiteTypeNames("LONGCHAR", DbType.String),
              new SQLiteTypeNames("LONGVARCHAR", DbType.String),
              new SQLiteTypeNames("LONG", DbType.Int64),
              new SQLiteTypeNames("TINYINT", DbType.Byte),
              new SQLiteTypeNames("INTEGER", DbType.Int64),
              new SQLiteTypeNames("INT", DbType.Int32),
              new SQLiteTypeNames("VARCHAR", DbType.String),
              new SQLiteTypeNames("NVARCHAR", DbType.String),
              new SQLiteTypeNames("CHAR", DbType.String),
              new SQLiteTypeNames("NCHAR", DbType.String),
              new SQLiteTypeNames("TEXT", DbType.String),
              new SQLiteTypeNames("NTEXT", DbType.String),
              new SQLiteTypeNames("STRING", DbType.String),
              new SQLiteTypeNames("DOUBLE", DbType.Double),
              new SQLiteTypeNames("FLOAT", DbType.Double),
              new SQLiteTypeNames("REAL", DbType.Double),
              new SQLiteTypeNames("BIT", DbType.Boolean),
              new SQLiteTypeNames("YESNO", DbType.Boolean),
              new SQLiteTypeNames("LOGICAL", DbType.Boolean),
              new SQLiteTypeNames("BOOL", DbType.Boolean),
              new SQLiteTypeNames("BOOLEAN", DbType.Boolean),
              new SQLiteTypeNames("NUMERIC", DbType.Decimal),
              new SQLiteTypeNames("DECIMAL", DbType.Decimal),
              new SQLiteTypeNames("MONEY", DbType.Decimal),
              new SQLiteTypeNames("CURRENCY", DbType.Decimal),




              new SQLiteTypeNames("TIME", DbType.DateTime),

              new SQLiteTypeNames("DATE", DbType.DateTime),
              new SQLiteTypeNames("DATETIME", DbType.DateTime),
              new SQLiteTypeNames("SMALLDATE", DbType.DateTime),
              new SQLiteTypeNames("TIMESTAMP", DbType.DateTime),
              new SQLiteTypeNames("BLOB", DbType.Binary),
              new SQLiteTypeNames("BINARY", DbType.Binary),
              new SQLiteTypeNames("VARBINARY", DbType.Binary),
              new SQLiteTypeNames("IMAGE", DbType.Binary),
              new SQLiteTypeNames("GENERAL", DbType.Binary),
              new SQLiteTypeNames("OLEOBJECT", DbType.Binary),
              new SQLiteTypeNames("GUID", DbType.Guid),
              new SQLiteTypeNames("UNIQUEIDENTIFIER", DbType.Guid),
              new SQLiteTypeNames("MEMO", DbType.String),
              new SQLiteTypeNames("NOTE", DbType.String),
              new SQLiteTypeNames("SMALLINT", DbType.Int16),
              new SQLiteTypeNames("BIGINT", DbType.Int64)
            })
          {
            _typeNames.Add(typeName.typeName, typeName);
          }
        }
      }

      SQLiteTypeNames value;

      if (_typeNames.TryGetValue(Name, out value))
      {
        return value.dataType;
      }
      else
      {
        int index = Name.IndexOf('(');

        if ((index > 0) &&
            _typeNames.TryGetValue(Name.Substring(0, index), out value))
        {
          return value.dataType;
        }
      }

      return DbType.Object;
    }
    #endregion

    private static object _syncRoot = new object();
    private static Dictionary<string, SQLiteTypeNames> _typeNames = null;
  }

  /// <summary>
  /// SQLite has very limited types, and is inherently text-based.  The first 5 types below represent the sum of all types SQLite
  /// understands.  The DateTime extension to the spec is for internal use only.
  /// </summary>
  public enum TypeAffinity
  {
    /// <summary>
    /// Not used
    /// </summary>
    Uninitialized = 0,
    /// <summary>
    /// All integers in SQLite default to Int64
    /// </summary>
    Int64 = 1,
    /// <summary>
    /// All floating point numbers in SQLite default to double
    /// </summary>
    Double = 2,
    /// <summary>
    /// The default data type of SQLite is text
    /// </summary>
    Text = 3,
    /// <summary>
    /// Typically blob types are only seen when returned from a function
    /// </summary>
    Blob = 4,
    /// <summary>
    /// Null types can be returned from functions
    /// </summary>
    Null = 5,
    /// <summary>
    /// Used internally by this provider
    /// </summary>
    DateTime = 10,
    /// <summary>
    /// Used internally
    /// </summary>
    None = 11,
  }

  /// <summary>
  /// This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of three formats.  Ticks, ISO8601
  /// and JulianDay.
  /// </summary>
  /// <remarks>
  /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.
  /// JulianDay is the numeric format the SQLite uses internally and is arguably the most compatible with 3rd party tools.  It is
  /// not readable as text without post-processing.
  /// Ticks less compatible with 3rd party tools that query the database, and renders the DateTime field unreadable as text without post-processing.
  /// 
  /// The preferred order of choosing a datetime format is JulianDay, ISO8601, and then Ticks.  Ticks is mainly present for legacy 
  /// code support.
  /// </remarks>
  public enum SQLiteDateFormats
  {
    /// <summary>
    /// Using ticks is not recommended and is not well supported with LINQ.
    /// </summary>
    Ticks = 0,
    /// <summary>
    /// The ISO8601 format
    /// </summary>
    ISO8601 = 1,
    /// <summary>
    /// JulianDay format, which is what SQLite uses internally
    /// </summary>
    JulianDay = 2,
    /// <summary>
    /// The whole number of seconds since the Unix epoch (January 1, 1970).
    /// </summary>
    UnixEpoch = 3,
    /// <summary>
    /// Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
    /// </summary>
    InvariantCulture = 4,
    /// <summary>
    /// Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
    /// </summary>
    CurrentCulture = 5,
    /// <summary>
    /// The default format for this provider.
    /// </summary>
    Default = ISO8601
  }

  /// <summary>
  /// This enum determines how SQLite treats its journal file.
  /// </summary>
  /// <remarks>
  /// By default SQLite will create and delete the journal file when needed during a transaction.
  /// However, for some computers running certain filesystem monitoring tools, the rapid
  /// creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite.
  /// 
  /// If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file"
  /// when starting a transaction.  If this is happening, you may want to change the default journal mode to Persist.
  /// </remarks>
  public enum SQLiteJournalModeEnum
  {
    /// <summary>
    /// The default mode, this causes SQLite to use the existing journaling mode for the database.
    /// </summary>
    Default = -1,
    /// <summary>
    /// SQLite will create and destroy the journal file as-needed.
    /// </summary>
    Delete = 0,
    /// <summary>
    /// When this is set, SQLite will keep the journal file even after a transaction has completed.  It's contents will be erased,
    /// and the journal re-used as often as needed.  If it is deleted, it will be recreated the next time it is needed.
    /// </summary>
    Persist = 1,
    /// <summary>
    /// This option disables the rollback journal entirely.  Interrupted transactions or a program crash can cause database
    /// corruption in this mode!
    /// </summary>
    Off = 2,
    /// <summary>
    /// SQLite will truncate the journal file to zero-length instead of deleting it.
    /// </summary>
    Truncate = 3,
    /// <summary>
    /// SQLite will store the journal in volatile RAM.  This saves disk I/O but at the expense of database safety and integrity.
    /// If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the
    /// database file will very likely go corrupt.
    /// </summary>
    Memory = 4,
    /// <summary>
    /// SQLite uses a write-ahead log instead of a rollback journal to implement transactions.  The WAL journaling mode is persistent;
    /// after being set it stays in effect across multiple database connections and after closing and reopening the database. A database
    /// in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later.
    /// </summary>
    Wal = 5
  }

  /// <summary>
  /// Struct used internally to determine the datatype of a column in a resultset
  /// </summary>
  internal class SQLiteType
  {
    /// <summary>
    /// The DbType of the column, or DbType.Object if it cannot be determined
    /// </summary>
    internal DbType Type;
    /// <summary>
    /// The affinity of a column, used for expressions or when Type is DbType.Object
    /// </summary>
    internal TypeAffinity Affinity;
  }

  internal struct SQLiteTypeNames
  {
    internal SQLiteTypeNames(string newtypeName, DbType newdataType)
    {
      typeName = newtypeName;
      dataType = newdataType;
    }

    internal string typeName;
    internal DbType dataType;
  }

  internal class TypeNameStringComparer : IEqualityComparer<string>
  {
    #region IEqualityComparer<string> Members
    public bool Equals(
      string left,
      string right
      )
    {
      return String.Equals(left, right, StringComparison.OrdinalIgnoreCase);
    }

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

    public int GetHashCode(
      string value
      )
    {
      //
      // NOTE: The only thing that we must guarantee here, according
      //       to the MSDN documentation for IEqualityComparer, is 
      //       that for two given strings, if Equals return true then 
      //       the two strings must hash to the same value.
      //
      if (value != null)
#if !PLATFORM_COMPACTFRAMEWORK
        return value.ToLowerInvariant().GetHashCode();
#else
        return value.ToLower().GetHashCode();
#endif
      else
        throw new ArgumentNullException("value");
    }
    #endregion
  }
}







|
|

|

|





|

|

|

|
|


|


<
|



|
<
<
<
|




|
<
<
<
<
<
<







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
|
|
<
>
|
<
|
<
<
<
<
<
<
|
|
<
<
>
>
|
<
<
<
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
<
|
|
|
>
|
>
|
|
>
|
|
|
|
|
>
|
>
>
|
>
>
|
|
|
|
|
|
<
|
|
|
|
>
|
<
<
<
<
>








|
<

<
>
|
|

<
<
<
|
<
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
>
|
<
>








|

<
<
|
|
<
|
|
<
|
|
|
|
|
<
|
|
|
|
<
<
|
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
>
>
>
>
|
>
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<




|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
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





































































































































































































    /// [0] One<br/>
    /// [1] Two<br/>
    /// [2] Three, Four<br/>
    /// [3] Five<br/>
    /// <br/>
    /// Note that the leading and trailing spaces were removed from each item during the split.
    /// </remarks>
    /// <param name="src">Source string to split apart</param>
    /// <param name="sep">Separator character</param>
    /// <returns>A string array of the split up elements</returns>
    public static string[] Split(string src, char sep)
    {
      char[] toks = new char[2] { '\"', sep };
      char[] quot = new char[1] { '\"' };
      int n = 0;
      List<string> ls = new List<string>();
      string s;

      while (src.Length > 0)
      {
        n = src.IndexOfAny(toks, n);
        if (n == -1) break;
        if (src[n] == toks[0])
        {
          src = src.Remove(n, 1);
          n = src.IndexOfAny(quot, n);
          if (n == -1)
          {
            src = "\"" + src;
            break;
          }

          src = src.Remove(n, 1);
        }
        else
        {
          s = src.Substring(0, n).Trim();



          src = src.Substring(n + 1).Trim();
          if (s.Length > 0) ls.Add(s);
          n = 0;
        }
      }
      if (src.Length > 0) ls.Add(src);







      string[] ar = new string[ls.Count];
      ls.CopyTo(ar, 0);

      return ar;
    }












































    #region Type Conversions



































    /// <summary>
    /// For a given intrinsic type, return a DbType
    /// </summary>
    /// <param name="typ">The native type to convert</param>
    /// <returns>The corresponding (closest match) DbType</returns>
    internal static DbType TypeToDbType(Type typ)
    {
      switch (Type.GetTypeCode(typ))








































      {
        case TypeCode.Int16:
          return DbType.Int16;
        case TypeCode.Int32:
          return DbType.Int32;
        case TypeCode.Int64:
          return DbType.Int64;
        case TypeCode.UInt16:
          return DbType.UInt16;
        case TypeCode.UInt32:
          return DbType.UInt32;




        case TypeCode.UInt64:


          return DbType.UInt64;










        case TypeCode.Double:
          return DbType.Double;

        case TypeCode.Single:
          return DbType.Single;

        case TypeCode.Decimal:






          return DbType.Decimal;
        case TypeCode.Boolean:


          return DbType.Boolean;
        case TypeCode.SByte:
        case TypeCode.Char:



          return DbType.SByte;
        case TypeCode.DateTime:
          return DbType.DateTime;
        case TypeCode.String:












          return DbType.String;
        case TypeCode.Object:

          if (typ == typeof(byte[])) return DbType.Binary;
          if (typ == typeof(Guid)) return DbType.Guid;
          return DbType.String;
      }





































      return DbType.String;
    }


















    /// <summary>
    /// Convert a DbType to a Type
    /// </summary>
    /// <param name="typ">The DbType to convert from</param>
    /// <returns>The closest-match .NET type</returns>
    internal static Type DbTypeToType(DbType typ)
    {
      switch (typ)

      {
        case DbType.Binary:
          return typeof(byte[]);
        case DbType.Boolean:
          return typeof(bool);
        case DbType.Byte:
          return typeof(byte);
        case DbType.Currency:
        case DbType.Decimal:
          return typeof(decimal);
        case DbType.DateTime:
          return typeof(DateTime);
        case DbType.Double:
          return typeof(double);
        case DbType.Guid:
          return typeof(Guid);
        case DbType.Int16:
        case DbType.UInt16:
          return typeof(Int16);
        case DbType.Int32:
        case DbType.UInt32:
          return typeof(Int32);
        case DbType.Int64:
        case DbType.UInt64:
          return typeof(Int64);
        case DbType.String:
          return typeof(string);

        case DbType.SByte:
          return typeof(char);
        case DbType.Single:
          return typeof(float);
      }
      return typeof(string);




    }

    /// <summary>
    /// For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types.
    /// </summary>
    /// <param name="typ">The type to evaluate</param>
    /// <returns>The SQLite type affinity for that type.</returns>
    internal static TypeAffinity TypeToAffinity(Type typ)
    {
      switch (Type.GetTypeCode(typ))

      {

        case TypeCode.DBNull:
          return TypeAffinity.Null;
        case TypeCode.String:
          return TypeAffinity.Text;



        case TypeCode.DateTime:

          return TypeAffinity.DateTime;
        case TypeCode.Int16:
        case TypeCode.Int32:
        case TypeCode.Int64:
        case TypeCode.UInt16:
        case TypeCode.UInt32:
        case TypeCode.UInt64:
        case TypeCode.Char:
        case TypeCode.SByte:
        case TypeCode.Byte:
        case TypeCode.Boolean:
          return TypeAffinity.Int64;
        case TypeCode.Double:
        case TypeCode.Single:
        case TypeCode.Decimal:
          return TypeAffinity.Double;
        case TypeCode.Object:
          if (typ == typeof(byte[])) return TypeAffinity.Blob;
          else return TypeAffinity.Text;
      }
      return TypeAffinity.Text;

    }

    /// <summary>
    /// For a given type name, return a closest-match .NET type
    /// </summary>
    /// <param name="Name">The name of the type to match</param>
    /// <returns>The .NET DBType the text evaluates to.</returns>
    internal static DbType TypeNameToDbType(string Name)
    {
      if (Name == null) return DbType.Object;



      Name = Name.ToUpper();


      if (Name.IndexOf("LONGTEXT") > -1) return DbType.String;
      if (Name.IndexOf("LONGCHAR") > -1) return DbType.String;

      if (Name.IndexOf("SMALLINT") > -1) return DbType.Int16;
      if (Name.IndexOf("BIGINT") > -1) return DbType.Int64;
      if (Name.IndexOf("COUNTER") > -1) return DbType.Int64;
      if (Name.IndexOf("AUTOINCREMENT") > -1) return DbType.Int64;
      if (Name.IndexOf("IDENTITY") > -1) return DbType.Int64;

      if (Name.IndexOf("LONG") > -1) return DbType.Int64;
      if (Name.IndexOf("TINYINT") > -1) return DbType.Byte;
      if (Name.IndexOf("INTEGER") > -1) return DbType.Int64;
      if (Name.IndexOf("INT") > -1) return DbType.Int32;


      if (Name.IndexOf("TEXT") > -1) return DbType.String;




      if (Name.IndexOf("DOUBLE") > -1) return DbType.Double;
      if (Name.IndexOf("FLOAT") > -1) return DbType.Double;
      if (Name.IndexOf("REAL") > -1) return DbType.Single;









      if (Name.IndexOf("BIT") > -1) return DbType.Boolean;
      if (Name.IndexOf("YESNO") > -1) return DbType.Boolean;
      if (Name.IndexOf("LOGICAL") > -1) return DbType.Boolean;
      if (Name.IndexOf("BOOL") > -1) return DbType.Boolean;
      if (Name.IndexOf("NUMERIC") > -1) return DbType.Decimal;
      if (Name.IndexOf("DECIMAL") > -1) return DbType.Decimal;
      if (Name.IndexOf("MONEY") > -1) return DbType.Decimal;
      if (Name.IndexOf("CURRENCY") > -1) return DbType.Decimal;
      if (Name.IndexOf("TIME") > -1) return DbType.DateTime;
      if (Name.IndexOf("DATE") > -1) return DbType.DateTime;
      if (Name.IndexOf("BLOB") > -1) return DbType.Binary;
      if (Name.IndexOf("BINARY") > -1) return DbType.Binary;
      if (Name.IndexOf("IMAGE") > -1) return DbType.Binary;
      if (Name.IndexOf("GENERAL") > -1) return DbType.Binary;
      if (Name.IndexOf("OLEOBJECT") > -1) return DbType.Binary;

      if (Name.IndexOf("GUID") > -1) return DbType.Guid;











      if (Name.IndexOf("UNIQUEIDENTIFIER") > -1) return DbType.Guid;

      if (Name.IndexOf("MEMO") > -1) return DbType.String;






      if (Name.IndexOf("NOTE") > -1) return DbType.String;
      if (Name.IndexOf("CHAR") > -1) return DbType.String;







      return DbType.Object;
    }
    #endregion
  }


}





































































































































































































Deleted System.Data.SQLite/SQLiteDataAdapter.bmp.

cannot compute difference between binary files

Changes to System.Data.SQLite/SQLiteDataAdapter.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

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

  /// <summary>
  /// SQLite implementation of DbDataAdapter.
  /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
  [DefaultEvent("RowUpdated")]
  [ToolboxItem("SQLite.Designer.SQLiteDataAdapterToolboxItem, SQLite.Designer, Version=" + SQLite3.DesignerVersion + ", Culture=neutral, PublicKeyToken=db937bc2d44ff139")]
  [Designer("Microsoft.VSDesigner.Data.VS.SqlDataAdapterDesigner, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
  public sealed class SQLiteDataAdapter : DbDataAdapter
  {
    private static object _updatingEventPH = new object();
    private static object _updatedEventPH = new object();

    /// <overloads>
    /// This class is just a shell around the DbDataAdapter.  Nothing from DbDataAdapter is overridden here, just a few constructors are defined.
    /// </overloads>
    /// <summary>
    /// Default constructor.
    /// </summary>
    public SQLiteDataAdapter()










|
|




<
<
<
<
<


<
<
<







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

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

  /// <summary>
  /// SQLite implementation of DbDataAdapter.
  /// </summary>





  public sealed class SQLiteDataAdapter : DbDataAdapter
  {



    /// <overloads>
    /// This class is just a shell around the DbDataAdapter.  Nothing from DbDataAdapter is overridden here, just a few constructors are defined.
    /// </overloads>
    /// <summary>
    /// Default constructor.
    /// </summary>
    public SQLiteDataAdapter()
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
    {
      SelectCommand = cmd;
    }

    /// <summary>
    /// Constructs a data adapter with the supplied select command text and associated with the specified connection.
    /// </summary>
    /// <param name="commandText">The select command text to associate with the data adapter.</param>
    /// <param name="connection">The connection to associate with the select command.</param>
    public SQLiteDataAdapter(string commandText, SQLiteConnection connection)
    {
      SelectCommand = new SQLiteCommand(commandText, connection);
    }

    /// <summary>
    /// Constructs a data adapter with the specified select command text, and using the specified database connection string.
    /// </summary>
    /// <param name="commandText">The select command text to use to construct a select command.</param>
    /// <param name="connectionString">A connection string suitable for passing to a new SQLiteConnection, which is associated with the select command.</param>
    public SQLiteDataAdapter(string commandText, string connectionString)
    {
      SQLiteConnection cnn = new SQLiteConnection(connectionString);
      SelectCommand = new SQLiteCommand(commandText, cnn);
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteDataAdapter).Name);
#endif
    }

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

    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                //if (disposing)
                //{
                //    ////////////////////////////////////
                //    // dispose managed resources here...
                //    ////////////////////////////////////
                //}

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

                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
    #endregion

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

    /// <summary>
    /// Row updating event handler
    /// </summary>
    public event EventHandler<RowUpdatingEventArgs> RowUpdating
    {
      add
      {
        CheckDisposed();

#if !PLATFORM_COMPACTFRAMEWORK
        EventHandler<RowUpdatingEventArgs> previous = (EventHandler<RowUpdatingEventArgs>)base.Events[_updatingEventPH];
        if ((previous != null) && (value.Target is DbCommandBuilder))
        {
          EventHandler<RowUpdatingEventArgs> handler = (EventHandler<RowUpdatingEventArgs>)FindBuilder(previous);
          if (handler != null)
          {
            base.Events.RemoveHandler(_updatingEventPH, handler);
          }
        }
#endif
        base.Events.AddHandler(_updatingEventPH, value); 
      }
      remove { CheckDisposed(); base.Events.RemoveHandler(_updatingEventPH, value); }
    }

#if !PLATFORM_COMPACTFRAMEWORK
    internal static Delegate FindBuilder(MulticastDelegate mcd)
    {
      if (mcd != null)
      {
        Delegate[] invocationList = mcd.GetInvocationList();
        for (int i = 0; i < invocationList.Length; i++)
        {
          if (invocationList[i].Target is DbCommandBuilder)
          {
            return invocationList[i];
          }
        }
      }
      return null;
    }
#endif

    /// <summary>
    /// Row updated event handler
    /// </summary>
    public event EventHandler<RowUpdatedEventArgs> RowUpdated
    {
      add { CheckDisposed(); base.Events.AddHandler(_updatedEventPH, value); }
      remove { CheckDisposed(); base.Events.RemoveHandler(_updatedEventPH, value); }
    }

    /// <summary>
    /// Raised by the underlying DbDataAdapter when a row is being updated
    /// </summary>
    /// <param name="value">The event's specifics</param>
    protected override void OnRowUpdating(RowUpdatingEventArgs value)
    {
      EventHandler<RowUpdatingEventArgs> handler = base.Events[_updatingEventPH] as EventHandler<RowUpdatingEventArgs>;

      if (handler != null)
        handler(this, value);
    }

    /// <summary>
    /// Raised by DbDataAdapter after a row is updated
    /// </summary>
    /// <param name="value">The event's specifics</param>
    protected override void OnRowUpdated(RowUpdatedEventArgs value)
    {
      EventHandler<RowUpdatedEventArgs> handler = base.Events[_updatedEventPH] as EventHandler<RowUpdatedEventArgs>;

      if (handler != null)
        handler(this, value);
    }

    /// <summary>
    /// Gets/sets the select command for this DataAdapter
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
    public new SQLiteCommand SelectCommand
    {
      get { CheckDisposed(); return (SQLiteCommand)base.SelectCommand; }
      set { CheckDisposed(); base.SelectCommand = value; }
    }

    /// <summary>
    /// Gets/sets the insert command for this DataAdapter
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
    public new SQLiteCommand InsertCommand
    {
      get { CheckDisposed(); return (SQLiteCommand)base.InsertCommand; }
      set { CheckDisposed(); base.InsertCommand = value; }
    }

    /// <summary>
    /// Gets/sets the update command for this DataAdapter
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
    public new SQLiteCommand UpdateCommand
    {
      get { CheckDisposed(); return (SQLiteCommand)base.UpdateCommand; }
      set { CheckDisposed(); base.UpdateCommand = value; }
    }

    /// <summary>
    /// Gets/sets the delete command for this DataAdapter
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
    public new SQLiteCommand DeleteCommand
    {
      get { CheckDisposed(); return (SQLiteCommand)base.DeleteCommand; }
      set { CheckDisposed(); base.DeleteCommand = value; }
    }
  }
}







|
|
|

|





|
|
|

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



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
    {
      SelectCommand = cmd;
    }

    /// <summary>
    /// Constructs a data adapter with the supplied select command text and associated with the specified connection.
    /// </summary>
    /// <param name="CommandText">The select command text to associate with the data adapter.</param>
    /// <param name="cnn">The connection to associate with the select command.</param>
    public SQLiteDataAdapter(string CommandText, SQLiteConnection cnn)
    {
      SelectCommand = new SQLiteCommand(CommandText, cnn);
    }

    /// <summary>
    /// Constructs a data adapter with the specified select command text, and using the specified database connection string.
    /// </summary>
    /// <param name="CommandText">The select command text to use to construct a select command.</param>
    /// <param name="ConnectionString">A connection string suitable for passing to a new SQLiteConnection, which is associated with the select command.</param>
    public SQLiteDataAdapter(string CommandText, string ConnectionString)
    {
      SQLiteConnection cnn = new SQLiteConnection(ConnectionString);
      SelectCommand = new SQLiteCommand(CommandText, cnn);







































































































































































    }
  }
}
Changes to System.Data.SQLite/SQLiteDataReader.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Data;
  using System.Data.Common;
  using System.Globalization;






  /// <summary>
  /// SQLite implementation of DbDataReader.
  /// </summary>
  public sealed class SQLiteDataReader : DbDataReader
  {
    /// <summary>
    /// Underlying command this reader is attached to
    /// </summary>
    private SQLiteCommand _command;
    /// <summary>
    /// Index of the current statement in the command being processed
    /// </summary>
    private int _activeStatementIndex;
    /// <summary>
    /// Current statement being Read()
    /// </summary>
    private SQLiteStatement _activeStatement;
    /// <summary>
    /// State of the current statement being processed.
    /// -1 = First Step() executed, so the first Read() will be ignored
    ///  0 = Actively reading
    ///  1 = Finished reading
    ///  2 = Non-row-returning statement, no records
    /// </summary>
    private int _readingState;
    /// <summary>
    /// Number of records affected by the insert/update statements executed on the command
    /// </summary>
    private int _rowsAffected;
    /// <summary>
    /// Count of fields (columns) in the row-returning statement currently being processed
    /// </summary>
    private int _fieldCount;
    /// <summary>
    /// Datatypes of active fields (columns) in the current statement, used for type-restricting data
    /// </summary>
    private SQLiteType[] _fieldTypeArray;

    /// <summary>
    /// The behavior of the datareader
    /// </summary>
    private CommandBehavior _commandBehavior;

    /// <summary>
    /// If set, then dispose of the command object when the reader is finished
    /// </summary>
    internal bool _disposeCommand;

    /// <summary>
    /// If set, then raise an exception when the object is accessed after being disposed.
    /// </summary>
    internal bool _throwOnDisposed;

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

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

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

    /// <summary>
    /// Internal constructor, initializes the datareader and sets up to begin executing statements
    /// </summary>
    /// <param name="cmd">The SQLiteCommand this data reader is for</param>
    /// <param name="behave">The expected behavior of the data reader</param>
    internal SQLiteDataReader(SQLiteCommand cmd, CommandBehavior behave)
    {
      _throwOnDisposed = true;
      _command = cmd;
      _version = _command.Connection._version;
      _baseSchemaName = _command.Connection._baseSchemaName;

      _commandBehavior = behave;
      _activeStatementIndex = -1;
      _rowsAffected = -1;


      if (_command != null)
        NextResult();
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed && _throwOnDisposed)
            throw new ObjectDisposedException(typeof(SQLiteDataReader).Name);
#endif
    }

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

    /// <summary>
    /// Dispose of all resources used by this datareader.
    /// </summary>
    /// <param name="disposing"></param>
    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                //if (disposing)
                //{
                //    ////////////////////////////////////
                //    // dispose managed resources here...
                //    ////////////////////////////////////
                //}

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

                //
                // NOTE: Fix for ticket [e1b2e0f769], do NOT throw exceptions
                //       while we are being disposed.
                //
                _throwOnDisposed = false;
                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
    #endregion

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

    internal void Cancel()
    {
      _version = 0;
    }

    /// <summary>
    /// Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified.
    /// </summary>
    public override void Close()
    {
      CheckDisposed();

      try
      {
        if (_command != null)
        {
          try
          {
            try
            {
              // Make sure we've not been canceled
              if (_version != 0)
              {
                try
                {
                  while (NextResult())
                  {
                  }
                }
                catch(SQLiteException)
                {
                }
              }
              _command.ClearDataReader();
            }
            finally
            {
              // If the datareader's behavior includes closing the connection, then do so here.
              if ((_commandBehavior & CommandBehavior.CloseConnection) != 0 && _command.Connection != null)
                _command.Connection.Close();
            }
          }
          finally
          {
            if (_disposeCommand)
              _command.Dispose();
          }
        }

        _command = null;
        _activeStatement = null;
        _fieldTypeArray = null;
      }
      finally
      {
        if (_keyInfo != null)




        {
          _keyInfo.Dispose();
          _keyInfo = null;
        }
      }

    }

    /// <summary>
    /// Throw an error if the datareader is closed
    /// </summary>
    private void CheckClosed()
    {
      if (!_throwOnDisposed)
        return;

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

      if (_version == 0)
        throw new SQLiteException((int)SQLiteErrorCode.Abort, "Execution was aborted by the user");

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

    /// <summary>
    /// Throw an error if a row is not loaded
    /// </summary>
    private void CheckValidRow()
    {
      if (_readingState != 0)
        throw new InvalidOperationException("No current row");
    }

    /// <summary>
    /// Enumerator support
    /// </summary>
    /// <returns>Returns a DbEnumerator object.</returns>
    public override Collections.IEnumerator GetEnumerator()
    {
      CheckDisposed();
      return new DbEnumerator(this, ((_commandBehavior & CommandBehavior.CloseConnection) == CommandBehavior.CloseConnection));
    }

    /// <summary>
    /// Not implemented.  Returns 0
    /// </summary>
    public override int Depth
    {
      get
      {
        CheckDisposed();
        CheckClosed();
        return 0;
      }
    }

    /// <summary>
    /// Returns the number of columns in the current resultset
    /// </summary>
    public override int FieldCount
    {
      get
      {
        CheckDisposed();
        CheckClosed();

        if (_keyInfo == null)
          return _fieldCount;

        return _fieldCount + _keyInfo.Count;
      }
    }

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

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


      TypeAffinity affinity = GetSQLiteType(i).Affinity;


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

      }

      throw new InvalidCastException();
    }

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

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

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

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

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

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

    /// <summary>
    /// Retrieves a column as an array of bytes (blob)
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>

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

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

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

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

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

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

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

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

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

    /// <summary>
    /// Retrieves the name of the back-end datatype of the column

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

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

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

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

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

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

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



      if (i >= VisibleFieldCount && _keyInfo != null)




        return _keyInfo.GetDecimal(i - VisibleFieldCount);



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

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

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

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



    /// <summary>

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

      if (i >= VisibleFieldCount && _keyInfo != null)

        return _keyInfo.GetFieldType(i - VisibleFieldCount);

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

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

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

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

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

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

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

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

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

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

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

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

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

    /// <summary>
    /// Retrieves the column as a long


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

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

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

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

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

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

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

      int r = _activeStatement._sql.ColumnIndex(_activeStatement, name);
      if (r == -1 && _keyInfo != null)
      {
        r = _keyInfo.GetOrdinal(name);
        if (r > -1) r += VisibleFieldCount;
      }

      return r;
    }

    /// <summary>
    /// Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done
    /// to gather the necessary information so it can be represented in an ADO.NET manner.



    /// </summary>




    /// <returns>Returns a DataTable containing the schema information for the active SELECT statement being processed.</returns>
    public override DataTable GetSchemaTable()
    {
      CheckDisposed();
      return GetSchemaTable(true, false);
    }

    private class ColumnParent : IEqualityComparer<ColumnParent>
    {
        public string DatabaseName;
        public string TableName;
        public string ColumnName;

        public ColumnParent()
        {
            // do nothing.
        }

        public ColumnParent(
            string databaseName,
            string tableName,
            string columnName
            )
            : this()
        {
            this.DatabaseName = databaseName;
            this.TableName = tableName;
            this.ColumnName = columnName;
        }

        #region IEqualityComparer<ColumnParent> Members
        public bool Equals(ColumnParent x, ColumnParent y)
        {
            if ((x == null) && (y == null))
            {
                return true;
            }
            else if ((x == null) || (y == null))
            {
                return false;
            }
            else
            {
                if (!String.Equals(x.DatabaseName, y.DatabaseName,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return false;
                }

                if (!String.Equals(x.TableName, y.TableName,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return false;
                }

                if (!String.Equals(x.ColumnName, y.ColumnName,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return false;
                }

                return true;
            }
        }

        public int GetHashCode(ColumnParent obj)
        {
            int result = 0;

            if ((obj != null) && (obj.DatabaseName != null))
                result ^= obj.DatabaseName.GetHashCode();

            if ((obj != null) && (obj.TableName != null))
                result ^= obj.TableName.GetHashCode();

            if ((obj != null) && (obj.ColumnName != null))
                result ^= obj.ColumnName.GetHashCode();

            return result;
        }
        #endregion
    }

    private static void GetStatementColumnParents(
        SQLiteBase sql,
        SQLiteStatement stmt,
        int fieldCount,
        ref Dictionary<ColumnParent, List<int>> parentToColumns,
        ref Dictionary<int, ColumnParent> columnToParent
        )
    {
        if (parentToColumns == null)
            parentToColumns = new Dictionary<ColumnParent, List<int>>(
                new ColumnParent());

        if (columnToParent == null)
            columnToParent = new Dictionary<int, ColumnParent>();

        for (int n = 0; n < fieldCount; n++)
        {
            string databaseName = sql.ColumnDatabaseName(stmt, n);
            string tableName = sql.ColumnTableName(stmt, n);
            string columnName = sql.ColumnOriginalName(stmt, n);

            ColumnParent key = new ColumnParent(databaseName, tableName, null);
            ColumnParent value = new ColumnParent(databaseName, tableName, columnName);

            if (!parentToColumns.ContainsKey(key))
                parentToColumns.Add(key, new List<int>(new int[] { n }));
            else
                parentToColumns[key].Add(n);

            columnToParent.Add(n, value);
        }
    }

    internal DataTable GetSchemaTable(bool wantUniqueInfo, bool wantDefaultValue)
    {
      CheckClosed();

     //
     // BUGFIX: We need to quickly scan all the fields in the current
     //         "result set" to see how many distinct tables are actually
     //         involved.  This information is necessary so that some
     //         intelligent decisions can be made when constructing the
     //         metadata below.  For example, we need to be very careful
     //         about flagging a particular column as "unique" just
     //         because it was in its original underlying database table
     //         if there are now multiple tables involved in the
     //         "result set".  See ticket [7e3fa93744] for more detailed
     //         information.
     //
      Dictionary<ColumnParent, List<int>> parentToColumns = null;
      Dictionary<int, ColumnParent> columnToParent = null;

      GetStatementColumnParents(
          _command.Connection._sql, _activeStatement, _fieldCount,
          ref parentToColumns, ref columnToParent);

      DataTable tbl = new DataTable("SchemaTable");
      DataTable tblIndexes = null;
      DataTable tblIndexColumns;
      DataRow row;
      string temp;
      string strCatalog = "";
      string strTable = "";
      string strColumn = "";


      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add(SchemaTableColumn.ColumnName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(int));
      tbl.Columns.Add(SchemaTableColumn.ColumnSize, typeof(int));
      tbl.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(short));
      tbl.Columns.Add(SchemaTableColumn.NumericScale, typeof(short));
      tbl.Columns.Add(SchemaTableColumn.IsUnique, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsKey, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.BaseServerName, typeof(string));
      tbl.Columns.Add(SchemaTableOptionalColumn.BaseCatalogName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseTableName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.DataType, typeof(Type));
      tbl.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.ProviderType, typeof(int));
      tbl.Columns.Add(SchemaTableColumn.IsAliased, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsExpression, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsAutoIncrement, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsRowVersion, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsHidden, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsLong, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsReadOnly, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.ProviderSpecificDataType, typeof(Type));
      tbl.Columns.Add(SchemaTableOptionalColumn.DefaultValue, typeof(object));
      tbl.Columns.Add("DataTypeName", typeof(string));
      tbl.Columns.Add("CollationType", typeof(string));
      tbl.BeginLoadData();


      for (int n = 0; n < _fieldCount; n++)

      {

        row = tbl.NewRow();




        DbType typ = GetSQLiteType(n).Type;


        // Default settings for the column
        row[SchemaTableColumn.ColumnName] = GetName(n);
        row[SchemaTableColumn.ColumnOrdinal] = n;
        row[SchemaTableColumn.ColumnSize] = SQLiteConvert.DbTypeToColumnSize(typ);
        row[SchemaTableColumn.NumericPrecision] = SQLiteConvert.DbTypeToNumericPrecision(typ);
        row[SchemaTableColumn.NumericScale] = SQLiteConvert.DbTypeToNumericScale(typ);
        row[SchemaTableColumn.ProviderType] = GetSQLiteType(n).Type;
        row[SchemaTableColumn.IsLong] = false;
        row[SchemaTableColumn.AllowDBNull] = true;
        row[SchemaTableOptionalColumn.IsReadOnly] = false;
        row[SchemaTableOptionalColumn.IsRowVersion] = false;
        row[SchemaTableColumn.IsUnique] = false;
        row[SchemaTableColumn.IsKey] = false;
        row[SchemaTableOptionalColumn.IsAutoIncrement] = false;
        row[SchemaTableColumn.DataType] = GetFieldType(n);
        row[SchemaTableOptionalColumn.IsHidden] = false;
        row[SchemaTableColumn.BaseSchemaName] = _baseSchemaName;



        strColumn = columnToParent[n].ColumnName;
        if (String.IsNullOrEmpty(strColumn) == false) row[SchemaTableColumn.BaseColumnName] = strColumn;



        row[SchemaTableColumn.IsExpression] = String.IsNullOrEmpty(strColumn);
        row[SchemaTableColumn.IsAliased] = (String.Compare(GetName(n), strColumn, StringComparison.OrdinalIgnoreCase) != 0);

        temp = columnToParent[n].TableName;


        if (String.IsNullOrEmpty(temp) == false) row[SchemaTableColumn.BaseTableName] = temp;

        temp = columnToParent[n].DatabaseName;
        if (String.IsNullOrEmpty(temp) == false) row[SchemaTableOptionalColumn.BaseCatalogName] = temp;

        string dataType = null;
        // If we have a table-bound column, extract the extra information from it
        if (String.IsNullOrEmpty(strColumn) == false)
        {
          string collSeq;
          bool bNotNull;
          bool bPrimaryKey;
          bool bAutoIncrement;
          string[] arSize;

          // Get the column meta data
          _command.Connection._sql.ColumnMetaData(
            (string)row[SchemaTableOptionalColumn.BaseCatalogName],
            (string)row[SchemaTableColumn.BaseTableName],
            strColumn,


            out dataType, out collSeq, out bNotNull, out bPrimaryKey, out bAutoIncrement);





          if (bNotNull || bPrimaryKey) row[SchemaTableColumn.AllowDBNull] = false;






          row[SchemaTableColumn.IsKey] = bPrimaryKey;


          row[SchemaTableOptionalColumn.IsAutoIncrement] = bAutoIncrement;
          row["CollationType"] = collSeq;

          // For types like varchar(50) and such, extract the size



          arSize = dataType.Split('(');
          if (arSize.Length > 1)
          {
            dataType = arSize[0];
            arSize = arSize[1].Split(')');
            if (arSize.Length > 1)
            {
              arSize = arSize[0].Split(',', '.');
              if (GetSQLiteType(n).Type == DbType.String || GetSQLiteType(n).Type == DbType.Binary)
              {
                row[SchemaTableColumn.ColumnSize] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);
              }
              else


              {
                row[SchemaTableColumn.NumericPrecision] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);
                if (arSize.Length > 1)
                  row[SchemaTableColumn.NumericScale] = Convert.ToInt32(arSize[1], CultureInfo.InvariantCulture);
              }
            }
          }

          if (wantDefaultValue)
          {
            // Determine the default value for the column, which sucks because we have to query the schema for each column
            using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].TABLE_INFO([{1}])",
              row[SchemaTableOptionalColumn.BaseCatalogName],
              row[SchemaTableColumn.BaseTableName]
              ), _command.Connection))
            using (DbDataReader rdTable = cmdTable.ExecuteReader())

            {
              // Find the matching column

              while (rdTable.Read())
              {
                if (String.Compare((string)row[SchemaTableColumn.BaseColumnName], rdTable.GetString(1), StringComparison.OrdinalIgnoreCase) == 0)
                {


                  if (rdTable.IsDBNull(4) == false)
                    row[SchemaTableOptionalColumn.DefaultValue] = rdTable[4];

                  break;
                }
              }
            }
          }

          // Determine IsUnique properly, which is a pain in the butt!
          if (wantUniqueInfo)
          {
            if ((string)row[SchemaTableOptionalColumn.BaseCatalogName] != strCatalog
              || (string)row[SchemaTableColumn.BaseTableName] != strTable)
            {
              strCatalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];
              strTable = (string)row[SchemaTableColumn.BaseTableName];

              tblIndexes = _command.Connection.GetSchema("Indexes", new string[] {
                (string)row[SchemaTableOptionalColumn.BaseCatalogName],
                null,
                (string)row[SchemaTableColumn.BaseTableName],
                null });
            }

            foreach (DataRow rowIndexes in tblIndexes.Rows)
            {
              tblIndexColumns = _command.Connection.GetSchema("IndexColumns", new string[] {
                (string)row[SchemaTableOptionalColumn.BaseCatalogName],
                null,
                (string)row[SchemaTableColumn.BaseTableName],
                (string)rowIndexes["INDEX_NAME"],
                null
                });
              foreach (DataRow rowColumnIndex in tblIndexColumns.Rows)
              {
                if (String.Compare((string)rowColumnIndex["COLUMN_NAME"], strColumn, StringComparison.OrdinalIgnoreCase) == 0)
                {
                  //
                  // BUGFIX: Make sure that we only flag this column as "unique"
                  //         if we are not processing of some kind of multi-table
                  //         construct (i.e. a join) because in that case we must
                  //         allow duplicate values (refer to ticket [7e3fa93744]).
                  //
                  if (parentToColumns.Count == 1 && tblIndexColumns.Rows.Count == 1 && (bool)row[SchemaTableColumn.AllowDBNull] == false)
                    row[SchemaTableColumn.IsUnique] = rowIndexes["UNIQUE"];

                  // If its an integer primary key and the only primary key in the table, then its a rowid alias and is autoincrement
                  // NOTE:  Currently commented out because this is not always the desired behavior.  For example, a 1:1 relationship with
                  //        another table, where the other table is autoincrement, but this one is not, and uses the rowid from the other.
                  //        It is safer to only set Autoincrement on tables where we're SURE the user specified AUTOINCREMENT, even if its a rowid column.

                  if (tblIndexColumns.Rows.Count == 1 && (bool)rowIndexes["PRIMARY_KEY"] == true && String.IsNullOrEmpty(dataType) == false &&
                    String.Compare(dataType, "integer", StringComparison.OrdinalIgnoreCase) == 0)
                  {
                    //  row[SchemaTableOptionalColumn.IsAutoIncrement] = true;
                  }

                  break;
                }
              }
            }
          }

          if (String.IsNullOrEmpty(dataType))
          {
            TypeAffinity affin;
            dataType = _activeStatement._sql.ColumnType(_activeStatement, n, out affin);
          }

          if (String.IsNullOrEmpty(dataType) == false)
            row["DataTypeName"] = dataType;
        }
        tbl.Rows.Add(row);
      }

      if (_keyInfo != null)
        _keyInfo.AppendSchemaTable(tbl);

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

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



      if (i >= VisibleFieldCount && _keyInfo != null)




        return _keyInfo.GetString(i - VisibleFieldCount);


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



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




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

      SQLiteType typ = GetSQLiteType(i);

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

    /// <summary>
    /// Retreives the values of multiple columns, up to the size of the supplied array

    /// </summary>
    /// <param name="values">The array to fill with values from the columns in the current resultset</param>
    /// <returns>The number of columns retrieved</returns>
    public override int GetValues(object[] values)
    {
      CheckDisposed();

      int nMax = FieldCount;
      if (values.Length < nMax) nMax = values.Length;

      for (int n = 0; n < nMax; n++)
      {
        values[n] = GetValue(n);
      }

      return nMax;
    }

    /// <summary>
    /// Returns True if the resultset has rows that can be fetched
    /// </summary>
    public override bool HasRows
    {
      get
      {
        CheckDisposed();
        CheckClosed();
        return (_readingState != 1);
      }
    }

    /// <summary>
    /// Returns True if the data reader is closed
    /// </summary>
    public override bool IsClosed
    {
      get { CheckDisposed(); return (_command == null); }
    }

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


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

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

    /// <summary>
    /// Moves to the next resultset in multiple row-returning SQL command.

    /// </summary>
    /// <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>
    public override bool NextResult()
    {
      CheckDisposed();
      CheckClosed();

      SQLiteStatement stmt = null;
      int fieldCount;

      while (true)
      {


        if (stmt == null && _activeStatement != null && _activeStatement._sql != null && _activeStatement._sql.IsOpen())
        {
          // Reset the previously-executed statement
          _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 (stmt._sql.ColumnCount(stmt) == 0)
              {
                if (_rowsAffected == -1) _rowsAffected = 0;
                _rowsAffected += stmt._sql.Changes;
              }
              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);

        // If we've reached the end of the statements, return false, no more resultsets
        if (stmt == null)
          return false;

        // If we were on a current resultset, set the state to "done reading" for it
        if (_readingState < 1)
          _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 (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;
            _rowsAffected += stmt._sql.Changes;
            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
          }
        }

        // Ahh, we found a row-returning resultset eligible to be returned!
        _activeStatement = stmt;
        _fieldCount = fieldCount;
        _fieldTypeArray = null;

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

        return true;
      }
    }

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

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

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

      typ = _fieldTypeArray[i];

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

      return typ;
    }

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

      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
      {
        // Don't read a new row if the command behavior dictates SingleRow.  We've already read the first row.
        if ((_commandBehavior & CommandBehavior.SingleRow) == 0)
        {
          if (_activeStatement._sql.Step(_activeStatement) == true)
          {
            if (_keyInfo != null)
              _keyInfo.Reset();

            return true;
          }
        }

        _readingState = 1; // Finished reading rows
      }

      return false;
    }

    /// <summary>
    /// Retrieve the count of records affected by an update/insert command.  Only valid once the data reader is closed!
    /// </summary>
    public override int RecordsAffected
    {
      get { CheckDisposed(); return (_rowsAffected < 0) ? 0 : _rowsAffected; }
    }

    /// <summary>
    /// Indexer to retrieve data from a column given its name
    /// </summary>
    /// <param name="name">The name of the column to retrieve data for</param>
    /// <returns>The value contained in the column</returns>
    public override object this[string name]
    {
      get { CheckDisposed(); return GetValue(GetOrdinal(name)); }
    }

    /// <summary>
    /// Indexer to retrieve data from a column given its i
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>The value contained in the column</returns>
    public override object this[int i]
    {
      get { CheckDisposed(); return GetValue(i); }
    }

    private void LoadKeyInfo()
    {
      if (_keyInfo != null)
        _keyInfo.Dispose();

      _keyInfo = new SQLiteKeyReader(_command.Connection, this, _activeStatement);
    }
  }
}










|
|
|
|
>
>
>
>
>









|



|











|



|



|



|






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

<
<
<
<
<
|

<
<
<
<
|
<
|

>

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







<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
|
<
|
|
|
|
|
<
<
<
<
<
<
<
<
|
<
<
|
<
|
<
>
>
>
>
|
|
<
<
<
>







<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








<
|



|





<






|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















|

|

|
|
>

|
|
>
|
|
|
|
|
|
|
|
<
<
<
<
|
|
|
|
|
<
|
|
|
|
|
|
|
<
|
|
<
|
|
|
>






<

|
|
|

|
<
<
<
<
|
|



|

|
|
|

|
<
<
<
<
|
|



|

|
>
<
|
|
|
<
|
<
<
|

|
<
<
<
<
|
|



|

|
|
|

|
<
<
<
<
|
|



|

|
|
|
|
|
<
|
<
<
|

|
<
<
<
<
|
|



<
>

|
|
|

|
|
<
<
|
<
<
<
|
<

|

|
|
|

|
<
<
<
<
|
|



|

|
|
|

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



|

|
|
|

|
|
<
<

|
|
|
>
|
>
|
>
|
<
|
|
|
<
<
|
<
>
|
|
<



|

|
|
|

|
<
<
<
<
|
|



|

|
|
|

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

|

|
|
|

|
<
<
<
<
|
|



|

|
|
|

|
<
<
<
<
|
|

<
<
|
>
>

|
|
|

|
<
<
<
<
|
|



|

|
|
|

|
<
<
<
<
|



|

|
|


<

<
|
<
<
<
<
<
<
<



|
|
>
>
>

>
>
>
>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
|
|
>

<

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

|
|
|
|
|

|
<


>
|
>

>
|
>
>
>
|
<
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
>
>
|
|

>
>
|
|
|
|
>
>
|
|
<
|
|
|
<
|
<
<
<
<
|
<
<
<
<
|
|
|
>
>
|
>
>

>
>
|
>
>
|
>
>
>
|
>
>
|
<
|
<
>
>
>
|
|
|
<
|
|
<
<
<
<
|
|
<
>
>
|
|
<
|
<
<
<
|
<
|
<
<
|
|
<
<
>
|
<
>
|
<
|
<
>
>
|
|
<
|
|
|
|
|
|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<
<
|
<
|
<
<
<
|
<
|
<
<
<
|
<
<
|
<
<
<
<
<








|

|
|
|

|
>
>
|
|
>
>
>
>
|
>
|
<
<
<
>
>

<
|
<
<
<
<
|
<
>
>
>

<
|
|
<

|



<
>

|
|


|
<





|






|





<

|




|



|



|

|
|
|

|
>
|
<
<

<
<
<

<
>

|


<


|




>
>
|

|






|

<
<

|

<
<
<
<
<






<
<
<

|


<
<
<
<


>


<
>








<
<














<
<
<




<
<
<
<
<
|

<
<
<
|
<

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



|

|


<









<
<
<
|
<
<
<
<
|
<
<








|



|



|

|
|


|



|

|
|
|

|

|
<
<
<
<
|
<
<
<
<
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




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

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;

  internal struct SQLiteType
  {
    internal DbType         Type;
    internal TypeAffinity Affinity;
  }

  /// <summary>
  /// SQLite implementation of DbDataReader.
  /// </summary>
  public sealed class SQLiteDataReader : DbDataReader
  {
    /// <summary>
    /// Underlying command this reader is attached to
    /// </summary>
    private SQLiteCommand   _command;
    /// <summary>
    /// Index of the current statement in the command being processed
    /// </summary>
    private int             _activeStatementIndex;
    /// <summary>
    /// Current statement being Read()
    /// </summary>
    private SQLiteStatement _activeStatement;
    /// <summary>
    /// State of the current statement being processed.
    /// -1 = First Step() executed, so the first Read() will be ignored
    ///  0 = Actively reading
    ///  1 = Finished reading
    ///  2 = Non-row-returning statement, no records
    /// </summary>
    private int             _readingState;
    /// <summary>
    /// Number of records affected by the insert/update statements executed on the command
    /// </summary>
    private int             _rowsAffected;
    /// <summary>
    /// Count of fields (columns) in the row-returning statement currently being processed
    /// </summary>
    private int             _fieldCount;
    /// <summary>
    /// Datatypes of active fields (columns) in the current statement, used for type-restricting data
    /// </summary>
    private SQLiteType[]    _fieldTypeArray;

    /// <summary>
    /// The behavior of the datareader
    /// </summary>
    private CommandBehavior _commandBehavior;





    internal SQLiteDataReader(SQLiteCommand cmd, CommandBehavior behave)




    {
      _command = cmd;
      _commandBehavior = behave;


      Initialize();




    }












    internal void Initialize()
    {




      _activeStatementIndex = -1;

      _activeStatement = null;
      _rowsAffected = -1;
      _fieldCount = -1;


      NextResult();

























































    }

    /// <summary>
    /// Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified.
    /// </summary>
    public override void Close()
    {




      if (_command != null)
      {









        while (NextResult()) ;







        _command.ClearDataReader();
      }


      // If the datareader's behavior includes closing the connection, then do so here.
      if ((_commandBehavior & CommandBehavior.CloseConnection) != 0)
        _command.Connection.Close();









      _command = null;


    }



    /// <summary>
    /// Disposes the datareader.  Calls Close() to ensure everything is cleaned up.
    /// </summary>
    public override void Dispose()
    {
      Close();



      GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Throw an error if the datareader is closed
    /// </summary>
    private void CheckClosed()
    {



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















    }

    /// <summary>
    /// Enumerator support
    /// </summary>
    /// <returns>Returns a DbEnumerator object.</returns>
    public override Collections.IEnumerator GetEnumerator()
    {

      return new DbEnumerator(this);
    }

    /// <summary>
    /// 
    /// </summary>
    public override int Depth
    {
      get
      {

        CheckClosed();
        return 0;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override int FieldCount
    {
      get
      {


















        CheckClosed();
        return _fieldCount;
      }
    }

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

      if (t.Type == typ) return;

      if (t.Type != DbType.Object)
      {
        // Coercable type, usually a literal of some kind
        switch (_fieldTypeArray[ordinal].Affinity)
        {
          case TypeAffinity.Int64:
            if (typ == DbType.Int16) return;
            if (typ == DbType.Int32) return;
            if (typ == DbType.Int64) return;
            if (typ == DbType.Boolean) return;
            if (typ == DbType.Byte) return;




            break;
          case TypeAffinity.Double:
            if (typ == DbType.Single) return;
            if (typ == DbType.Double) return;
            if (typ == DbType.Decimal) return;

            break;
          case TypeAffinity.Text:
            if (typ == DbType.SByte) return;
            if (typ == DbType.String) return;
            if (typ == DbType.SByte) return;
            if (typ == DbType.Guid) return;
            if (typ == DbType.DateTime) return;

            break;
          case TypeAffinity.Blob:

            if (typ == DbType.String) return;
            if (typ == DbType.Binary) return;
            break;
        }
      }

      throw new InvalidCastException();
    }

    /// <summary>

    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override bool GetBoolean(int ordinal)
    {
      CheckClosed();




      VerifyType(ordinal, DbType.Boolean);
      return Convert.ToBoolean(GetValue(ordinal));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override byte GetByte(int ordinal)
    {
      CheckClosed();




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

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <param name="dataOffset"></param>

    /// <param name="buffer"></param>
    /// <param name="bufferOffset"></param>
    /// <param name="length"></param>

    /// <returns></returns>


    public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
    {
      CheckClosed();




      VerifyType(ordinal, DbType.Binary);
      return _activeStatement._sql.GetBytes(_activeStatement, ordinal, (int)dataOffset, buffer, bufferOffset, length);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override char GetChar(int ordinal)
    {
      CheckClosed();




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

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <param name="dataOffset"></param>
    /// <param name="buffer"></param>
    /// <param name="bufferOffset"></param>
    /// <param name="length"></param>

    /// <returns></returns>


    public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
    {
      CheckClosed();




      VerifyType(ordinal, DbType.String);
      return _activeStatement._sql.GetChars(_activeStatement, ordinal, (int)dataOffset, buffer, bufferOffset, length);
    }

    /// <summary>

    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override string GetDataTypeName(int ordinal)
    {
      CheckClosed();
      return _activeStatement._sql.ColumnName(_activeStatement, ordinal);


    }





    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override DateTime GetDateTime(int ordinal)
    {
      CheckClosed();




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

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override decimal GetDecimal(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Decimal);
      return Convert.ToDecimal(_activeStatement._sql.GetDouble(_activeStatement, ordinal));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override double GetDouble(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Double);
      return _activeStatement._sql.GetDouble(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Type GetFieldType(int ordinal)
    {
      CheckClosed();
      SQLiteType t = GetSQLiteType(ordinal);



      if (t.Type != DbType.Object)
        return SQLiteConvert.DbTypeToType(t.Type);

      switch (t.Affinity)
      {
        case TypeAffinity.Null:
          return typeof(DBNull);
        case TypeAffinity.Int64:
          return typeof(Int64);

        case TypeAffinity.Double:
          return typeof(Double);
        case TypeAffinity.Blob:


          return typeof(byte[]);

        default:
          return typeof(string);
      }

    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override float GetFloat(int ordinal)
    {
      CheckClosed();




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

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Guid GetGuid(int ordinal)
    {
      CheckClosed();




      VerifyType(ordinal, DbType.Guid);




      return new Guid(_activeStatement._sql.GetText(_activeStatement, ordinal));
    }




    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Int16 GetInt16(int ordinal)
    {
      CheckClosed();




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

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Int32 GetInt32(int ordinal)
    {
      CheckClosed();




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



    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Int64 GetInt64(int ordinal)
    {
      CheckClosed();




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

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override string GetName(int ordinal)
    {
      CheckClosed();




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

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public override int GetOrdinal(string name)
    {

      CheckClosed();

      return _activeStatement._sql.ColumnIndex(_activeStatement, name);







    }

    /// <summary>
    /// Schema information in SQLite is an iffy-business.  We've extended the native SQLite3.DLL to include a special pragma called
    /// PRAGMA real_column_names
    /// When enabled, the pragma causes all column aliases to be ignored, and the full Database.Table.ColumnName to be returned for
    /// each column of a SELECT statement.  Using this information it is then possible to query each database and table for the
    /// matching column, and associate it with the active statement.
    /// </summary>
    /// <remarks>
    /// The current connection is cloned for the sake of executing this statement, so as to avoid any possibility of corrupting the
    /// original connection's existing statements or state.  Any attached databases are re-attached to the new connection.
    /// </remarks>
    /// <returns>Returns a DataTable containing the schema information for the active SELECT statement being processed.</returns>
    public override DataTable GetSchemaTable()
    {



















































































































      CheckClosed();




















      DataTable tbl = new DataTable("Schema");



      string[] arName;

      string strTable;
      string strCatalog;
      DataRow row;


      tbl.Columns.Add(SchemaTableColumn.ColumnName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(Int32));
      tbl.Columns.Add(SchemaTableColumn.ColumnSize, typeof(Int32));
      tbl.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(Int32));
      tbl.Columns.Add(SchemaTableColumn.NumericScale, typeof(Int32));
      tbl.Columns.Add(SchemaTableColumn.DataType, typeof(Type));
      tbl.Columns.Add(SchemaTableColumn.ProviderType, typeof(Int32));


      tbl.Columns.Add(SchemaTableColumn.IsLong, typeof(Boolean));


      tbl.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsReadOnly, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsRowVersion, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsUnique, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsKey, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsAutoIncrement, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(String));
      tbl.Columns.Add(SchemaTableOptionalColumn.BaseCatalogName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseTableName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(String));
      tbl.Columns.Add(SchemaTableOptionalColumn.BaseColumnNamespace, typeof(string));
      tbl.Columns.Add(SchemaTableOptionalColumn.DefaultValue, typeof(object));


      tbl.BeginLoadData();

      SQLiteConnection cnn = (SQLiteConnection)_command.Connection;

      try
      {
        cnn._sql.SetRealColNames(true);

        // Create a new command based on the original.  The only difference being that this new command returns
        // fully-qualified Database.Table.Column column names because of the above pragma
        using (SQLiteCommand cmd = new SQLiteCommand(_activeStatement._sqlStatement, cnn))
        {

          using (DbDataReader rd = cmd.ExecuteReader())
          {
            // No need to Read() from this reader, we just want the column names













            for (int n = 0; n < FieldCount; n++)


            {
              strTable = "";
              strCatalog = "main";

              row = tbl.NewRow();

              // Default settings for the column
              row[SchemaTableColumn.ColumnName] = GetName(n);
              row[SchemaTableColumn.ColumnOrdinal] = n;
              row[SchemaTableColumn.ColumnSize] = 0;
              row[SchemaTableColumn.NumericPrecision] = 0;
              row[SchemaTableColumn.NumericScale] = 0;
              row[SchemaTableColumn.DataType] = GetFieldType(n);
              row[SchemaTableColumn.ProviderType] = GetSQLiteType(n).Type;
              row[SchemaTableColumn.IsLong] = false;
              row[SchemaTableColumn.AllowDBNull] = true;

              row[SchemaTableOptionalColumn.IsReadOnly] = true;
              row[SchemaTableOptionalColumn.IsRowVersion] = false;
              row[SchemaTableColumn.IsUnique] = false;

              row[SchemaTableColumn.IsKey] = false;




              row[SchemaTableOptionalColumn.IsAutoIncrement] = false;




              row[SchemaTableOptionalColumn.IsReadOnly] = false;
              row[SchemaTableColumn.BaseColumnName] = GetName(n);

              // Try and extract the database, table and column from the datareader
              arName = rd.GetName(n).Split('.');

              if (arName.Length > 1)
                strTable = arName[arName.Length - 2];

              if (arName.Length > 2)
                strCatalog = arName[arName.Length - 3];

              // If we have a table-bound column, extract the extra information from it
              if (arName.Length > 1)
              {
                using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format("PRAGMA [{1}].TABLE_INFO([{0}])", strTable, strCatalog), cnn))
                {
                  if (arName.Length < 3) strCatalog = "";

                  using (DbDataReader rdTable = cmdTable.ExecuteReader())
                  {
                    while (rdTable.Read())

                    {

                      if (String.Compare(arName[arName.Length - 1], rdTable.GetString(1), true) == 0)
                      {
                        string strType = rdTable.GetString(2);
                        string[] arSize = strType.Split('(');
                        if (arSize.Length > 1)
                        {

                          arSize = arSize[1].Split(')');
                          if (arSize.Length > 1)




                            row["ColumnSize"] = Convert.ToInt32(arSize[0]);
                        }

                        bool bNotNull = rdTable.GetBoolean(3);
                        bool bPrimaryKey = rdTable.GetBoolean(5);

                        row[SchemaTableColumn.BaseTableName] = strTable;

                        row[SchemaTableColumn.BaseColumnName] = rdTable.GetString(1);



                        if (strCatalog.Length > 0)

                        {


                          row[SchemaTableOptionalColumn.BaseColumnNamespace] = strCatalog;
                          row[SchemaTableColumn.BaseSchemaName] = strCatalog;


                        }


                        row[SchemaTableColumn.AllowDBNull] = (!bNotNull && !bPrimaryKey);
                        row[SchemaTableColumn.IsUnique] = bPrimaryKey;

                        row[SchemaTableColumn.IsKey] = bPrimaryKey;

                        row[SchemaTableOptionalColumn.IsAutoIncrement] = (bPrimaryKey && String.Compare(strType, "Integer", true) == 0);
                        row[SchemaTableOptionalColumn.IsReadOnly] = !(bool)row[SchemaTableOptionalColumn.IsAutoIncrement];
                        if (rdTable.IsDBNull(4) == false)
                          row[SchemaTableOptionalColumn.DefaultValue] = rdTable[4];

                        break;
                      }
                    }
                  }
                }
              }
              tbl.Rows.Add(row);







            }





          }
        }





















      }




      catch (Exception e)


      {


        throw (e);

      }



      finally

      {



        cnn._sql.SetRealColNames(false);


      }






      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override string GetString(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.String);
      return _activeStatement._sql.GetText(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override object GetValue(int ordinal)
    {



      CheckClosed();
      if (IsDBNull(ordinal)) return DBNull.Value;


      if (GetFieldType(ordinal) == typeof(byte[]))




      {

        int n = (int)GetBytes(ordinal, 0, null, 0, 0);
        byte[] b = new byte[n];
        GetBytes(ordinal, 0, b, 0, n);


        return b;
      }


      return Convert.ChangeType(_activeStatement._sql.GetText(_activeStatement, ordinal), GetFieldType(ordinal), null);
    }

    /// <summary>

    /// 
    /// </summary>
    /// <param name="values"></param>
    /// <returns></returns>
    public override int GetValues(object[] values)
    {
      CheckClosed();

      int nMax = FieldCount;
      if (values.Length < nMax) nMax = values.Length;

      for (int n = 0; n < nMax; n++)
      {
        values.SetValue(GetValue(n), n);
      }

      return nMax;
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool HasRows
    {
      get
      {

        CheckClosed();
        return (_readingState != 2);
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsClosed
    {
      get { return (_command == null); }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override bool IsDBNull(int ordinal)
    {
      CheckClosed();
      return _activeStatement._sql.IsNull(_activeStatement, ordinal);
    }






    /// <summary>

    /// 
    /// </summary>
    /// <returns></returns>
    public override bool NextResult()
    {

      CheckClosed();

      SQLiteStatement stmt;
      int fieldCount;

      while (true)
      {
        _readingState = 2; // HasRows() returns false, Read() returns false

        if (_activeStatement != null)
        {
          // Reset the previously-executed command
          _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)
          {
            while (_activeStatementIndex + 1 != _command._statementList.Length)
            {


              _activeStatementIndex++;
              stmt = _command._statementList[_activeStatementIndex];
              stmt._sql.Step(stmt);





              stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
            }
            return false;
          }
        }




        // If we've reached the end of the statements, return false, no more resultsets
        if (_activeStatementIndex + 1 == _command._statementList.Length)
          return false;





        _activeStatementIndex++;

        stmt = _command._statementList[_activeStatementIndex];
        fieldCount = stmt._sql.ColumnCount(stmt);


        // If we're told to get schema information only, then don't perform an initial step() through the resultset
        if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)
        {
          if (stmt._sql.Step(stmt))
          {
            _readingState = -1;
          }
          else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
          {


            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
          }
        }

        // Ahh, we found a row-returning resultset eligible to be returned!
        _activeStatement = stmt;
        _fieldCount = fieldCount;
        _fieldTypeArray = null;




        return true;
      }
    }






    private SQLiteType GetSQLiteType(int ordinal)
    {



      if (_fieldTypeArray == null) _fieldTypeArray = new SQLiteType[_fieldCount];





      if (_fieldTypeArray[ordinal].Affinity == 0)




        _fieldTypeArray[ordinal].Type = SQLiteConvert.TypeNameToDbType(_activeStatement._sql.ColumnType(_activeStatement, ordinal, out _fieldTypeArray[ordinal].Affinity));



      return _fieldTypeArray[ordinal];
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override bool Read()
    {

      CheckClosed();

      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
      {



        if (_activeStatement._sql.Step(_activeStatement) == true)




          return true;



        _readingState = 1; // Finished reading rows
      }

      return false;
    }

    /// <summary>
    /// 
    /// </summary>
    public override int RecordsAffected
    {
      get { return _rowsAffected; }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public override object this[string name]
    {
      get { return GetValue(GetOrdinal(name)); }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override object this[int ordinal]
    {
      get { return GetValue(ordinal); }
    }
  }




}




Deleted System.Data.SQLite/SQLiteEnlistment.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
/********************************************************
 * 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!
 ********************************************************/

#if !PLATFORM_COMPACTFRAMEWORK
namespace System.Data.SQLite
{
  using System.Transactions;

  internal class SQLiteEnlistment : IEnlistmentNotification, IDisposable
  {
    internal SQLiteTransaction _transaction;
    internal Transaction _scope;
    internal bool _disposeConnection;

    internal SQLiteEnlistment(SQLiteConnection cnn, Transaction scope)
    {
      _transaction = cnn.BeginTransaction();
      _scope = scope;

      _scope.EnlistVolatile(this, System.Transactions.EnlistmentOptions.None);
    }

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

    #region IDisposable Members
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteEnlistment).Name);
#endif
    }

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

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                ////////////////////////////////////
                // dispose managed resources here...
                ////////////////////////////////////

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

                if (_scope != null)
                {
                    // _scope.Dispose(); // NOTE: Not "owned" by us.
                    _scope = null;
                }
            }

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

            disposed = true;
        }
    }
    #endregion

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

    #region Destructor
    ~SQLiteEnlistment()
    {
        Dispose(false);
    }
    #endregion

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

    private void Cleanup(SQLiteConnection cnn)
    {
      if (_disposeConnection)
        cnn.Dispose();

      _transaction = null;
      _scope = null;
    }

    #region IEnlistmentNotification Members

    public void Commit(Enlistment enlistment)
    {
      CheckDisposed();

      SQLiteConnection cnn = _transaction.Connection;
      cnn._enlistment = null;

      try
      {
        _transaction.IsValid(true);
        _transaction.Connection._transactionLevel = 1;
        _transaction.Commit();

        enlistment.Done();
      }
      finally
      {
        Cleanup(cnn);
      }
    }

    public void InDoubt(Enlistment enlistment)
    {
      CheckDisposed();
      enlistment.Done();
    }

    public void Prepare(PreparingEnlistment preparingEnlistment)
    {
      CheckDisposed();

      if (_transaction.IsValid(false) == false)
        preparingEnlistment.ForceRollback();
      else
        preparingEnlistment.Prepared();
    }

    public void Rollback(Enlistment enlistment)
    {
      CheckDisposed();

      SQLiteConnection cnn = _transaction.Connection;
      cnn._enlistment = null;

      try
      {
        _transaction.Rollback();
        enlistment.Done();
      }
      finally
      {
        Cleanup(cnn);
      }
    }

    #endregion
  }
}
#endif // !PLATFORM_COMPACT_FRAMEWORK
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































Changes to System.Data.SQLite/SQLiteException.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

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

#if !PLATFORM_COMPACTFRAMEWORK
  using System.Runtime.Serialization;
#endif

  /// <summary>
  /// SQLite exception class.
  /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
  [Serializable]
  public sealed class SQLiteException : DbException
#else
  public sealed class SQLiteException : Exception
#endif
  {
    private SQLiteErrorCode _errorCode;

#if !PLATFORM_COMPACTFRAMEWORK
    private SQLiteException(SerializationInfo info, StreamingContext context)
      : base(info, context)
    {

    }
#endif

    /// <summary>
    /// Public constructor for generating a SQLite error given the base error code
    /// </summary>
    /// <param name="errorCode">The SQLite error code to report</param>
    /// <param name="extendedInformation">Extra text to go along with the error message text</param>
    public SQLiteException(int errorCode, string extendedInformation)
      : base(GetStockErrorMessage(errorCode, extendedInformation))
    {
      _errorCode = (SQLiteErrorCode)errorCode;
    }

    /// <summary>
    /// Various public constructors that just pass along to the base Exception
    /// </summary>
    /// <param name="message">Passed verbatim to Exception</param>
    public SQLiteException(string message)
      : base(message)
    {
    }

    /// <summary>
    /// Various public constructors that just pass along to the base Exception
    /// </summary>
    public SQLiteException()
    {
    }

    /// <summary>
    /// Various public constructors that just pass along to the base Exception
    /// <param name="message">Passed to Exception</param>
    /// <param name="innerException">Passed to Exception</param>
    /// </summary>
    public SQLiteException(string message, Exception innerException)
      : base(message, innerException)
    {
    }

    /// <summary>
    /// Retrieves the underlying SQLite error code for this exception
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    public new SQLiteErrorCode ErrorCode
#else
    public SQLiteErrorCode ErrorCode
#endif
    {
      get { return _errorCode; }
    }

    /// <summary>
    /// Initializes the exception class with the SQLite error code.
    /// </summary>
    /// <param name="errorCode">The SQLite error code</param>
    /// <param name="errorMessage">A detailed error message</param>
    /// <returns>An error message string</returns>
    private static string GetStockErrorMessage(int errorCode, string errorMessage)
    {
      if (errorMessage == null) errorMessage = "";

      if (errorMessage.Length > 0)
        errorMessage = "\r\n" + errorMessage;

      if (errorCode < 0 || errorCode >= _errorMessages.Length)
        errorCode = 1;

      return _errorMessages[errorCode] + errorMessage;
    }

    private static string[] _errorMessages = {
      "SQLite OK",
      "SQLite error",
      "An internal logic error in SQLite",

      "Access permission denied",

      "Callback routine requested an abort",

      "The database file is locked",

      "A table in the database is locked",

      "malloc() failed",
      "Attempt to write a read-only database",
      "Operation terminated by sqlite3_interrupt()",
      "Some kind of disk I/O error occurred",
      "The database disk image is malformed",
      "Table or record not found",
      "Insertion failed because the database is full",
      "Unable to open the database file",
      "Database lock protocol error",
      "Database is empty",
      "The database schema changed",
      "Too much data for one row of a table",
      "Abort due to constraint violation",
      "Data type mismatch",
      "Library used incorrectly",
      "Uses OS features not supported on host",
      "Authorization denied",
      "Auxiliary database format error",
      "2nd parameter to sqlite3_bind() out of range",
      "File opened that is not a database file",
    };
  }

  /// <summary>
  /// SQLite error codes
  /// </summary>
  public enum SQLiteErrorCode
  {
    /// <summary>
    /// Success
    /// </summary>
    Ok = 0,
    /// <summary>
    /// SQL error or missing database
    /// </summary>
    Error,
    /// <summary>
    /// Internal logic error in SQLite
    /// </summary>
    Internal,
    /// <summary>
    /// Access permission denied
    /// </summary>
    Perm,
    /// <summary>
    /// Callback routine requested an abort
    /// </summary>
    Abort,
    /// <summary>
    /// The database file is locked
    /// </summary>
    Busy,
    /// <summary>
    /// A table in the database is locked
    /// </summary>
    Locked,
    /// <summary>
    /// malloc() failed
    /// </summary>
    NoMem,
    /// <summary>
    /// Attempt to write a read-only database
    /// </summary>
    ReadOnly,
    /// <summary>
    /// Operation terminated by sqlite3_interrupt()
    /// </summary>
    Interrupt,
    /// <summary>
    /// Some kind of disk I/O error occurred
    /// </summary>
    IOErr,
    /// <summary>
    /// The database disk image is malformed
    /// </summary>
    Corrupt,
    /// <summary>
    /// Table or record not found
    /// </summary>
    NotFound,
    /// <summary>
    /// Insertion failed because database is full
    /// </summary>
    Full,
    /// <summary>
    /// Unable to open the database file
    /// </summary>
    CantOpen,
    /// <summary>
    /// Database lock protocol error
    /// </summary>
    Protocol,
    /// <summary>
    /// Database is empty
    /// </summary>
    Empty,
    /// <summary>
    /// The database schema changed
    /// </summary>
    Schema,
    /// <summary>
    /// Too much data for one row of a table
    /// </summary>
    TooBig,
    /// <summary>
    /// Abort due to constraint violation
    /// </summary>
    Constraint,
    /// <summary>
    /// Data type mismatch
    /// </summary>
    Mismatch,
    /// <summary>
    /// Library used incorrectly
    /// </summary>
    Misuse,
    /// <summary>
    /// Uses OS features not supported on host
    /// </summary>
    NOLFS,
    /// <summary>
    /// Authorization denied
    /// </summary>
    Auth,
    /// <summary>
    /// Auxiliary database format error
    /// </summary>
    Format,
    /// <summary>
    /// 2nd parameter to sqlite3_bind out of range
    /// </summary>
    Range,
    /// <summary>
    /// File opened that is not a database file
    /// </summary>
    NotADatabase,
    /// <summary>
    /// sqlite3_step() has another row ready
    /// </summary>
    Row = 100,
    /// <summary>
    /// sqlite3_step() has finished executing
    /// </summary>
    Done = 101,



  }
}










|
<
<
|
<




<
<
<
<

<

<
|
<
<
<

>

<

<
<
<
<
<
|
<

|


<
<
<
<
|
<

<
|
<
<
<
<
|
<
|
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
|
<
|
<
<
|
<
<
|
<
<
<
<
<
<
|
>
|
>
|
>
|
>
|
>
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
|
<
<
|
|
<
<
|
|
<
<
|
|
<
<
|
|
<
|
<
|
<
|
<
|
<
<
|
|
<
|
<
|
<
<
|
|
<
|
<
|
<
|
<
<
|
|
<
|
<
<
|
|
<
<
|
|
<
|
<
|
<
|
<
|
<
<
<
<
<
<
<
<
<
<
>
>
>


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

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;


  using System.Text;


  /// <summary>
  /// SQLite exception class.
  /// </summary>




  public sealed class SQLiteException : Exception

  {

    internal SQLiteException(int nCode) : base(Initialize(nCode, null))



    {
      HResult = (int)((uint)0x800F0000 | (uint)nCode);
    }







    internal SQLiteException(int nCode, string strMessage) : base(Initialize(nCode, strMessage))

    {
      HResult = (int)((uint)0x800F0000 | (uint)nCode);
    }





    private static string Initialize(int nCode, string strMessage)

    {

      if (strMessage != null)




      {

        if (strMessage.Length > 0)






          strMessage = "\r\n\r\n" + strMessage;

      }












      switch (nCode)







      {

        case 1:


          return "SQLite error" + strMessage;


        case 2:






          return "An internal logic error in SQLite" + strMessage;
        case 3:
          return "Access permission denied" + strMessage;
        case 4:
          return "Callback routine requested an abort" + strMessage;
        case 5:
          return "The database file is locked" + strMessage;
        case 6:
          return "A table in the database is locked" + strMessage;
        case 7:
          return "A malloc() failed" + strMessage;








        case 8:












          return "Attempt to write a readonly database" + strMessage;


























        case 9:















          return "Operation terminated by sqlite3_interrupt()" + strMessage;

        case 10:

          return "Some kind of disk I/O error occurred" + strMessage;


        case 11:
          return "The database disk image is malformed" + strMessage;


        case 12:
          return "Table or record not found" + strMessage;


        case 13:
          return "Insertion failed because database is full" + strMessage;


        case 14:
          return "Unable to open the database file" + strMessage;

        case 15:

          return "Database lock protocol error" + strMessage;

        case 16:

          return "Database is empty" + strMessage;


        case 17:
          return "The database schema changed" + strMessage;

        case 18:

          return "Too much data for one row of a table" + strMessage;


        case 19:
          return "Abort due to constraint violation" + strMessage;

        case 20:

          return "Data type mismatch" + strMessage;

        case 21:


          return "Library used incorrectly" + strMessage;
        case 22:

          return "Uses OS features not supported on host" + strMessage;


        case 23:
          return "Authorization denied" + strMessage;


        case 24:
          return "Auxiliary database format error" + strMessage;

        case 25:

          return "2nd parameter to sqlite3_bind() out of range" + strMessage;

        case 26:

          return "File opened that is not a database file" + strMessage;










      }
      return strMessage;
    }
  }
}
Changes to System.Data.SQLite/SQLiteFactory.cs.
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
  using System;
  using System.Data.Common;

#if !PLATFORM_COMPACTFRAMEWORK
  /// <summary>
  /// SQLite implementation of DbProviderFactory.
  /// </summary>
  public sealed partial class SQLiteFactory : DbProviderFactory, IDisposable
  {
    /// <overloads>
    /// Constructs a new SQLiteFactory object
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteFactory()
    {
        //
        // NOTE: Do nothing here now.  All the logging setup related code has
        //       been moved to the new SQLiteLog static class.
        //
    }

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

    #region IDisposable Members
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteFactory).Name);
#endif
    }

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

    private void Dispose(bool disposing)
    {
        if (!disposed)
        {
            //if (disposing)
            //{
            //    ////////////////////////////////////
            //    // dispose managed resources here...
            //    ////////////////////////////////////
            //}

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

            disposed = true;
        }
    }
    #endregion

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

    #region Destructor
    ~SQLiteFactory()
    {
        Dispose(false);
    }
    #endregion

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

    /// <summary>
    /// This event is raised whenever SQLite raises a logging event.
    /// Note that this should be set as one of the first things in the
    /// application.  This event is provided for backward compatibility only.
    /// New code should use the SQLiteLog class instead.
    /// </summary>
    public event SQLiteLogEventHandler Log
    {
      add { CheckDisposed(); SQLiteLog.Log += value; }
      remove { CheckDisposed(); SQLiteLog.Log -= value; }
    }

    /// <summary>
    /// Static instance member which returns an instanced SQLiteFactory class.
    /// </summary>
    public static readonly SQLiteFactory Instance = new SQLiteFactory();













    /// <summary>
    /// Returns a new SQLiteCommand object.
    /// </summary>
    /// <returns>A SQLiteCommand object.</returns>
    public override DbCommand CreateCommand()
    {
      CheckDisposed();
      return new SQLiteCommand();
    }

    /// <summary>
    /// Returns a new SQLiteCommandBuilder object.
    /// </summary>
    /// <returns>A SQLiteCommandBuilder object.</returns>
    public override DbCommandBuilder CreateCommandBuilder()
    {
      CheckDisposed();
      return new SQLiteCommandBuilder();
    }

    /// <summary>
    /// Creates a new SQLiteConnection.
    /// </summary>
    /// <returns>A SQLiteConnection object.</returns>
    public override DbConnection CreateConnection()
    {
      CheckDisposed();
      return new SQLiteConnection();
    }

    /// <summary>
    /// Creates a new SQLiteConnectionStringBuilder.
    /// </summary>
    /// <returns>A SQLiteConnectionStringBuilder object.</returns>
    public override DbConnectionStringBuilder CreateConnectionStringBuilder()
    {
      CheckDisposed();
      return new SQLiteConnectionStringBuilder();
    }

    /// <summary>
    /// Creates a new SQLiteDataAdapter.
    /// </summary>
    /// <returns>A SQLiteDataAdapter object.</returns>
    public override DbDataAdapter CreateDataAdapter()
    {
      CheckDisposed();
      return new SQLiteDataAdapter();
    }

    /// <summary>
    /// Creates a new SQLiteParameter.
    /// </summary>
    /// <returns>A SQLiteParameter object.</returns>
    public override DbParameter CreateParameter()
    {
      CheckDisposed();
      return new SQLiteParameter();
    }
  }
#endif
}







|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




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







<









<









<









<









<









<





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
  using System;
  using System.Data.Common;

#if !PLATFORM_COMPACTFRAMEWORK
  /// <summary>
  /// SQLite implementation of DbProviderFactory.
  /// </summary>
  public sealed class SQLiteFactory : DbProviderFactory
  {

















































































    /// <summary>
    /// Static instance member which returns an instanced SQLiteFactory class.
    /// </summary>
    public static readonly SQLiteFactory Instance = new SQLiteFactory();

    /// <summary>
    /// Returns the types of classes this factory supports
    /// </summary>
    [Obsolete]
    public override DbProviderSupportedClasses SupportedClasses
    {
      get
      {
        return (DbProviderSupportedClasses)0x3F;
      }
    }

    /// <summary>
    /// Returns a new SQLiteCommand object.
    /// </summary>
    /// <returns>A SQLiteCommand object.</returns>
    public override DbCommand CreateCommand()
    {

      return new SQLiteCommand();
    }

    /// <summary>
    /// Returns a new SQLiteCommandBuilder object.
    /// </summary>
    /// <returns>A SQLiteCommandBuilder object.</returns>
    public override DbCommandBuilder CreateCommandBuilder()
    {

      return new SQLiteCommandBuilder();
    }

    /// <summary>
    /// Creates a new SQLiteConnection.
    /// </summary>
    /// <returns>A SQLiteConnection object.</returns>
    public override DbConnection CreateConnection()
    {

      return new SQLiteConnection();
    }

    /// <summary>
    /// Creates a new SQLiteConnectionStringBuilder.
    /// </summary>
    /// <returns>A SQLiteConnectionStringBuilder object.</returns>
    public override DbConnectionStringBuilder CreateConnectionStringBuilder()
    {

      return new SQLiteConnectionStringBuilder();
    }

    /// <summary>
    /// Creates a new SQLiteDataAdapter.
    /// </summary>
    /// <returns>A SQLiteDataAdapter object.</returns>
    public override DbDataAdapter CreateDataAdapter()
    {

      return new SQLiteDataAdapter();
    }

    /// <summary>
    /// Creates a new SQLiteParameter.
    /// </summary>
    /// <returns>A SQLiteParameter object.</returns>
    public override DbParameter CreateParameter()
    {

      return new SQLiteParameter();
    }
  }
#endif
}
Changes to System.Data.SQLite/SQLiteFunction.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;

  using System.Collections.Generic;
  using System.Runtime.InteropServices;
  using System.Globalization;

  /// <summary>
  /// This abstract class is designed to handle user-defined functions easily.  An instance of the derived class is made for each
  /// connection to the database.
  /// </summary>
  /// <remarks>
  /// Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access
  /// to the underlying connection.  This is necessary to deter implementers from thinking it would be a good idea to make database
  /// calls during processing.
  /// 
  /// It is important to distinguish between a per-connection instance, and a per-SQL statement context.  One instance of this class
  /// services all SQL statements being stepped through on that connection, and there can be many.  One should never store per-statement
  /// information in member variables of user-defined function classes.
  /// 
  /// For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step.  This data will
  /// be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes.
  /// </remarks>
  public abstract class SQLiteFunction : IDisposable
  {
    private class AggregateData
    {
      internal int _count = 1;
      internal object _data;
    }

    /// <summary>
    /// The base connection this function is attached to
    /// </summary>
    internal SQLiteBase              _base;

    /// <summary>
    /// Internal array used to keep track of aggregate function context data
    /// </summary>
    private Dictionary<long, AggregateData> _contextDataList;

    /// <summary>
    /// Holds a reference to the callback function for user functions
    /// </summary>
    private SQLiteCallback  _InvokeFunc;
    /// <summary>
    /// Holds a reference to the callbakc function for stepping in an aggregate function
    /// </summary>
    private SQLiteCallback  _StepFunc;
    /// <summary>
    /// Holds a reference to the callback function for finalizing an aggregate function
    /// </summary>
    private SQLiteFinalCallback  _FinalFunc;
    /// <summary>
    /// Holds a reference to the callback function for collation sequences
    /// </summary>
    private SQLiteCollation _CompareFunc;

    private SQLiteCollation _CompareFunc16;

    /// <summary>
    /// Current context of the current callback.  Only valid during a callback
    /// </summary>
    internal IntPtr _context;

    /// <summary>
    /// This static list contains all the user-defined functions declared using the proper attributes.
    /// </summary>
    private static List<SQLiteFunctionAttribute> _registeredFunctions;

    /// <summary>
    /// Internal constructor, initializes the function's internal variables.
    /// </summary>
    protected SQLiteFunction()
    {
      _contextDataList = new Dictionary<long, AggregateData>();
    }

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

    #region IDisposable Members
    /// <summary>
    /// Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if
    /// someone closes the connection while a DataReader is open.
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteFunction).Name);
#endif
    }

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

    /// <summary>
    /// Placeholder for a user-defined disposal routine
    /// </summary>
    /// <param name="disposing">True if the object is being disposed explicitly</param>
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                ////////////////////////////////////
                // dispose managed resources here...
                ////////////////////////////////////

                IDisposable disp;

                foreach (KeyValuePair<long, AggregateData> kv in _contextDataList)
                {
                    disp = kv.Value._data as IDisposable;
                    if (disp != null)
                        disp.Dispose();
                }
                _contextDataList.Clear();

                _InvokeFunc = null;
                _StepFunc = null;
                _FinalFunc = null;
                _CompareFunc = null;
                _base = null;
                _contextDataList = null;
            }

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

            disposed = true;
        }
    }
    #endregion

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

    #region Destructor
    ~SQLiteFunction()
    {
        Dispose(false);
    }
    #endregion

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

    /// <summary>
    /// Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert
    /// strings and DateTime's into the current connection's encoding schema.
    /// </summary>
    public SQLiteConvert SQLiteConvert
    {
      get
      {
        CheckDisposed();
        return _base;
      }
    }

    /// <summary>
    /// Scalar functions override this method to do their magic.
    /// </summary>
    /// <remarks>
    /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available
    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are
    /// DBNull.Value, Int64, Double, String or byte[] array.
    /// </remarks>
    /// <param name="args">The arguments for the command to process</param>
    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
    /// you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,
    /// just return it!</returns>
    public virtual object Invoke(object[] args)
    {
      CheckDisposed();
      return null;
    }

    /// <summary>
    /// Aggregate functions override this method to do their magic.
    /// </summary>
    /// <remarks>
    /// Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible.
    /// </remarks>
    /// <param name="args">The arguments for the command to process</param>
    /// <param name="stepNumber">The 1-based step number.  This is incrememted each time the step method is called.</param>
    /// <param name="contextData">A placeholder for implementers to store contextual data pertaining to the current context.</param>
    public virtual void Step(object[] args, int stepNumber, ref object contextData)
    {
      CheckDisposed();
    }

    /// <summary>
    /// Aggregate functions override this method to finish their aggregate processing.
    /// </summary>
    /// <remarks>
    /// If you implemented your aggregate function properly,
    /// you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have
    /// all the information you need in there to figure out what to return.
    /// NOTE:  It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will
    /// be null.  This can happen when no rows were returned.  You can either return null, or 0 or some other custom return value
    /// if that is the case.
    /// </remarks>
    /// <param name="contextData">Your own assigned contextData, provided for you so you can return your final results.</param>
    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
    /// you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,
    /// just return it!
    /// </returns>
    public virtual object Final(object contextData)
    {
      CheckDisposed();
      return null;
    }

    /// <summary>
    /// User-defined collation sequences override this method to provide a custom string sorting algorithm.
    /// </summary>
    /// <param name="param1">The first string to compare</param>
    /// <param name="param2">The second strnig to compare</param>
    /// <returns>1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2</returns>
    public virtual int Compare(string param1, string param2)
    {
      CheckDisposed();
      return 0;
    }

    /// <summary>
    /// Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to.
    /// </summary>
    /// <remarks>
    /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available
    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are
    /// DBNull.Value, Int64, Double, String or byte[] array.
    /// </remarks>
    /// <param name="nArgs">The number of arguments</param>
    /// <param name="argsptr">A pointer to the array of arguments</param>
    /// <returns>An object array of the arguments once they've been converted to .NET values</returns>
    internal object[] ConvertParams(int nArgs, IntPtr argsptr)
    {
      object[] parms = new object[nArgs];
#if !PLATFORM_COMPACTFRAMEWORK
      IntPtr[] argint = new IntPtr[nArgs];
#else
      int[] argint = new int[nArgs];
#endif
      Marshal.Copy(argsptr, argint, 0, nArgs);

      for (int n = 0; n < nArgs; n++)
      {
        switch (_base.GetParamValueType((IntPtr)argint[n]))
        {
          case TypeAffinity.Null:
            parms[n] = DBNull.Value;
            break;
          case TypeAffinity.Int64:
            parms[n] = _base.GetParamValueInt64((IntPtr)argint[n]);
            break;
          case TypeAffinity.Double:
            parms[n] = _base.GetParamValueDouble((IntPtr)argint[n]);
            break;
          case TypeAffinity.Text:
            parms[n] = _base.GetParamValueText((IntPtr)argint[n]);
            break;
          case TypeAffinity.Blob:
            {
              int x;
              byte[] blob;

              x = (int)_base.GetParamValueBytes((IntPtr)argint[n], 0, null, 0, 0);
              blob = new byte[x];
              _base.GetParamValueBytes((IntPtr)argint[n], 0, blob, 0, x);
              parms[n] = blob;
            }
            break;
          case TypeAffinity.DateTime: // Never happens here but what the heck, maybe it will one day.
            parms[n] = _base.ToDateTime(_base.GetParamValueText((IntPtr)argint[n]));
            break;
        }
      }
      return parms;
    }

    /// <summary>
    /// Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context.
    /// </summary>
    /// <param name="context">The context the return value applies to</param>
    /// <param name="returnValue">The parameter to return to SQLite</param>
    private void SetReturnValue(IntPtr context, object returnValue)
    {
      if (returnValue == null || returnValue == DBNull.Value)
      {
        _base.ReturnNull(context);
        return;
      }

      Type t = returnValue.GetType();
      if (t == typeof(DateTime))
      {
        _base.ReturnText(context, _base.ToString((DateTime)returnValue));
        return;
      }
      else
      {
        Exception r = returnValue as Exception;

        if (r != null)
        {
          _base.ReturnError(context, r.Message);
          return;
        }
      }

      switch (SQLiteConvert.TypeToAffinity(t))
      {
        case TypeAffinity.Null:
          _base.ReturnNull(context);
          return;
        case TypeAffinity.Int64:
          _base.ReturnInt64(context, Convert.ToInt64(returnValue, CultureInfo.CurrentCulture));
          return;
        case TypeAffinity.Double:
          _base.ReturnDouble(context, Convert.ToDouble(returnValue, CultureInfo.CurrentCulture));
          return;
        case TypeAffinity.Text:
          _base.ReturnText(context, returnValue.ToString());
          return;
        case TypeAffinity.Blob:
          _base.ReturnBlob(context, (byte[])returnValue);
          return;
      }
    }

    /// <summary>
    /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method.
    /// </summary>
    /// <param name="context">A raw context pointer</param>
    /// <param name="nArgs">Number of arguments passed in</param>
    /// <param name="argsptr">A pointer to the array of arguments</param>
    internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr)
    {
      _context = context;
      SetReturnValue(context, Invoke(ConvertParams(nArgs, argsptr)));
    }

    /// <summary>
    /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function.
    /// </summary>
    /// <param name="ptr">Not used</param>
    /// <param name="len1">Length of the string pv1</param>
    /// <param name="ptr1">Pointer to the first string to compare</param>
    /// <param name="len2">Length of the string pv2</param>
    /// <param name="ptr2">Pointer to the second string to compare</param>
    /// <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater
    /// than the second.</returns>
    internal int CompareCallback(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2)
    {
      return Compare(SQLiteConvert.UTF8ToString(ptr1, len1), SQLiteConvert.UTF8ToString(ptr2, len2));
    }

    internal int CompareCallback16(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2)
    {
      return Compare(SQLite3_UTF16.UTF16ToString(ptr1, len1), SQLite3_UTF16.UTF16ToString(ptr2, len2));
    }

    /// <summary>
    /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method.
    /// </summary>
    /// <remarks>
    /// This function takes care of doing the lookups and getting the important information put together to call the Step() function.
    /// That includes pulling out the user's contextData and updating it after the call is made.  We use a sorted list for this so
    /// binary searches can be done to find the data.
    /// </remarks>
    /// <param name="context">A raw context pointer</param>
    /// <param name="nArgs">Number of arguments passed in</param>
    /// <param name="argsptr">A pointer to the array of arguments</param>
    internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr)
    {
      long nAux;
      AggregateData data;

      nAux = (long)_base.AggregateContext(context);
      if (_contextDataList.TryGetValue(nAux, out data) == false)
      {
        data = new AggregateData();
        _contextDataList[nAux] = data;
      }

      try
      {
        _context = context;
        Step(ConvertParams(nArgs, argsptr), data._count, ref data._data);
      }
      finally
      {
        data._count++;
      }
    }

    /// <summary>
    /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method.
    /// </summary>
    /// <param name="context">A raw context pointer</param>
    internal void FinalCallback(IntPtr context)
    {
      long n = (long)_base.AggregateContext(context);
      object obj = null;

      if (_contextDataList.ContainsKey(n))
      {
        obj = _contextDataList[n]._data;
        _contextDataList.Remove(n);
      }

      _context = context;
      SetReturnValue(context, Final(obj));

      IDisposable disp = obj as IDisposable;
      if (disp != null) disp.Dispose();
    }

    /// <summary>
    /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that
    /// have a SQLiteFunctionAttribute attribute, and registering them accordingly.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Security.Permissions.FileIOPermission(Security.Permissions.SecurityAction.Assert, AllFiles = Security.Permissions.FileIOPermissionAccess.PathDiscovery)]
#endif
    static SQLiteFunction()
    {
      _registeredFunctions = new List<SQLiteFunctionAttribute>();
      try
      {
#if !PLATFORM_COMPACTFRAMEWORK
        SQLiteFunctionAttribute at;
        System.Reflection.Assembly[] arAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
        int w = arAssemblies.Length;
        System.Reflection.AssemblyName sqlite = System.Reflection.Assembly.GetCallingAssembly().GetName();

        for (int n = 0; n < w; n++)
        {
          Type[] arTypes;
          bool found = false;
          System.Reflection.AssemblyName[] references;
          try
          {
            // Inspect only assemblies that reference SQLite
            references = arAssemblies[n].GetReferencedAssemblies();
            int t = references.Length;
            for (int z = 0; z < t; z++)
            {
              if (references[z].Name == sqlite.Name)
              {
                found = true;
                break;
              }
            }

            if (found == false)
              continue;

            arTypes = arAssemblies[n].GetTypes();
          }
          catch (Reflection.ReflectionTypeLoadException e)
          {
            arTypes = e.Types;
          }

          int v = arTypes.Length;
          for (int x = 0; x < v; x++)
          {
            if (arTypes[x] == null) continue;

            object[] arAtt = arTypes[x].GetCustomAttributes(typeof(SQLiteFunctionAttribute), false);
            int u = arAtt.Length;
            for (int y = 0; y < u; y++)
            {
              at = arAtt[y] as SQLiteFunctionAttribute;
              if (at != null)
              {
                at._instanceType = arTypes[x];
                _registeredFunctions.Add(at);
              }
            }
          }
        }
#endif
      }
      catch // SQLite provider can continue without being able to find built-in functions
      {
      }
    }

    /// <summary>
    /// Manual method of registering a function.  The type must still have the SQLiteFunctionAttributes in order to work
    /// properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported.
    /// </summary>
    /// <param name="typ">The type of the function to register</param>
    public static void RegisterFunction(Type typ)
    {
      object[] arAtt = typ.GetCustomAttributes(typeof(SQLiteFunctionAttribute), false);
      int u = arAtt.Length;
      SQLiteFunctionAttribute at;

      for (int y = 0; y < u; y++)
      {
        at = arAtt[y] as SQLiteFunctionAttribute;
        if (at != null)
        {
          at._instanceType = typ;
          _registeredFunctions.Add(at);
        }
      }
    }

    /// <summary>
    /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
    /// as the connection (UTF-8 or UTF-16).
    /// </summary>
    /// <remarks>
    /// The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to
    /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
    /// </remarks>
    /// <param name="sqlbase">The base object on which the functions are to bind</param>
    /// <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>
    internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase)
    {
      SQLiteFunction f;
      List<SQLiteFunction> lFunctions = new List<SQLiteFunction>();

      foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
      {
        f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType);
        f._base = sqlbase;
        f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null;
        f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null;
        f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteFinalCallback(f.FinalCallback) : null;
        f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null;
        f._CompareFunc16 = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback16) : null;

        if (pr.FuncType != FunctionType.Collation)
          sqlbase.CreateFunction(pr.Name, pr.Arguments, (f is SQLiteFunctionEx), f._InvokeFunc, f._StepFunc, f._FinalFunc);
        else
          sqlbase.CreateCollation(pr.Name, f._CompareFunc, f._CompareFunc16);


        lFunctions.Add(f);
      }

      SQLiteFunction[] arFunctions = new SQLiteFunction[lFunctions.Count];
      lFunctions.CopyTo(arFunctions, 0);

      return arFunctions;
    }
  }

  /// <summary>
  /// Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call.
  /// </summary>
  /// <remarks>
  /// User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays.
  /// </remarks>
  public class SQLiteFunctionEx : SQLiteFunction
  {
    /// <summary>
    /// Obtains the collating sequence in effect for the given function.
    /// </summary>
    /// <returns></returns>
    protected CollationSequence GetCollationSequence()
    {
      return _base.GetCollationSequence(this, _context);
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteFunctionEx).Name);
#endif
    }

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

    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                //if (disposing)
                //{
                //    ////////////////////////////////////
                //    // dispose managed resources here...
                //    ////////////////////////////////////
                //}

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

                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
    #endregion
  }

  /// <summary>
  /// The type of user-defined function to declare
  /// </summary>
  public enum FunctionType
  {
    /// <summary>










>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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












































































































































































































































































































































































































































































































































































































































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

namespace System.Data.SQLite
{
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Runtime.InteropServices;













































































































































































































































































































































































































































































































































































































































  /// <summary>
  /// The type of user-defined function to declare
  /// </summary>
  public enum FunctionType
  {
    /// <summary>
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

  /// <summary>
  /// An internal callback delegate declaration.
  /// </summary>
  /// <param name="context">Raw context pointer for the user function</param>
  /// <param name="nArgs">Count of arguments to the function</param>
  /// <param name="argsptr">A pointer to the array of argument pointers</param>
#if !PLATFORM_COMPACTFRAMEWORK
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
  internal delegate void SQLiteCallback(IntPtr context, int nArgs, IntPtr argsptr);
  /// <summary>
  /// An internal final callback delegate declaration.
  /// </summary>
  /// <param name="context">Raw context pointer for the user function</param>
#if !PLATFORM_COMPACTFRAMEWORK
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
  internal delegate void SQLiteFinalCallback(IntPtr context);
  /// <summary>
  /// Internal callback delegate for implementing collation sequences
  /// </summary>
  /// <param name="puser">Not used</param>
  /// <param name="len1">Length of the string pv1</param>
  /// <param name="pv1">Pointer to the first string to compare</param>
  /// <param name="len2">Length of the string pv2</param>
  /// <param name="pv2">Pointer to the second string to compare</param>
  /// <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater
  /// than the second.</returns>























#if !PLATFORM_COMPACTFRAMEWORK




  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]



















#endif





  internal delegate int SQLiteCollation(IntPtr puser, int len1, IntPtr pv1, int len2, IntPtr pv2);


  /// <summary>
  /// The type of collating sequence
  /// </summary>
  public enum CollationTypeEnum
  {






    /// <summary>
    /// The built-in BINARY collating sequence

    /// </summary>













    Binary = 1,
    /// <summary>
    /// The built-in NOCASE collating sequence
    /// </summary>










    NoCase = 2,
    /// <summary>
    /// The built-in REVERSE collating sequence

    /// </summary>
    Reverse = 3,
    /// <summary>



    /// A custom user-defined collating sequence



    /// </summary>
    Custom = 0,
  }










  /// <summary>
  /// The encoding type the collation sequence uses
  /// </summary>



  public enum CollationEncodingEnum
  {



    /// <summary>
    /// The collation sequence is UTF8

    /// </summary>


































    UTF8 = 1,
    /// <summary>




    /// The collation sequence is UTF16 little-endian











    /// </summary>

    UTF16LE = 2,
    /// <summary>
    /// The collation sequence is UTF16 big-endian

    /// </summary>









    UTF16BE = 3,





  }


























  /// <summary>
  /// A struct describing the collating sequence a function is executing in

  /// </summary>
  public struct CollationSequence




  {



    /// <summary>
    /// The name of the collating sequence
    /// </summary>










    public string Name;
    /// <summary>
    /// The type of collating sequence
    /// </summary>













    public CollationTypeEnum Type;







    /// <summary>
    /// The text encoding of the collation sequence

    /// </summary>







    public CollationEncodingEnum Encoding;







    /// <summary>






    /// Context of the function that requested the collating sequence



    /// </summary>



    internal SQLiteFunction _func;






















    /// <summary>
    /// Calls the base collating sequence to compare two strings

    /// </summary>





    /// <param name="s1">The first string to compare</param>




















    /// <param name="s2">The second string to compare</param>
    /// <returns>-1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2</returns>





    public int Compare(string s1, string s2)
    {



      return _func._base.ContextCollateCompare(Encoding, _func._context, s1, s2);







    }











































    /// <summary>
    /// Calls the base collating sequence to compare two character arrays
    /// </summary>





    /// <param name="c1">The first array to compare</param>
    /// <param name="c2">The second array to compare</param>



    /// <returns>-1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2</returns>
    public int Compare(char[] c1, char[] c2)
    {
      return _func._base.ContextCollateCompare(Encoding, _func._context, c1, c2);



    }
  }
}







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



<






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

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

>
>
>
>
>
|
>
|
|
<
|
|
|
>
>
>
>
>
>

<
>

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

|

>
>
>
>
>
>
>
>
>
>
|

<
>

<
|
>
>
>
|
>
>
>
|
<
<
>
>
>
>
>
>
|
>
>
>
|
|
|
>
>
>
|
|
>
>
>

<
>

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

<
>

>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
<
>
|
<
>
>
>
>
|
>
>
>

|

>
>
>
>
>
>
>
>
>
>
|

|

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

<
>

>
>
>
>
>
>
>
|
>
>

>
>
>
>

>
>
>
>
>
>
|
>
>
>

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


|
>

>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
|

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

|

>
>
>
>
>
|
|
>
>
>
|
|
|
<
>
>
>



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

  /// <summary>
  /// An internal callback delegate declaration.
  /// </summary>
  /// <param name="context">Raw context pointer for the user function</param>
  /// <param name="nArgs">Count of arguments to the function</param>
  /// <param name="argsptr">A pointer to the array of argument pointers</param>



  internal delegate void SQLiteCallback(int context, int nArgs, IntPtr argsptr);








  /// <summary>
  /// Internal callback delegate for implementing collation sequences
  /// </summary>

  /// <param name="len1">Length of the string pv1</param>
  /// <param name="pv1">Pointer to the first string to compare</param>
  /// <param name="len2">Length of the string pv2</param>
  /// <param name="pv2">Pointer to the second string to compare</param>
  /// <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater
  /// than the second.</returns>
  internal delegate int SQLiteCollation(int len1, IntPtr pv1, int len2, IntPtr pv2);

  /// <summary>
  /// This abstract class is designed to handle user-defined functions easily.  An instance of the derived class is made for each
  /// connection to the database.
  /// </summary>
  /// <remarks>
  /// Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access
  /// to the underlying connection.  This is necessary to deter implementers from thinking it would be a good idea to make database
  /// calls during processing.
  /// 
  /// It is important to distinguish between a per-connection instance, and a per-SQL statement context.  One instance of this class
  /// services all SQL statements being stepped through on that connection, and there can be many.  One should never store per-statement
  /// information in member variables of user-defined function classes.
  /// 
  /// For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step.  This data will
  /// be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes.
  /// </remarks>
  public abstract class SQLiteFunction : IDisposable
  {

    private SQLiteBase              _base;
    private int                     _interopCookie;
#if !PLATFORM_COMPACTFRAMEWORK
    private SortedList<int, object> _contextDataList;
#else
    private SortedList _contextDataList;
#endif

    private SQLiteCallback  _InvokeFunc;
    private SQLiteCallback  _StepFunc;
    private SQLiteCallback  _FinalFunc;
    private SQLiteCollation _CompareFunc;

    /// <summary>
    /// This static list contains all the user-defined functions declared using the proper attributes.
    /// </summary>
    private static List<SQLiteFunctionAttribute> _registeredFunctions = new List<SQLiteFunctionAttribute>();

    /// <summary>
    /// Internal constructor, initializes the function's internal variables.
    /// </summary>
    protected SQLiteFunction()
    {
#if !PLATFORM_COMPACTFRAMEWORK
      _contextDataList = new SortedList<int, object>();
#else
      _contextDataList = new SortedList();
#endif
      _InvokeFunc = null;
      _StepFunc = null;
      _FinalFunc = null;
      _CompareFunc = null;
    }

    /// <summary>
    /// Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert
    /// strings and DateTime's into the current connection's encoding schema.

    /// </summary>
    public SQLiteConvert SQLiteConvert
    {
      get
      {
        return _base;
      }
    }

    /// <summary>

    /// Scalar functions override this method to do their magic.
    /// </summary>
    /// <remarks>
    /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available
    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are
    /// DBNull.Value, Int64, Double, String or byte[] array.
    /// </remarks>
    /// <param name="args">The arguments for the command to process</param>
    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
    /// you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,
    /// just return it!</returns>
    public virtual object Invoke(object[] args)
    {
      return null;
    }

    /// <summary>
    /// Aggregate functions override this method to do their magic.
    /// </summary>
    /// <remarks>
    /// Don't call the ReturnXXX functions of the context object during this function call.  Save it for the Final() method.
    /// Typically you'll just be updating whatever you've placed in the contextData field and returning as quickly as possible.
    /// </remarks>
    /// <param name="args">The arguments for the command to process</param>
    /// <param name="nStep">The 1-based step number.  This is incrememted each time the step method is called.</param>
    /// <param name="contextData">A placeholder for implementers to store contextual data pertaining to the current context.</param>
    public virtual void Step(object[] args, int nStep, ref object contextData)
    {
    }

    /// <summary>

    /// Aggregate functions override this method to finish their aggregate processing.
    /// </summary>

    /// <remarks>
    /// This is where you will call one of the ReturnXXX methods of the context class.  If you implemented your aggregate properly,
    /// you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have
    /// all the information you need in there to figure out what to return.
    /// 
    /// Parameters passed to this function have only an affinity for a certain data type, there is no underlying schema available
    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are
    /// DBNull.Value, Int64, Double, String or byte[] array.
    /// </remarks>


    /// <param name="contextData">Your own assigned contextData, provided for you so you can return your final results.</param>
    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
    /// you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,
    /// just return it!
    /// </returns>
    public virtual object Final(object contextData)
    {
      return null;
    }

    /// <summary>
    /// User-defined collation sequences override this method to provide a custom string sorting algorithm.
    /// </summary>
    /// <param name="param1">The first string to compare</param>
    /// <param name="param2">The second strnig to compare</param>
    /// <returns>1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2</returns>
    public virtual int Compare(string param1, string param2)
    {
      return 0;
    }

    /// <summary>

    /// Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to.
    /// </summary>
    /// <remarks>
    /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available
    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are
    /// DBNull.Value, Int64, Double, String or byte[] array.
    /// </remarks>
    /// <param name="nArgs">The number of arguments</param>
    /// <param name="argsptr">A pointer to the array of arguments</param>
    /// <returns>An object array of the arguments once they've been converted to .NET values</returns>
    internal object[] ConvertParams(int nArgs, IntPtr argsptr)
    {
      object[] parms = new object[nArgs];
      int[] argint = new int[nArgs];
      //string s;
      //DateTime dt;

      Marshal.Copy(argsptr, argint, 0, nArgs);

      for (int n = 0; n < nArgs; n++)
      {
        switch (_base.GetParamValueType(argint[n]))
        {
          case TypeAffinity.Null:
            parms[n] = DBNull.Value;
            break;
          case TypeAffinity.Int64:
            parms[n] = _base.GetParamValueInt64(argint[n]);
            break;
          case TypeAffinity.Double:
            parms[n] = _base.GetParamValueDouble(argint[n]);
            break;
          case TypeAffinity.Text:
            parms[n] = _base.GetParamValueText(argint[n]);
            //s = _base.GetParamValueText(argint[n]);
            //if (_base.TryToDateTime(s, out dt) == true) parms[n] = dt;
            //else parms[n] = s;
            break;
          case TypeAffinity.Blob:
            {
              int x;
              byte[] blob;

              x = (int)_base.GetParamValueBytes(argint[n], 0, null, 0, 0);
              blob = new byte[x];
              _base.GetParamValueBytes(argint[n], 0, blob, 0, x);
              parms[n] = blob;
            }
            break;
          case TypeAffinity.DateTime: // Never happens here but what the heck, maybe it will one day.
            parms[n] = _base.ToDateTime(_base.GetParamValueText(argint[n]));
            break;
        }
      }
      return parms;
    }

    /// <summary>

    /// Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context.
    /// </summary>
    /// <param name="context">The context the return value applies to</param>
    /// <param name="obj">The parameter to return to SQLite</param>
    void SetReturnValue(int context, object obj)
    {
      if (obj == null || obj == DBNull.Value)
      {
        _base.ReturnNull(context);
        return;
      }

      Type t = obj.GetType();
      if (t == typeof(DateTime))
      {
        _base.ReturnText(context, _base.ToString((DateTime)obj));
        return;
      }
      else if (obj as Exception != null)
      {
        _base.ReturnError(context, ((Exception)obj).Message);
        return;
      }

      switch (SQLiteConvert.TypeToAffinity(t))
      {
        case TypeAffinity.Null:
          _base.ReturnNull(context);
          return;
        case TypeAffinity.Int64:
          _base.ReturnInt64(context, Convert.ToInt64(obj));
          return;
        case TypeAffinity.Double:
          _base.ReturnDouble(context, Convert.ToDouble(obj));
          return;
        case TypeAffinity.Text:
          _base.ReturnText(context, obj.ToString());
          return;
        case TypeAffinity.Blob:
          _base.ReturnBlob(context, (byte[])obj);
          return;
      }
    }

    /// <summary>

    /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method.
    /// </summary>

    /// <param name="context">A raw context pointer</param>
    /// <param name="nArgs">Number of arguments passed in</param>
    /// <param name="argsptr">A pointer to the array of arguments</param>
    internal void ScalarCallback(int context, int nArgs, IntPtr argsptr)
    {
      SetReturnValue(context, Invoke(ConvertParams(nArgs, argsptr)));
    }

    /// <summary>
    /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function.
    /// </summary>
    /// <param name="len1">Length of the string pv1</param>
    /// <param name="ptr1">Pointer to the first string to compare</param>
    /// <param name="len2">Length of the string pv2</param>
    /// <param name="ptr2">Pointer to the second string to compare</param>
    /// <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater
    /// than the second.</returns>
    internal int CompareCallback(int len1, IntPtr ptr1, int len2, IntPtr ptr2)
    {
      return Compare(_base.ToString(ptr1, len1), _base.ToString(ptr2, len2));
    }

    /// <summary>
    /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method.
    /// </summary>
    /// <remarks>
    /// This function takes care of doing the lookups and getting the important information put together to call the Step() function.
    /// That includes pulling out the user's contextData and updating it after the call is made.  We use a sorted list for this so
    /// binary searches can be done to find the data.
    /// </remarks>
    /// <param name="context">A raw context pointer</param>
    /// <param name="nArgs">Number of arguments passed in</param>
    /// <param name="argsptr">A pointer to the array of arguments</param>
    internal void StepCallback(int context, int nArgs, IntPtr argsptr)
    {
      int n = _base.AggregateCount(context);
      int nAux;
      object obj = null;

      nAux = _base.AggregateContext(context);
      if (n > 1) obj = _contextDataList[nAux];

      Step(ConvertParams(nArgs, argsptr), _base.AggregateCount(context), ref obj);
      _contextDataList[nAux] = obj;      
    }

    /// <summary>

    /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method.
    /// </summary>
    /// <param name="context">A raw context pointer</param>
    /// <param name="nArgs">Not used, always zero</param>
    /// <param name="argsptr">Not used, always zero</param>
    internal void FinalCallback(int context, int nArgs, IntPtr argsptr)
    {
      int n = _base.AggregateContext(context);
      object obj = _contextDataList[n];

      SetReturnValue(context, Final(obj));
      _contextDataList.Remove(n);

      IDisposable disp = obj as IDisposable;
      if (disp != null) disp.Dispose();
    }

    /// <summary>
    /// Placeholder for a user-defined disposal routine
    /// </summary>
    /// <param name="bDisposing">True if the object is being disposed explicitly</param>
    protected virtual void Dispose(bool bDisposing)
    {
    }

    /// <summary>
    /// Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if
    /// someone closes the connection while a DataReader is open.
    /// </summary>
    public void Dispose()
    {
      Dispose(true);

      _InvokeFunc = null;
      _StepFunc = null;
      _FinalFunc = null;
      _CompareFunc = null;

      IDisposable disp;

#if !PLATFORM_COMPACTFRAMEWORK
      foreach (KeyValuePair<int, object> kv in _contextDataList)
#else
      foreach (DictionaryEntry kv in _contextDataList)
#endif
      {
        disp = kv.Value as IDisposable;
        if (disp != null)
          disp.Dispose();
      }
      _contextDataList.Clear();

      GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that
    /// have a SQLiteFunctionAttribute attribute, and registering them accordingly.
    /// </summary>
    static SQLiteFunction()
    {
      SQLiteFunctionAttribute at;
      System.Reflection.Assembly[] arAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
      int w = arAssemblies.Length;

      for (int n = 0; n < w; n++)
      {
        Type[] arTypes = arAssemblies[n].GetTypes();
        int v = arTypes.Length;
        for (int x = 0; x < v; x++)
        {
          object[] arAtt = arTypes[x].GetCustomAttributes(false);
          int u = arAtt.Length;
          for (int y = 0; y < u; y++)
          {
            at = arAtt[y] as SQLiteFunctionAttribute;
            if (at != null)
            {
              at.InstanceType = arTypes[x];
              _registeredFunctions.Add(at);
            }
          }
        }
      }
    }


    /// <summary>
    /// Manual method of registering a function.  The type must still have the SQLiteFunctionAttributes in order to work
    /// properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported.
    /// </summary>
    /// <param name="typ">The type of the function to register</param>
    public static void RegisterFunction(Type typ)
    {
      object[] arAtt = typ.GetCustomAttributes(false);
      int u = arAtt.Length;
      SQLiteFunctionAttribute at;

      for (int y = 0; y < u; y++)
      {
        at = arAtt[y] as SQLiteFunctionAttribute;
        if (at != null)
        {
          at.InstanceType = typ;
          _registeredFunctions.Add(at);
        }
      }
    }

    /// <summary>
    /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
    /// as the connection (UTF-8 or UTF-16).
    /// </summary>
    /// <remarks>
    /// The wrapper functions that interop with SQLite will create a unique cooke value, which internally is a pointer to
    /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
    /// </remarks>
    /// <param name="sqlbase">The base object on which the functions are to bind</param>
    /// <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>
    internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase)
    {
      SQLiteFunction f;
      List<SQLiteFunction> lFunctions = new List<SQLiteFunction>();

      foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
      {
        f = (SQLiteFunction)Activator.CreateInstance(pr.InstanceType);
        f._base = sqlbase;
        f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null;
        f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null;
        f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.FinalCallback) : null;
        f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null;

        if (pr.FuncType != FunctionType.Collation)
          f._interopCookie = sqlbase.CreateFunction(pr.Name, pr.Arguments, f._InvokeFunc, f._StepFunc, f._FinalFunc);
        else
          f._interopCookie = sqlbase.CreateCollation(pr.Name, f._CompareFunc);


        lFunctions.Add(f);
      }

      SQLiteFunction[] arFunctions = new SQLiteFunction[lFunctions.Count];
      lFunctions.CopyTo(arFunctions, 0);

      return arFunctions;
    }

    /// <summary>
    /// Issued after the base connection is closed, this function cleans up all user-defined functions and disposes of them.
    /// </summary>
    /// <remarks>
    /// Cleaning up here is done mainly because of the interop wrapper.  It allocated memory to hold a reference to all the
    /// delegates, and now must free that memory.
    /// Freeing is done after the connection is closed to ensure no callbacks get hit after we've freed the cookie.
    /// </remarks>
    /// <param name="sqlbase">The base SQLite connection object</param>
    /// <param name="ar">An array of user-defined functions for this object</param>
    internal static void UnbindFunctions(SQLiteBase sqlbase, SQLiteFunction[] ar)
    {
      if (ar == null) return;

      for (int n = 0; n < ar.Length; n++)
      {

        sqlbase.FreeFunction(ar[n]._interopCookie);
        ar[n].Dispose();
      }
    }
  }
}
Changes to System.Data.SQLite/SQLiteFunctionAttribute.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;


  /// <summary>
  /// A simple custom attribute to enable us to easily find user-defined functions in
  /// the loaded assemblies and initialize them in SQLite as connections are made.
  /// </summary>
  [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
  public sealed class SQLiteFunctionAttribute : Attribute
  {



    private string       _name;



    private int          _arguments;



    private FunctionType _functionType;

    internal Type        _instanceType;

    /// <summary>
    /// Default constructor, initializes the internal variables for the function.
    /// </summary>
    public SQLiteFunctionAttribute()
    {
      Name = "";
      Arguments = -1;
      FuncType = FunctionType.Scalar;
    }

    /// <summary>
    /// The function's name as it will be used in SQLite command text.
    /// </summary>
    public string Name
    {
      get { return _name; }
      set { _name = value; }
    }

    /// <summary>
    /// The number of arguments this function expects.  -1 if the number of arguments is variable.
    /// </summary>
    public int Arguments
    {
      get { return _arguments; }
      set { _arguments = value; }
    }

    /// <summary>
    /// The type of function this implementation will be.
    /// </summary>
    public FunctionType FuncType
    {
      get { return _functionType; }
      set { _functionType = value; }
    }
  }
}










>








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









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



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

namespace System.Data.SQLite
{
  using System;
  using System.Runtime.InteropServices;

  /// <summary>
  /// A simple custom attribute to enable us to easily find user-defined functions in
  /// the loaded assemblies and initialize them in SQLite as connections are made.
  /// </summary>
  [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
  public sealed class SQLiteFunctionAttribute : Attribute
  {
    /// <summary>
    /// The function's name as it will be used in SQLite command text.
    /// </summary>
    public string       Name;
    /// <summary>
    /// The number of arguments this function expects.  -1 if the number of arguments is variable.
    /// </summary>
    public int          Arguments;
    /// <summary>
    /// The type of function this implementation will be.
    /// </summary>
    public FunctionType FuncType;

    internal Type       InstanceType;

    /// <summary>
    /// Default constructor, initializes the internal variables for the function.
    /// </summary>
    public SQLiteFunctionAttribute()
    {
      Name = "";
      Arguments = -1;
      FuncType = FunctionType.Scalar;

      InstanceType = null;

























    }
  }
}
Deleted System.Data.SQLite/SQLiteKeyReader.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;
  using System.Globalization;

  /// <summary>
  /// This class provides key info for a given SQLite statement.
  /// <remarks>
  /// Providing key information for a given statement is non-trivial :(
  /// </remarks>
  /// </summary>
  internal sealed class SQLiteKeyReader : IDisposable
  {
    private KeyInfo[] _keyInfo;
    private SQLiteStatement _stmt;
    private bool _isValid;

    /// <summary>
    /// Used to support CommandBehavior.KeyInfo
    /// </summary>
    private struct KeyInfo
    {
      internal string databaseName;
      internal string tableName;
      internal string columnName;
      internal int database;
      internal int rootPage;
      internal int cursor;
      internal KeyQuery query;
      internal int column;
    }

    /// <summary>
    /// A single sub-query for a given table/database.
    /// </summary>
    private sealed class KeyQuery : IDisposable
    {
        private SQLiteCommand _command;
        internal SQLiteDataReader _reader;

        internal KeyQuery(SQLiteConnection cnn, string database, string table, params string[] columns)
        {
            using (SQLiteCommandBuilder builder = new SQLiteCommandBuilder())
            {
                _command = cnn.CreateCommand();
                for (int n = 0; n < columns.Length; n++)
                {
                    columns[n] = builder.QuoteIdentifier(columns[n]);
                }
            }
            _command.CommandText = String.Format(CultureInfo.InvariantCulture, "SELECT {0} FROM [{1}].[{2}] WHERE ROWID = ?", String.Join(",", columns), database, table);
            _command.Parameters.AddWithValue(null, (long)0);
        }

        internal bool IsValid
        {
            set
            {
                if (value != false) throw new ArgumentException();
                if (_reader != null)
                {
                    _reader.Dispose();
                    _reader = null;
                }
            }
        }

        internal void Sync(long rowid)
        {
            IsValid = false;
            _command.Parameters[0].Value = rowid;
            _reader = _command.ExecuteReader();
            _reader.Read();
        }

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

        #region IDisposable Members
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion

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

        #region IDisposable "Pattern" Members
        private bool disposed;
        private void CheckDisposed() /* throw */
        {
#if THROW_ON_DISPOSED
            if (disposed)
                throw new ObjectDisposedException(typeof(KeyQuery).Name);
#endif
        }

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

        private void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    IsValid = false;

                    if (_command != null) _command.Dispose();
                    _command = null;
                }

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

                disposed = true;
            }
        }
        #endregion

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

        #region Destructor
        ~KeyQuery()
        {
            Dispose(false);
        }
        #endregion
    }

    /// <summary>
    /// This function does all the nasty work at determining what keys need to be returned for
    /// a given statement.
    /// </summary>
    /// <param name="cnn"></param>
    /// <param name="reader"></param>
    /// <param name="stmt"></param>
    internal SQLiteKeyReader(SQLiteConnection cnn, SQLiteDataReader reader, SQLiteStatement stmt)
    {
      Dictionary<string, int> catalogs = new Dictionary<string, int>();
      Dictionary<string, List<string>> tables = new Dictionary<string, List<string>>();
      List<string> list;
      List<KeyInfo> keys = new List<KeyInfo>();

      // Record the statement so we can use it later for sync'ing
      _stmt = stmt;

      // Fetch all the attached databases on this connection
      using (DataTable tbl = cnn.GetSchema("Catalogs"))
      {
        foreach (DataRow row in tbl.Rows)
        {
          catalogs.Add((string)row["CATALOG_NAME"], Convert.ToInt32(row["ID"], CultureInfo.InvariantCulture));
        }
      }

      // Fetch all the unique tables and catalogs used by the current statement
      using (DataTable schema = reader.GetSchemaTable(false, false))
      {
        foreach (DataRow row in schema.Rows)
        {
          // Check if column is backed to a table
          if (row[SchemaTableOptionalColumn.BaseCatalogName] == DBNull.Value)
            continue;

          // Record the unique table so we can look up its keys
          string catalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];
          string table = (string)row[SchemaTableColumn.BaseTableName];

          if (tables.ContainsKey(catalog) == false)
          {
            list = new List<string>();
            tables.Add(catalog, list);
          }
          else
            list = tables[catalog];

          if (list.Contains(table) == false)
            list.Add(table);
        }

        // For each catalog and each table, query the indexes for the table.
        // Find a primary key index if there is one.  If not, find a unique index instead
        foreach (KeyValuePair<string, List<string>> pair in tables)
        {
          for (int i = 0; i < pair.Value.Count; i++)
          {
            string table = pair.Value[i];
            DataRow preferredRow = null;
            using (DataTable tbl = cnn.GetSchema("Indexes", new string[] { pair.Key, null, table }))
            {
              // Loop twice.  The first time looking for a primary key index, 
              // the second time looking for a unique index
              for (int n = 0; n < 2 && preferredRow == null; n++)
              {
                foreach (DataRow row in tbl.Rows)
                {
                  if (n == 0 && (bool)row["PRIMARY_KEY"] == true)
                  {
                    preferredRow = row;
                    break;
                  }
                  else if (n == 1 && (bool)row["UNIQUE"] == true)
                  {
                    preferredRow = row;
                    break;
                  }
                }
              }
              if (preferredRow == null) // Unable to find any suitable index for this table so remove it
              {
                pair.Value.RemoveAt(i);
                i--;
              }
              else // We found a usable index, so fetch the necessary table details
              {
                using (DataTable tblTables = cnn.GetSchema("Tables", new string[] { pair.Key, null, table }))
                {
                  // Find the root page of the table in the current statement and get the cursor that's iterating it
                  int database = catalogs[pair.Key];
                  int rootPage = Convert.ToInt32(tblTables.Rows[0]["TABLE_ROOTPAGE"], CultureInfo.InvariantCulture);
                  int cursor = stmt._sql.GetCursorForTable(stmt, database, rootPage);

                  // Now enumerate the members of the index we're going to use
                  using (DataTable indexColumns = cnn.GetSchema("IndexColumns", new string[] { pair.Key, null, table, (string)preferredRow["INDEX_NAME"] }))
                  {
                    KeyQuery query = null;

                    List<string> cols = new List<string>();
                    for (int x = 0; x < indexColumns.Rows.Count; x++)
                    {
                      bool addKey = true;
                      // If the column in the index already appears in the query, skip it
                      foreach (DataRow row in schema.Rows)
                      {
                        if (row.IsNull(SchemaTableColumn.BaseColumnName))
                          continue;

                        if ((string)row[SchemaTableColumn.BaseColumnName] == (string)indexColumns.Rows[x]["COLUMN_NAME"] &&
                            (string)row[SchemaTableColumn.BaseTableName] == table &&
                            (string)row[SchemaTableOptionalColumn.BaseCatalogName] == pair.Key)
                        {
                          indexColumns.Rows.RemoveAt(x);
                          x--;
                          addKey = false;
                          break;
                        }
                      }
                      if (addKey == true)
                        cols.Add((string)indexColumns.Rows[x]["COLUMN_NAME"]);
                    }

                    // If the index is not a rowid alias, record all the columns
                    // needed to make up the unique index and construct a SQL query for it
                    if ((string)preferredRow["INDEX_NAME"] != "sqlite_master_PK_" + table)
                    {
                      // Whatever remains of the columns we need that make up the index that are not
                      // already in the query need to be queried separately, so construct a subquery
                      if (cols.Count > 0)
                      {
                        string[] querycols = new string[cols.Count];
                        cols.CopyTo(querycols);
                        query = new KeyQuery(cnn, pair.Key, table, querycols);
                      }
                    }

                    // Create a KeyInfo struct for each column of the index
                    for (int x = 0; x < indexColumns.Rows.Count; x++)
                    {
                      string columnName = (string)indexColumns.Rows[x]["COLUMN_NAME"];
                      KeyInfo key = new KeyInfo();

                      key.rootPage = rootPage;
                      key.cursor = cursor;
                      key.database = database;
                      key.databaseName = pair.Key;
                      key.tableName = table;
                      key.columnName = columnName;
                      key.query = query;
                      key.column = x;

                      keys.Add(key);
                    }
                  }
                }
              }
            }
          }
        }
      }

      // Now we have all the additional columns we have to return in order to support
      // CommandBehavior.KeyInfo
      _keyInfo = new KeyInfo[keys.Count];
      keys.CopyTo(_keyInfo);
    }

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

    #region IDisposable Members
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteKeyReader).Name);
#endif
    }

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

    private void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                ////////////////////////////////////
                // dispose managed resources here...
                ////////////////////////////////////

                _stmt = null;

                if (_keyInfo == null) return;

                for (int n = 0; n < _keyInfo.Length; n++)
                {
                    if (_keyInfo[n].query != null)
                        _keyInfo[n].query.Dispose();
                }

                _keyInfo = null;
            }

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

            disposed = true;
        }
    }
    #endregion

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

    #region Destructor
    ~SQLiteKeyReader()
    {
        Dispose(false);
    }
    #endregion

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

    /// <summary>
    /// How many additional columns of keyinfo we're holding
    /// </summary>
    internal int Count
    {
      get { return (_keyInfo == null) ? 0 : _keyInfo.Length; }
    }

    internal void Sync(int i)
    {
      Sync();
      if (_keyInfo[i].cursor == -1)
        throw new InvalidCastException();
    }

    /// <summary>
    /// Make sure all the subqueries are open and ready and sync'd with the current rowid
    /// of the table they're supporting
    /// </summary>
    internal void Sync()
    {
      if (_isValid == true) return;

      KeyQuery last = null;

      for (int n = 0; n < _keyInfo.Length; n++)
      {
        if (_keyInfo[n].query == null || _keyInfo[n].query != last)
        {
          last = _keyInfo[n].query;

          if (last != null)
          {
            last.Sync(_stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[n].cursor));
          }
        }
      }
      _isValid = true;
    }

    /// <summary>
    /// Release any readers on any subqueries
    /// </summary>
    internal void Reset()
    {
      _isValid = false;
      if (_keyInfo == null) return;

      for (int n = 0; n < _keyInfo.Length; n++)
      {
        if (_keyInfo[n].query != null)
          _keyInfo[n].query.IsValid = false;
      }
    }

    internal string GetDataTypeName(int i)
    {
      Sync();
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDataTypeName(_keyInfo[i].column);
      else return "integer";
    }

    internal Type GetFieldType(int i)
    {
      Sync();
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetFieldType(_keyInfo[i].column);
      else return typeof(Int64);
    }

    internal string GetName(int i)
    {
      return _keyInfo[i].columnName;
    }

    internal int GetOrdinal(string name)
    {
      for (int n = 0; n < _keyInfo.Length; n++)
      {
        if (String.Compare(name, _keyInfo[n].columnName, StringComparison.OrdinalIgnoreCase) == 0) return n;
      }
      return -1;
    }

    internal bool GetBoolean(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetBoolean(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal byte GetByte(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetByte(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetBytes(_keyInfo[i].column, fieldOffset, buffer, bufferoffset, length);
      else throw new InvalidCastException();
    }

    internal char GetChar(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetChar(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal long GetChars(int i, long fieldOffset, char[] buffer, int bufferoffset, int length)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetChars(_keyInfo[i].column, fieldOffset, buffer, bufferoffset, length);
      else throw new InvalidCastException();
    }

    internal DateTime GetDateTime(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDateTime(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal decimal GetDecimal(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDecimal(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal double GetDouble(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDouble(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal float GetFloat(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetFloat(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal Guid GetGuid(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetGuid(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal Int16 GetInt16(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt16(_keyInfo[i].column);
      else
      {
        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);
        if (rowid == 0) throw new InvalidCastException();
        return Convert.ToInt16(rowid);
      }
    }

    internal Int32 GetInt32(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt32(_keyInfo[i].column);
      else
      {
        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);
        if (rowid == 0) throw new InvalidCastException();
        return Convert.ToInt32(rowid);
      }
    }

    internal Int64 GetInt64(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt64(_keyInfo[i].column);
      else
      {
        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);
        if (rowid == 0) throw new InvalidCastException();
        return Convert.ToInt64(rowid);
      }
    }

    internal string GetString(int i)
    {
      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetString(_keyInfo[i].column);
      else throw new InvalidCastException();
    }

    internal object GetValue(int i)
    {
      if (_keyInfo[i].cursor == -1) return DBNull.Value;

      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetValue(_keyInfo[i].column);

      if (IsDBNull(i) == true)
        return DBNull.Value;
      else return GetInt64(i);
    }

    internal bool IsDBNull(int i)
    {
      if (_keyInfo[i].cursor == -1) return true;

      Sync(i);
      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.IsDBNull(_keyInfo[i].column);
      else return _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor) == 0;
    }

    /// <summary>
    /// Append all the columns we've added to the original query to the schema
    /// </summary>
    /// <param name="tbl"></param>
    internal void AppendSchemaTable(DataTable tbl)
    {
      KeyQuery last = null;

      for (int n = 0; n < _keyInfo.Length; n++)
      {
        if (_keyInfo[n].query == null || _keyInfo[n].query != last)
        {
          last = _keyInfo[n].query;

          if (last == null) // ROWID aliases are treated special
          {
            DataRow row = tbl.NewRow();
            row[SchemaTableColumn.ColumnName] = _keyInfo[n].columnName;
            row[SchemaTableColumn.ColumnOrdinal] = tbl.Rows.Count;
            row[SchemaTableColumn.ColumnSize] = 8;
            row[SchemaTableColumn.NumericPrecision] = 255;
            row[SchemaTableColumn.NumericScale] = 255;
            row[SchemaTableColumn.ProviderType] = DbType.Int64;
            row[SchemaTableColumn.IsLong] = false;
            row[SchemaTableColumn.AllowDBNull] = false;
            row[SchemaTableOptionalColumn.IsReadOnly] = false;
            row[SchemaTableOptionalColumn.IsRowVersion] = false;
            row[SchemaTableColumn.IsUnique] = false;
            row[SchemaTableColumn.IsKey] = true;
            row[SchemaTableColumn.DataType] = typeof(Int64);
            row[SchemaTableOptionalColumn.IsHidden] = true;
            row[SchemaTableColumn.BaseColumnName] = _keyInfo[n].columnName;
            row[SchemaTableColumn.IsExpression] = false;
            row[SchemaTableColumn.IsAliased] = false;
            row[SchemaTableColumn.BaseTableName] = _keyInfo[n].tableName;
            row[SchemaTableOptionalColumn.BaseCatalogName] = _keyInfo[n].databaseName;
            row[SchemaTableOptionalColumn.IsAutoIncrement] = true;
            row["DataTypeName"] = "integer";

            tbl.Rows.Add(row);
          }
          else
          {
            last.Sync(0);
            using (DataTable tblSub = last._reader.GetSchemaTable())
            {
              foreach (DataRow row in tblSub.Rows)
              {
                object[] o = row.ItemArray;
                DataRow newrow = tbl.Rows.Add(o);
                newrow[SchemaTableOptionalColumn.IsHidden] = true;
                newrow[SchemaTableColumn.ColumnOrdinal] = tbl.Rows.Count - 1;
              }
            }
          }
        }
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite/SQLiteLog.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
    using System;
    using System.Data.Common;
    using System.Diagnostics;

    /// <summary>
    /// Passed during an Log callback
    /// </summary>
    public class LogEventArgs : EventArgs
    {
        /// <summary>
        /// The error code.
        /// </summary>
        public readonly int ErrorCode;

        /// <summary>
        /// SQL statement text as the statement first begins executing
        /// </summary>
        public readonly string Message;

        /// <summary>
        /// Extra data associated with this event, if any.
        /// </summary>
        public readonly object Data;

        /// <summary>
        /// Constructs the LogEventArgs object.
        /// </summary>
        /// <param name="pUserData">Should be null.</param>
        /// <param name="errorCode">The SQLite error code.</param>
        /// <param name="message">The error message, if any.</param>
        /// <param name="data">The extra data, if any.</param>
        internal LogEventArgs(
            IntPtr pUserData,
            int errorCode,
            string message,
            object data
            )
        {
            ErrorCode = errorCode;
            Message = message;
            Data = data;
        }
    }

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

    /// <summary>
    /// Raised when a log event occurs.
    /// </summary>
    /// <param name="sender">The current connection</param>
    /// <param name="e">Event arguments of the trace</param>
    public delegate void SQLiteLogEventHandler(object sender, LogEventArgs e);

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

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Manages the SQLite custom logging functionality and the associated
    /// callback for the whole process.
    /// </summary>
    public static class SQLiteLog
    {
        /// <summary>
        /// Object used to synchronize access to the static instance data
        /// for this class.
        /// </summary>
        private static object syncRoot = new object();

        /// <summary>
        /// Member variable to store the AppDomain.DomainUnload event handler.
        /// </summary>
        private static EventHandler _domainUnload;

        /// <summary>
        /// Member variable to store the application log handler to call.
        /// </summary>
        private static event SQLiteLogEventHandler _handlers;

        /// <summary>
        /// The default log event handler.
        /// </summary>
        private static SQLiteLogEventHandler _defaultHandler;

        /// <summary>
        /// The log callback passed to native SQLite engine.  This must live
        /// as long as the SQLite library has a pointer to it.
        /// </summary>
        private static SQLiteLogCallback _callback;

        /// <summary>
        /// The base SQLite object to interop with.
        /// </summary>
        private static SQLiteBase _sql;

        /// <summary>
        /// This will be non-zero if logging is currently enabled.
        /// </summary>
        private static bool _enabled;

        /// <summary>
        /// Initializes the SQLite logging facilities.
        /// </summary>
        public static void Initialize()
        {
            //
            // BUFXIX: We cannot initialize the logging interface if the SQLite
            //         core library has already been initialized anywhere in
            //         the process (see ticket [2ce0870fad]).
            //
            if (SQLite3.StaticIsInitialized())
                return;

            //
            // BUGFIX: To avoid nasty situations where multiple AppDomains are
            //         attempting to initialize and/or shutdown what is really
            //         a shared native resource (i.e. the SQLite core library
            //         is loaded per-process and has only one logging callback,
            //         not one per-AppDomain, which it knows nothing about),
            //         prevent all non-default AppDomains from registering a
            //         log handler unless the "Force_SQLiteLog" environment
            //         variable is used to manually override this safety check.
            //
            if (!AppDomain.CurrentDomain.IsDefaultAppDomain() &&
                Environment.GetEnvironmentVariable("Force_SQLiteLog") == null)
            {
                return;
            }

            lock (syncRoot)
            {
                //
                // NOTE: Add an event handler for the DomainUnload event so
                //       that we can unhook our logging managed function
                //       pointer from the native SQLite code prior to it
                //       being invalidated.
                //
                // BUGFIX: Make sure this event handler is only added one
                //         time (per-AppDomain).
                //
                if (_domainUnload == null)
                {
                    _domainUnload = new EventHandler(DomainUnload);
                    AppDomain.CurrentDomain.DomainUnload += _domainUnload;
                }

                //
                // NOTE: Create an instance of the SQLite wrapper class.
                //
                if (_sql == null)
                    _sql = new SQLite3(SQLiteDateFormats.Default,
                        DateTimeKind.Unspecified);

                //
                // NOTE: Create a single "global" (i.e. per-process) callback
                //       to register with SQLite.  This callback will pass the
                //       event on to any registered handler.  We only want to
                //       do this once.
                //
                if (_callback == null)
                {
                    _callback = new SQLiteLogCallback(LogCallback);

                    int rc = _sql.SetLogCallback(_callback);

                    if (rc != 0)
                        throw new SQLiteException(rc,
                            "Failed to initialize logging.");
                }

                //
                // NOTE: Logging is enabled by default.
                //
                _enabled = true;

                //
                // NOTE: For now, always setup the default log event handler.
                //
                AddDefaultHandler();
            }
        }

        /// <summary>
        /// Handles the AppDomain being unloaded.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void DomainUnload(
            object sender,
            EventArgs e
            )
        {
            lock (syncRoot)
            {
                //
                // NOTE: Remove the default log event handler.
                //
                RemoveDefaultHandler();

                //
                // NOTE: Disable logging.  If necessary, it can be re-enabled
                //       later by the Initialize method.
                //
                _enabled = false;

                //
                // BUGBUG: This will cause serious problems if other AppDomains
                //         have any open SQLite connections; however, there is
                //         currently no way around this limitation.
                //
                if (_sql != null)
                {
                    int rc = _sql.Shutdown();

                    if (rc != 0)
                        throw new SQLiteException(rc,
                            "Failed to shutdown interface.");

                    rc = _sql.SetLogCallback(null);

                    if (rc != 0)
                        throw new SQLiteException(rc,
                            "Failed to shutdown logging.");
                }

                //
                // BUGFIX: Make sure to reset the callback for next time.  This
                //         must be done after it has been succesfully removed
                //         as logging callback by the SQLite core library as we
                //         cannot allow native code to refer to a delegate that
                //         has been garbage collected.
                //
                if (_callback != null)
                {
                    _callback = null;
                }

                //
                // NOTE: Remove the event handler for the DomainUnload event
                //       that we added earlier.
                //
                if (_domainUnload != null)
                {
                    AppDomain.CurrentDomain.DomainUnload -= _domainUnload;
                    _domainUnload = null;
                }
            }
        }

        /// <summary>
        /// This event is raised whenever SQLite raises a logging event.
        /// Note that this should be set as one of the first things in the
        /// application.
        /// </summary>
        public static event SQLiteLogEventHandler Log
        {
            add
            {
                lock (syncRoot)
                {
                    // Remove any copies of this event handler from registered
                    // list.  This essentially means that a handler will be
                    // called only once no matter how many times it is added.
                    _handlers -= value;

                    // Add this to the list of event handlers.
                    _handlers += value;
                }
            }
            remove
            {
                lock (syncRoot)
                {
                    _handlers -= value;
                }
            }
        }

        /// <summary>
        /// If this property is true, logging is enabled; otherwise, logging is
        /// disabled.  When logging is disabled, no logging events will fire.
        /// </summary>
        public static bool Enabled
        {
            get { lock (syncRoot) { return _enabled; } }
            set { lock (syncRoot) { _enabled = value; } }
        }

        /// <summary>
        /// Log a message to all the registered log event handlers without going
        /// through the SQLite library.
        /// </summary>
        /// <param name="errorCode">The error code or zero for success.</param>
        /// <param name="message">The message to be logged.</param>
        public static void LogMessage(
            int errorCode,
            string message
            )
        {
            bool enabled;
            SQLiteLogEventHandler handlers;

            lock (syncRoot)
            {
                enabled = _enabled;
                handlers = _handlers;
            }

            if (enabled && (handlers != null))
                handlers(null, new LogEventArgs(
                    IntPtr.Zero, errorCode, message, null));
        }

        /// <summary>
        /// Creates and initializes the default log event handler.
        /// </summary>
        private static void InitializeDefaultHandler()
        {
            lock (syncRoot)
            {
                if (_defaultHandler == null)
                    _defaultHandler = new SQLiteLogEventHandler(LogEventHandler);
            }
        }

        /// <summary>
        /// Adds the default log event handler to the list of handlers.
        /// </summary>
        public static void AddDefaultHandler()
        {
            InitializeDefaultHandler();
            Log += _defaultHandler;
        }

        /// <summary>
        /// Removes the default log event handler from the list of handlers.
        /// </summary>
        public static void RemoveDefaultHandler()
        {
            InitializeDefaultHandler();
            Log -= _defaultHandler;
        }

        /// <summary>
        /// Internal proxy function that calls any registered application log
        /// event handlers.
        /// </summary>
        private static void LogCallback(
            IntPtr pUserData,
            int errorCode,
            IntPtr pMessage
            )
        {
            bool enabled;
            SQLiteLogEventHandler handlers;

            lock (syncRoot)
            {
                enabled = _enabled;
                handlers = _handlers;
            }

            if (enabled && (handlers != null))
                handlers(null, new LogEventArgs(pUserData, errorCode,
                    SQLiteBase.UTF8ToString(pMessage, -1), null));
        }

        /// <summary>
        /// Default logger.  Currently, uses the Trace class (i.e. sends events
        /// to the current trace listeners, if any).
        /// </summary>
        /// <param name="sender">Should be null.</param>
        /// <param name="e">The data associated with this event.</param>
        private static void LogEventHandler(
            object sender,
            LogEventArgs e
            )
        {
            if (e == null)
                return;

            string message = e.Message;

            if (message == null)
            {
                message = "<null>";
            }
            else
            {
                message = message.Trim();

                if (message.Length == 0)
                    message = "<empty>";
            }

            int errorCode = e.ErrorCode;

            Trace.WriteLine(String.Format(
                "SQLite {0} ({1}): {2}", errorCode == 0 ?
                "message" : "error", errorCode, message));
        }
    }
#endif
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































Deleted System.Data.SQLite/SQLiteMetaDataCollectionNames.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  /// <summary>
  /// MetaDataCollections specific to SQLite
  /// </summary>
  public static class SQLiteMetaDataCollectionNames
  {
    /// <summary>
    /// Returns a list of databases attached to the connection
    /// </summary>
    public static readonly string Catalogs = "Catalogs";
    /// <summary>
    /// Returns column information for the specified table
    /// </summary>
    public static readonly string Columns = "Columns";
    /// <summary>
    /// Returns index information for the optionally-specified table
    /// </summary>
    public static readonly string Indexes = "Indexes";
    /// <summary>
    /// Returns base columns for the given index
    /// </summary>
    public static readonly string IndexColumns = "IndexColumns";
    /// <summary>
    /// Returns the tables in the given catalog
    /// </summary>
    public static readonly string Tables = "Tables";
    /// <summary>
    /// Returns user-defined views in the given catalog
    /// </summary>
    public static readonly string Views = "Views";
    /// <summary>
    /// Returns underlying column information on the given view
    /// </summary>
    public static readonly string ViewColumns = "ViewColumns";
    /// <summary>
    /// Returns foreign key information for the given catalog
    /// </summary>
    public static readonly string ForeignKeys = "ForeignKeys";
    /// <summary>
    /// Returns the triggers on the database
    /// </summary>
    public static readonly string Triggers = "Triggers";
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































Changes to System.Data.SQLite/SQLiteParameter.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

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

  /// <summary>
  /// SQLite implementation of DbParameter.
  /// </summary>
  public sealed class SQLiteParameter : DbParameter, ICloneable
  {
    /// <summary>
    /// The data type of the parameter
    /// </summary>
    internal int            _dbType;
    /// <summary>
    /// The version information for mapping the parameter
    /// </summary>
    private DataRowVersion _rowVersion;
    /// <summary>
    /// The value of the data in the parameter
    /// </summary>
    private Object         _objValue;
    /// <summary>
    /// The source column for the parameter
    /// </summary>
    private string         _sourceColumn;
    /// <summary>
    /// The column name
    /// </summary>
    private string         _parameterName;
    /// <summary>
    /// The data size, unused by SQLite
    /// </summary>
    private int            _dataSize;

    private bool           _nullable;
    private bool           _nullMapping;

    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteParameter() 
      : this(null, (DbType)(-1), 0, null, DataRowVersion.Current)
    {

    }

    /// <summary>
    /// Constructs a named parameter given the specified parameter name
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    public SQLiteParameter(string parameterName)
      : this(parameterName, (DbType)(-1), 0, null, DataRowVersion.Current)
    {

    }

    /// <summary>
    /// Constructs a named parameter given the specified parameter name and initial value
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="value">The initial value of the parameter</param>
    public SQLiteParameter(string parameterName, object value)
      : this(parameterName, (DbType)(-1), 0, null, DataRowVersion.Current)
    {
      Value = value;
    }

    /// <summary>
    /// Constructs a named parameter of the specified type
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="dbType">The datatype of the parameter</param>
    public SQLiteParameter(string parameterName, DbType dbType)
      : this(parameterName, dbType, 0, null, DataRowVersion.Current)
    {

    }

    /// <summary>
    /// Constructs a named parameter of the specified type and source column reference
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="dbType">The data type</param>
    /// <param name="sourceColumn">The source column</param>
    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn)
      : this(parameterName, dbType, 0, sourceColumn, DataRowVersion.Current)
    {

    }

    /// <summary>
    /// Constructs a named parameter of the specified type, source column and row version
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="dbType">The data type</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn, DataRowVersion rowVersion)
      : this(parameterName, dbType, 0, sourceColumn, rowVersion)
    {

    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified data type
    /// </summary>
    /// <param name="dbType">The datatype of the parameter</param>
    public SQLiteParameter(DbType dbType)
      : this(null, dbType, 0, null, DataRowVersion.Current)
    {

    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified data type and sets the initial value
    /// </summary>
    /// <param name="dbType">The datatype of the parameter</param>
    /// <param name="value">The initial value of the parameter</param>
    public SQLiteParameter(DbType dbType, object value)
      : this(null, dbType, 0, null, DataRowVersion.Current)
    {
      Value = value;
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified data type and source column
    /// </summary>
    /// <param name="dbType">The datatype of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    public SQLiteParameter(DbType dbType, string sourceColumn)
      : this(null, dbType, 0, sourceColumn, DataRowVersion.Current)
    {

    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified data type, source column and row version
    /// </summary>
    /// <param name="dbType">The data type</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(DbType dbType, string sourceColumn, DataRowVersion rowVersion)

      : this(null, dbType, 0, sourceColumn, rowVersion)

    {









    }

    /// <summary>
    /// Constructs a named parameter of the specified type and size

    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>

    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize)
      : this(parameterName, parameterType, parameterSize, null, DataRowVersion.Current)
    {

    }

    /// <summary>











    /// Constructs a named parameter of the specified type, size and source column


    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <param name="parameterType">The data type</param>









    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)

      : this(parameterName, parameterType, parameterSize, sourceColumn, DataRowVersion.Current)

    {










    }

    /// <summary>
    /// Constructs a named parameter of the specified type, size, source column and row version

    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)      
    {
      _parameterName = parameterName;
      _dbType = (int)parameterType;
      _sourceColumn = sourceColumn;
      _rowVersion = rowVersion;
      _dataSize = parameterSize;
      _nullable = true;
    }

    private SQLiteParameter(SQLiteParameter source)
      : this(source.ParameterName, (DbType)source._dbType, 0, source.Direction, source.IsNullable, 0, 0, source.SourceColumn, source.SourceVersion, source.Value)
    {
      _nullMapping = source._nullMapping;
    }

    /// <summary>
    /// Constructs a named parameter of the specified type, size, source column and row version
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="direction">Only input parameters are supported in SQLite</param>
    /// <param name="isNullable">Ignored</param>
    /// <param name="precision">Ignored</param>
    /// <param name="scale">Ignored</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    /// <param name="value">The initial value to assign the parameter</param>   
#if !PLATFORM_COMPACTFRAMEWORK
    [EditorBrowsable(EditorBrowsableState.Advanced)]
#endif
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, object value)
      : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion)
    {
      Direction = direction;
      IsNullable = isNullable;
      Value = value;
    }

    /// <summary>
    /// Constructs a named parameter, yet another flavor
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="direction">Only input parameters are supported in SQLite</param>
    /// <param name="precision">Ignored</param>
    /// <param name="scale">Ignored</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    /// <param name="sourceColumnNullMapping">Whether or not this parameter is for comparing NULL's</param>
    /// <param name="value">The intial value to assign the parameter</param>
#if !PLATFORM_COMPACTFRAMEWORK
    [EditorBrowsable(EditorBrowsableState.Advanced)]
#endif
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, bool sourceColumnNullMapping, object value)
      : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion)
    {
      Direction = direction;
      SourceColumnNullMapping = sourceColumnNullMapping;
      Value = value;
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified type and size
    /// </summary>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    public SQLiteParameter(DbType parameterType, int parameterSize)
      : this(null, parameterType, parameterSize, null, DataRowVersion.Current)
    {
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified type, size, and source column
    /// </summary>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    public SQLiteParameter(DbType parameterType, int parameterSize, string sourceColumn)
      : this(null, parameterType, parameterSize, sourceColumn, DataRowVersion.Current)
    {
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified type, size, source column and row version
    /// </summary>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)
      : this(null, parameterType, parameterSize, sourceColumn, rowVersion)
    {
    }

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

    /// <summary>
    /// Returns the datatype of the parameter
    /// </summary>

#if !PLATFORM_COMPACTFRAMEWORK
    [DbProviderSpecificTypeProperty(true)]



    [RefreshProperties(RefreshProperties.All)]
#endif



    public override DbType DbType
    {
      get
      {
        if (_dbType == -1)
        {
          if (_objValue != null && _objValue != DBNull.Value)
          {
            return SQLiteConvert.TypeToDbType(_objValue.GetType());
          }
          return DbType.String; // Unassigned default value is String
        }
        return (DbType)_dbType;
      }
      set
      {
        _dbType = (int)value;
      }
    }

    /// <summary>
    /// Supports only input parameters
    /// </summary>
    public override ParameterDirection Direction
    {
      get
      {
        return ParameterDirection.Input;
      }
      set
      {
        if (value != ParameterDirection.Input)
          throw new NotSupportedException();














      }
    }

    /// <summary>
    /// Returns the parameter name
    /// </summary>
    public override string ParameterName
    {
      get
      {
        return _parameterName;
      }
      set
      {
        _parameterName = value;
      }
    }

    /// <summary>
    /// Resets the DbType of the parameter so it can be inferred from the value
    /// </summary>
    public override void ResetDbType()
    {
      _dbType = -1;
    }

    /// <summary>
    /// Returns the size of the parameter
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [DefaultValue((int)0)]
#endif
    public override int Size
    {
      get
      {
        return _dataSize;
      }
      set
      {
        _dataSize = value;
      }
    }

    /// <summary>
    /// Gets/sets the source column
    /// </summary>
    public override string SourceColumn
    {
      get
      {
        return _sourceColumn;
      }
      set
      {
        _sourceColumn = value;
      }
    }

    /// <summary>
    /// Used by DbCommandBuilder to determine the mapping for nullable fields
    /// </summary>
    public override bool SourceColumnNullMapping
    {
      get
      {
        return _nullMapping;
      }
      set
      {
        _nullMapping = value;
      }
    }

    /// <summary>
    /// Gets and sets the row version
    /// </summary>
    public override DataRowVersion SourceVersion
    {
      get
      {
        return _rowVersion;
      }
      set
      {
        _rowVersion = value;
      }
    }

    /// <summary>
    /// Gets and sets the parameter value.  If no datatype was specified, the datatype will assume the type from the value given.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [TypeConverter(typeof(StringConverter)), RefreshProperties(RefreshProperties.All)]
#endif
    public override object Value
    {
      get
      {
        return _objValue;
      }
      set
      {
        _objValue = value;
        if (_dbType == -1 && _objValue != null && _objValue != DBNull.Value) // If the DbType has never been assigned, try to glean one from the value's datatype 
          _dbType = (int)SQLiteConvert.TypeToDbType(_objValue.GetType());
      }
    }

    /// <summary>
    /// Clones a parameter
    /// </summary>
    /// <returns>A new, unassociated SQLiteParameter</returns>
    public object Clone()
    {
      SQLiteParameter newparam = new SQLiteParameter(this);

      return newparam;
    }
  }
}












<




|

<
<
<
|
<
<
<

<
<
<

<
<
<

<
<
<
|
<
<
<


<
<
<

|

|
<

>



|

|

<

>



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

|
|

<

>



|

|
|
|

<

>



|

|
|
|
|

<

>



|

|

<

>



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

|
|

<

>



|

|
|
|

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



<
>

|
|
|
>
|
<

>



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

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



<
>

|
|
|
|
|
|

|
|


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



<
|
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|



<




|

>
|
|
>
>
>
|
<
>
>
>




<
<
<
<
<
<
|
<









|










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




|





|



|




|



|



|

<
<
<













|














|





|



<




|














|

<
<
<












|
|
<
<
<
<
<
<
<
|
<
<
<
<
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




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

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


  /// <summary>
  /// SQLite implementation of DbParameter.
  /// </summary>
  public sealed class SQLiteParameter : DbParameter
  {



    private int            _dbType;



    private DataRowVersion _rowVersion;



    private Object         _objValue;



    private string         _sourceColumn;



    private string         _columnName;



    private int            _dataSize;




    /// <summary>
    /// 
    /// </summary>
    public SQLiteParameter()

    {
      Initialize(null, -1, 0, null, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    public SQLiteParameter(string parameterName)

    {
      Initialize(parameterName, -1, 0, null, DataRowVersion.Current);
    }

    /// <summary>

    /// 










    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    public SQLiteParameter(string parameterName, DbType dbType)

    {
      Initialize(parameterName, (int)dbType, 0, null, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="sourceColumn"></param>
    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn)

    {
      Initialize(parameterName, (int)dbType, 0, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn, DataRowVersion rowVersion)

    {
      Initialize(parameterName, (int)dbType, 0, sourceColumn, rowVersion);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbType"></param>
    public SQLiteParameter(DbType dbType)

    {
      Initialize(null, (int)dbType, 0, null, DataRowVersion.Current);
    }

    /// <summary>

    /// 










    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="sourceColumn"></param>
    public SQLiteParameter(DbType dbType, string sourceColumn)

    {
      Initialize(null, (int)dbType, 0, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    public SQLiteParameter(DbType dbType, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(null, (int)dbType, 0, sourceColumn, rowVersion);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    public SQLiteParameter(string parameterName, DbType dbType, int nSize)
    {
      Initialize(parameterName, (int)dbType, nSize, null, DataRowVersion.Current);
    }

    /// <summary>

    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    public SQLiteParameter(string parameterName, DbType dbType, int nSize, string sourceColumn)

    {
      Initialize(parameterName, (int)dbType, nSize, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    public SQLiteParameter(string parameterName, DbType dbType, int nSize, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(parameterName, (int)dbType, nSize, sourceColumn, rowVersion);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    public SQLiteParameter(DbType dbType, int nSize)
    {
      Initialize(null, (int)dbType, nSize, null, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    public SQLiteParameter(DbType dbType, int nSize, string sourceColumn)
    {
      Initialize(null, (int)dbType, nSize, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    public SQLiteParameter(DbType dbType, int nSize, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(null, (int)dbType, nSize, sourceColumn, rowVersion);
    }

    /// <summary>

    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    private void Initialize(string parameterName, int dbType, int nSize, string sourceColumn, DataRowVersion rowVersion)
    {
      _columnName = parameterName;
      _dbType = dbType;
      _sourceColumn = sourceColumn;
      _rowVersion = rowVersion;































      _objValue = null;

      _dataSize = nSize;






















    }

    /// <summary>

    /// 









    /// </summary>























    public override bool IsNullable
    {
      get
      {
        return true;
      }
      set 
      {

      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="destination"></param>
    [Obsolete]
    public override void CopyTo(DbParameter destination)
    {
      throw new NotImplementedException();
    }


    /// <summary>
    /// 
    /// </summary>
    public override DbType DbType
    {
      get
      {






        if (_dbType == -1) return DbType.String; // Unassigned default value is String

        return (DbType)_dbType;
      }
      set
      {
        _dbType = (int)value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override ParameterDirection Direction
    {
      get
      {
        return ParameterDirection.Input;
      }
      set
      {
        if (value != ParameterDirection.Input)
          throw new NotImplementedException();
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override int Offset
    {
      get
      {
        throw new NotImplementedException();
      }
      set
      {
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override string ParameterName
    {
      get
      {
        return _columnName;
      }
      set
      {
        _columnName = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override void ResetDbType()
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// 
    /// </summary>



    public override int Size
    {
      get
      {
        return _dataSize;
      }
      set
      {
        _dataSize = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override string SourceColumn
    {
      get
      {
        return _sourceColumn;
      }
      set
      {
        _sourceColumn = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool SourceColumnNullMapping
    {
      get
      {
        return false;
      }
      set
      {

      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override DataRowVersion SourceVersion
    {
      get
      {
        return _rowVersion;
      }
      set
      {
        _rowVersion = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>



    public override object Value
    {
      get
      {
        return _objValue;
      }
      set
      {
        _objValue = value;
        if (_dbType == -1 && _objValue != null && _objValue != DBNull.Value) // If the DbType has never been assigned, try to glean one from the value's datatype 
          _dbType = (int)SQLiteConvert.TypeToDbType(_objValue.GetType());
      }
    }    
  }







}




Changes to System.Data.SQLite/SQLiteParameterCollection.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;
  using System.Globalization;

#if !PLATFORM_COMPACTFRAMEWORK
  using System.ComponentModel;
#endif

  using System.Reflection;

  /// <summary>
  /// SQLite implementation of DbParameterCollection.
  /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
  [Editor("Microsoft.VSDesigner.Data.Design.DBParametersEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), ListBindable(false)]
#endif
  public sealed class SQLiteParameterCollection : DbParameterCollection
  {
    /// <summary>
    /// The underlying command to which this collection belongs
    /// </summary>
    private SQLiteCommand         _command;
    /// <summary>
    /// The internal array of parameters in this collection
    /// </summary>
    private List<SQLiteParameter> _parameterList;
    /// <summary>
    /// Determines whether or not all parameters have been bound to their statement(s)
    /// </summary>
    private bool                  _unboundFlag;

    /// <summary>
    /// Initializes the collection
    /// </summary>
    /// <param name="cmd">The command to which the collection belongs</param>
    internal SQLiteParameterCollection(SQLiteCommand cmd)
    {
      _command = cmd;
      _parameterList = new List<SQLiteParameter>();
      _unboundFlag = true;
    }

    /// <summary>
    /// Returns true
    /// </summary>
    public override bool IsSynchronized
    {
      get { return true; }
    }

    /// <summary>
    /// Returns false
    /// </summary>
    public override bool IsFixedSize
    {
      get { return false; }
    }

    /// <summary>
    /// Returns false
    /// </summary>
    public override bool IsReadOnly
    {
      get { return false; }
    }

    /// <summary>
    /// Returns null
    /// </summary>
    public override object SyncRoot
    {
      get { return null; }
    }

    /// <summary>
    /// Retrieves an enumerator for the collection
    /// </summary>
    /// <returns>An enumerator for the underlying array</returns>
    public override System.Collections.IEnumerator GetEnumerator()
    {
      return _parameterList.GetEnumerator();
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the value</param>
    /// <param name="sourceColumn">The source column</param>
    /// <returns>A SQLiteParameter object</returns>
    public SQLiteParameter Add(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)
    {
      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType, parameterSize, sourceColumn);
      Add(param);

      return param;
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the value</param>
    /// <returns>A SQLiteParameter object</returns>
    public SQLiteParameter Add(string parameterName, DbType parameterType, int parameterSize)
    {
      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType, parameterSize);
      Add(param);

      return param;
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="parameterType">The data type</param>
    /// <returns>A SQLiteParameter object</returns>
    public SQLiteParameter Add(string parameterName, DbType parameterType)
    {
      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType);
      Add(param);

      return param;
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="parameter">The parameter to add</param>
    /// <returns>A zero-based index of where the parameter is located in the array</returns>
    public int Add(SQLiteParameter parameter)
    {
      int n = -1;

      if (String.IsNullOrEmpty(parameter.ParameterName) == false)
      {
        n = IndexOf(parameter.ParameterName);
      }

      if (n == -1)
      {
        n = _parameterList.Count;
        _parameterList.Add((SQLiteParameter)parameter);
      }

      SetParameter(n, parameter);

      return n;
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="value">The parameter to add</param>
    /// <returns>A zero-based index of where the parameter is located in the array</returns>
#if !PLATFORM_COMPACTFRAMEWORK
    [EditorBrowsable(EditorBrowsableState.Never)]
#endif
    public override int Add(object value)
    {
      return Add((SQLiteParameter)value);
    }

    /// <summary>
    /// Adds a named/unnamed parameter and its value to the parameter collection.
    /// </summary>
    /// <param name="parameterName">Name of the parameter, or null to indicate an unnamed parameter</param>
    /// <param name="value">The initial value of the parameter</param>
    /// <returns>Returns the SQLiteParameter object created during the call.</returns>
    public SQLiteParameter AddWithValue(string parameterName, object value)
    {
      SQLiteParameter param = new SQLiteParameter(parameterName, value);
      Add(param);

      return param;
    }

    /// <summary>
    /// Adds an array of parameters to the collection
    /// </summary>
    /// <param name="values">The array of parameters to add</param>
    public void AddRange(SQLiteParameter[] values)
    {
      int x = values.Length;
      for (int n = 0; n < x; n++)
        Add(values[n]);
    }

    /// <summary>
    /// Adds an array of parameters to the collection
    /// </summary>
    /// <param name="values">The array of parameters to add</param>
    public override void AddRange(Array values)
    {
      int x = values.Length;
      for (int n = 0; n < x; n++)
        Add((SQLiteParameter)(values.GetValue(n)));
    }

    /// <summary>









    /// Clears the array and resets the collection


    /// </summary>
    public override void Clear()
    {
      _unboundFlag = true;
      _parameterList.Clear();
    }

    /// <summary>
    /// Determines if the named parameter exists in the collection
    /// </summary>
    /// <param name="parameterName">The name of the parameter to check</param>
    /// <returns>True if the parameter is in the collection</returns>
    public override bool Contains(string parameterName)
    {
      return (IndexOf(parameterName) != -1);
    }

    /// <summary>
    /// Determines if the parameter exists in the collection
    /// </summary>
    /// <param name="value">The SQLiteParameter to check</param>
    /// <returns>True if the parameter is in the collection</returns>
    public override bool Contains(object value)
    {
      return _parameterList.Contains((SQLiteParameter)value);
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    /// <param name="array"></param>
    /// <param name="index"></param>
    public override void CopyTo(Array array, int index)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// Returns a count of parameters in the collection
    /// </summary>
    public override int Count
    {
      get { return _parameterList.Count; }
    }

    /// <summary>
    /// Overloaded to specialize the return value of the default indexer
    /// </summary>
    /// <param name="parameterName">Name of the parameter to get/set</param>
    /// <returns>The specified named SQLite parameter</returns>
    public new SQLiteParameter this[string parameterName]
    {
      get
      {
        return (SQLiteParameter)GetParameter(parameterName);
      }
      set
      {
        SetParameter(parameterName, value);
      }
    }

    /// <summary>
    /// Overloaded to specialize the return value of the default indexer
    /// </summary>
    /// <param name="index">The index of the parameter to get/set</param>
    /// <returns>The specified SQLite parameter</returns>
    public new SQLiteParameter this[int index]
    {
      get
      {
        return (SQLiteParameter)GetParameter(index);
      }
      set
      {
        SetParameter(index, value);
      }
    }
    /// <summary>
    /// Retrieve a parameter by name from the collection
    /// </summary>
    /// <param name="parameterName">The name of the parameter to fetch</param>
    /// <returns>A DbParameter object</returns>
    protected override DbParameter GetParameter(string parameterName)
    {
      return GetParameter(IndexOf(parameterName));
    }


    /// <summary>
    /// Retrieves a parameter by its index in the collection
    /// </summary>
    /// <param name="index">The index of the parameter to retrieve</param>
    /// <returns>A DbParameter object</returns>
    protected override DbParameter GetParameter(int index)
    {
      return _parameterList[index];
    }

    /// <summary>
    /// Returns the index of a parameter given its name
    /// </summary>
    /// <param name="parameterName">The name of the parameter to find</param>
    /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>
    public override int IndexOf(string parameterName)
    {
      int x = _parameterList.Count;
      for (int n = 0; n < x; n++)
      {
        if (String.Compare(parameterName, _parameterList[n].ParameterName, StringComparison.OrdinalIgnoreCase) == 0)
          return n;
      }
      return -1;
    }

    /// <summary>
    /// Returns the index of a parameter
    /// </summary>
    /// <param name="value">The parameter to find</param>
    /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>
    public override int IndexOf(object value)
    {
      return _parameterList.IndexOf((SQLiteParameter)value);
    }

    /// <summary>
    /// Inserts a parameter into the array at the specified location
    /// </summary>
    /// <param name="index">The zero-based index to insert the parameter at</param>
    /// <param name="value">The parameter to insert</param>
    public override void Insert(int index, object value)
    {
      _unboundFlag = true;
      _parameterList.Insert(index, (SQLiteParameter)value);
    }

    /// <summary>
    /// Removes a parameter from the collection
    /// </summary>
    /// <param name="value">The parameter to remove</param>
    public override void Remove(object value)
    {
      _unboundFlag = true;
      _parameterList.Remove((SQLiteParameter)value);
    }

    /// <summary>
    /// Removes a parameter from the collection given its name
    /// </summary>
    /// <param name="parameterName">The name of the parameter to remove</param>
    public override void RemoveAt(string parameterName)
    {
      RemoveAt(IndexOf(parameterName));
    }

    /// <summary>
    /// Removes a parameter from the collection given its index
    /// </summary>
    /// <param name="index">The zero-based parameter index to remove</param>
    public override void RemoveAt(int index)
    {
      _unboundFlag = true;
      _parameterList.RemoveAt(index);
    }


    /// <summary>
    /// Re-assign the named parameter to a new parameter object
    /// </summary>
    /// <param name="parameterName">The name of the parameter to replace</param>
    /// <param name="value">The new parameter</param>
    protected override void SetParameter(string parameterName, DbParameter value)
    {
      SetParameter(IndexOf(parameterName), value);
    }


    /// <summary>
    /// Re-assign a parameter at the specified index
    /// </summary>
    /// <param name="index">The zero-based index of the parameter to replace</param>
    /// <param name="value">The new parameter</param>
    protected override void SetParameter(int index, DbParameter value)
    {
      _unboundFlag = true;
      _parameterList[index] = (SQLiteParameter)value;
    }

    /// <summary>
    /// Un-binds all parameters from their statements
    /// </summary>
    internal void Unbind()
    {
      _unboundFlag = true;
    }

    /// <summary>
    /// This function attempts to map all parameters in the collection to all statements in a Command.
    /// Since named parameters may span multiple statements, this function makes sure all statements are bound
    /// to the same named parameter.  Unnamed parameters are bound in sequence.
    /// </summary>
    internal void MapParameters(SQLiteStatement activeStatement)
    {
      if (_unboundFlag == false || _parameterList.Count == 0 || _command._statementList == null) return;

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

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

        int x;
        bool isMapped = false;

        if (activeStatement == null)
          x = _command._statementList.Count;
        else
          x = 1;

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

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

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













<
<
<
<
<
<
<




<
<
<


<
<
<

<
<
<

<
<
<


<
<
<
<








|







|







|







|







|

|






|

|
|
|
|
|
|

|






|

|
|
|
|
|

|






|

|
|
|
|

|






|

|
|
|



|

|





|


|





|

|
|
<
<
<






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

|


<
|




|

|


<
|




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








|

|
|
|

|



|

|
|






|









|






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

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

|
|




>


|

|
|






|

|
|


<
|

|
<





|

|
|






|

|
|







|

|







|

|


|



|

|






>

|

|
|




>


|

|
|






<
<
<










|

|




<




<



|



<
<
<
<
<
<
<
<
<
|

<
|


|
<

<

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



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

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;








  /// <summary>
  /// SQLite implementation of DbParameterCollection.
  /// </summary>



  public sealed class SQLiteParameterCollection : DbParameterCollection
  {



    private SQLiteCommand         _command;



    private List<SQLiteParameter> _parameterList;



    private bool                  _unboundFlag;





    internal SQLiteParameterCollection(SQLiteCommand cmd)
    {
      _command = cmd;
      _parameterList = new List<SQLiteParameter>();
      _unboundFlag = true;
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsSynchronized
    {
      get { return true; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsFixedSize
    {
      get { return false; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsReadOnly
    {
      get { return false; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override object SyncRoot
    {
      get { return null; }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override System.Collections.IEnumerator GetEnumerator()
    {
      return _parameterList.GetEnumerator();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="paramName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    /// <returns></returns>
    public SQLiteParameter Add(string paramName, DbType dbType, int nSize, string sourceColumn)
    {
      SQLiteParameter param = new SQLiteParameter(paramName, dbType, nSize, sourceColumn);
      Add(param);

      return param;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="paramName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <returns></returns>
    public SQLiteParameter Add(string paramName, DbType dbType, int nSize)
    {
      SQLiteParameter param = new SQLiteParameter(paramName, dbType, nSize);
      Add(param);

      return param;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="paramName"></param>
    /// <param name="dbType"></param>
    /// <returns></returns>
    public SQLiteParameter Add(string paramName, DbType dbType)
    {
      SQLiteParameter param = new SQLiteParameter(paramName, dbType);
      Add(param);

      return param;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    public int Add(SQLiteParameter p)
    {
      int n = -1;

      if (p.ParameterName != null)
      {
        n = IndexOf(p.ParameterName);
      }

      if (n == -1)
      {
        n = _parameterList.Count;
        _parameterList.Add(p);
      }

      SetParameter(n, p);

      return n;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>



    public override int Add(object value)
    {
      return Add((SQLiteParameter)value);
    }

    /// <summary>

    /// 













    /// </summary>
    /// <param name="values"></param>
    public void AddRange(SQLiteParameter[] values)
    {

      for (int n = 0; n < values.Length; n++)
        Add(values[n]);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="values"></param>
    public override void AddRange(Array values)
    {

      for (int n = 0; n < values.Length; n++)
        Add((SQLiteParameter)(values.GetValue(n)));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <returns></returns>
    [Obsolete]
    protected override int CheckName(string parameterName)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// 
    /// </summary>
    public override void Clear()
    {
      _unboundFlag = true;
      _parameterList.Clear();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool Contains(string value)
    {
      return (IndexOf(value) != -1);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool Contains(object value)
    {
      return _parameterList.Contains((SQLiteParameter)value);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="array"></param>
    /// <param name="index"></param>
    public override void CopyTo(Array array, int index)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// 
    /// </summary>
    public override int Count
    {
      get { return _parameterList.Count; }
    }

















#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>

    /// 















    /// </summary>
    /// <param name="parameterName"></param>
    /// <returns></returns>
    protected override DbParameter GetParameter(string parameterName)
    {
      return GetParameter(IndexOf(parameterName));
    }
#endif

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    protected override DbParameter GetParameter(int index)
    {
      return _parameterList[index];
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <returns></returns>
    public override int IndexOf(string parameterName)
    {

      for (int n = 0; n < _parameterList.Count; n++)
      {
        if (String.Compare(parameterName, _parameterList[n].ParameterName, true) == 0) return n;

      }
      return -1;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public override int IndexOf(object value)
    {
      return _parameterList.IndexOf((SQLiteParameter)value);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    /// <param name="value"></param>
    public override void Insert(int index, object value)
    {
      _unboundFlag = true;
      _parameterList.Insert(index, (SQLiteParameter)value);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    public override void Remove(object value)
    {
      _unboundFlag = true;
      _parameterList.Remove((SQLiteParameter)value);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    public override void RemoveAt(string parameterName)
    {
      Remove(IndexOf(parameterName));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    public override void RemoveAt(int index)
    {
      _unboundFlag = true;
      _parameterList.RemoveAt(index);
    }

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="value"></param>
    protected override void SetParameter(string parameterName, DbParameter value)
    {
      SetParameter(IndexOf(parameterName), value);
    }
#endif

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    /// <param name="value"></param>
    protected override void SetParameter(int index, DbParameter value)
    {
      _unboundFlag = true;
      _parameterList[index] = (SQLiteParameter)value;
    }




    internal void Unbind()
    {
      _unboundFlag = true;
    }

    /// <summary>
    /// This function attempts to map all parameters in the collection to all statements in a Command.
    /// Since named parameters may span multiple statements, this function makes sure all statements are bound
    /// to the same named parameter.  Unnamed parameters are bound in sequence.
    /// </summary>
    internal void MapParameters()
    {
      if (_unboundFlag == false || _parameterList.Count == 0) return;

      int nUnnamed = 0;
      string s;
      int n;

      SQLiteStatement stmt;

      foreach(SQLiteParameter p in _parameterList)
      {

        s = p.ParameterName;
        if (s == null)
        {
          s = String.Format(";{0}", nUnnamed);
          nUnnamed++;
        }










        for (n = 0; n < _command._statementList.Length; n++)
        {

          stmt = _command._statementList[n];
          if (stmt._paramNames != null)
          {
            stmt.MapParameter(s, p);

          }

        }
      }



















      _unboundFlag = false;
    }
  }
}
Changes to System.Data.SQLite/SQLiteStatement.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

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

  /// <summary>
  /// Represents a single SQL statement in SQLite.
  /// </summary>
  internal sealed class SQLiteStatement : IDisposable
  {
    /// <summary>
    /// The underlying SQLite object this statement is bound to
    /// </summary>
    internal SQLiteBase        _sql;
    /// <summary>
    /// The command text of this SQL statement
    /// </summary>
    internal string            _sqlStatement;
    /// <summary>
    /// The actual statement pointer
    /// </summary>
    internal SQLiteStatementHandle  _sqlite_stmt;
    /// <summary>
    /// An index from which unnamed parameters begin
    /// </summary>
    internal int               _unnamedParameters;
    /// <summary>
    /// Names of the parameters as SQLite understands them to be
    /// </summary>
    internal string[]          _paramNames;
    /// <summary>
    /// Parameters for this statement
    /// </summary>
    internal SQLiteParameter[] _paramValues;
    /// <summary>
    /// Command this statement belongs to (if any)
    /// </summary>
    internal SQLiteCommand     _command;

    private string[] _types;


    /// <summary>
    /// Initializes the statement and attempts to get all information about parameters in the statement
    /// </summary>
    /// <param name="sqlbase">The base SQLite object</param>
    /// <param name="stmt">The statement</param>
    /// <param name="strCommand">The command text for this statement</param>
    /// <param name="previous">The previous command in a multi-statement command</param>
    internal SQLiteStatement(SQLiteBase sqlbase, SQLiteStatementHandle stmt, string strCommand, SQLiteStatement previous)
    {

      _sql     = sqlbase;
      _sqlite_stmt = stmt;
      _sqlStatement  = strCommand;

      // Determine parameters for this statement (if any) and prepare space for them.
      int nCmdStart = 0;
      int n = _sql.Bind_ParamCount(this);
      int x;
      string s;

      if (n > 0)
      {
        if (previous != null)
          nCmdStart = previous._unnamedParameters;

        _paramNames = new string[n];
        _paramValues = new SQLiteParameter[n];

        for (x = 0; x < n; x++)
        {
          s = _sql.Bind_ParamName(this, x + 1);
          if (String.IsNullOrEmpty(s))
          {
            s = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
            nCmdStart++;
            _unnamedParameters++;
          }
          _paramNames[x] = s;
          _paramValues[x] = null;
        }
      }
    }

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

    #region IDisposable Members
    /// <summary>
    /// Disposes and finalizes the statement
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteStatement).Name);
#endif
    }

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

    private void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                ////////////////////////////////////
                // dispose managed resources here...
                ////////////////////////////////////

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

                _paramNames = null;
                _paramValues = null;
                _sql = null;
                _sqlStatement = null;
            }

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

            disposed = true;
        }
    }
    #endregion

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

    #region Destructor
    ~SQLiteStatement()
    {
        Dispose(false);
    }
    #endregion

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

    /// <summary>
    /// Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to
    /// this statement, and if so, keeps a reference to the parameter so it can be bound later.
    /// </summary>
    /// <param name="s">The parameter name to map</param>
    /// <param name="p">The parameter to assign it</param>
    internal bool MapParameter(string s, SQLiteParameter p)
    {
      if (_paramNames == null) return false;
      
      int startAt = 0;
      if (s.Length > 0)
      {
        if (":$@;".IndexOf(s[0]) == -1)
          startAt = 1;
      }

      int x = _paramNames.Length;
      for (int n = 0; n < x; n++)
      {
        if (String.Compare(_paramNames[n], startAt, s, 0, Math.Max(_paramNames[n].Length - startAt, s.Length), StringComparison.OrdinalIgnoreCase) == 0)
        {
          _paramValues[n] = p;
          return true;
        }

      }
      return false;
    }

    /// <summary>
    ///  Bind all parameters, making sure the caller didn't miss any
    /// </summary>
    internal void BindParameters()
    {
      if (_paramNames == null) return;

      int x = _paramNames.Length;
      for (int n = 0; n < x; n++)
      {
        BindParameter(n + 1, _paramValues[n]);
      }
    }

    /// <summary>
    /// Attempts to convert an arbitrary object to the Boolean data type.
    /// Null object values are converted to false.  Throws a SQLiteException
    /// upon failure.
    /// </summary>
    /// <param name="obj">The object value to convert.</param>
    /// <param name="provider">The format provider to use.</param>
    /// <returns>The converted boolean value.</returns>
    private static bool ToBoolean(object obj, IFormatProvider provider)
    {
        if (obj == null)
            return false;

        TypeCode typeCode = Type.GetTypeCode(obj.GetType());

        switch (typeCode)
        {
            case TypeCode.Empty:
            case TypeCode.DBNull:
                return false;
            case TypeCode.Boolean:
                return (bool)obj;
            case TypeCode.Char:
                return ((char)obj) != (char)0 ? true : false;
            case TypeCode.SByte:
                return ((sbyte)obj) != (sbyte)0 ? true : false;
            case TypeCode.Byte:
                return ((byte)obj) != (byte)0 ? true : false;
            case TypeCode.Int16:
                return ((short)obj) != (short)0 ? true : false;
            case TypeCode.UInt16:
                return ((ushort)obj) != (ushort)0 ? true : false;
            case TypeCode.Int32:
                return ((int)obj) != (int)0 ? true : false;
            case TypeCode.UInt32:
                return ((uint)obj) != (uint)0 ? true : false;
            case TypeCode.Int64:
                return ((long)obj) != (long)0 ? true : false;
            case TypeCode.UInt64:
                return ((ulong)obj) != (ulong)0 ? true : false;
            case TypeCode.Single:
                return ((float)obj) != (float)0.0 ? true : false;
            case TypeCode.Double:
                return ((double)obj) != (double)0.0 ? true : false;
            case TypeCode.Decimal:
                return ((decimal)obj) != Decimal.Zero ? true : false;
            case TypeCode.String:
                return Convert.ToBoolean(obj, provider);
            default:
                throw new SQLiteException((int)SQLiteErrorCode.Error,
                    String.Format("Cannot convert type {0} to boolean",
                    typeCode));
        }
    }

    /// <summary>
    /// Perform the bind operation for an individual parameter
    /// </summary>
    /// <param name="index">The index of the parameter to bind</param>
    /// <param name="param">The parameter we're binding</param>
    private void BindParameter(int index, SQLiteParameter param)
    {
      if (param == null)
        throw new SQLiteException((int)SQLiteErrorCode.Error, "Insufficient parameters supplied to the command");

      object obj = param.Value;
      DbType objType = param.DbType;

      if (Convert.IsDBNull(obj) || obj == null)
      {
        _sql.Bind_Null(this, index);
        return;
      }

      if (objType == DbType.Object)
        objType = SQLiteConvert.TypeToDbType(obj.GetType());

      switch (objType)
      {
        case DbType.Date:
        case DbType.Time:
        case DbType.DateTime:
          //
          // NOTE: The old method (commented below) does not honor the selected date format
          //       for the connection.
          // _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture));
          _sql.Bind_DateTime(this, index, (obj is string) ?
              _sql.ToDateTime((string)obj) : Convert.ToDateTime(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Boolean:
          _sql.Bind_Int32(this, index, ToBoolean(obj, CultureInfo.CurrentCulture) ? 1 : 0);
          break;
        case DbType.SByte:
          _sql.Bind_Int32(this, index, Convert.ToSByte(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Int16:
          _sql.Bind_Int32(this, index, Convert.ToInt16(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Int32:
          _sql.Bind_Int32(this, index, Convert.ToInt32(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Int64:
          _sql.Bind_Int64(this, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Byte:
          _sql.Bind_UInt32(this, index, Convert.ToByte(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.UInt16:
          _sql.Bind_UInt32(this, index, Convert.ToUInt16(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.UInt32:
          _sql.Bind_UInt32(this, index, Convert.ToUInt32(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.UInt64:
          _sql.Bind_UInt64(this, index, Convert.ToUInt64(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Single:
        case DbType.Double:
        case DbType.Currency:
        //case DbType.Decimal: // Dont store decimal as double ... loses precision
          _sql.Bind_Double(this, index, Convert.ToDouble(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Binary:
          _sql.Bind_Blob(this, index, (byte[])obj);
          break;
        case DbType.Guid:
          if (_command.Connection._binaryGuid == true)
            _sql.Bind_Blob(this, index, ((Guid)obj).ToByteArray());
          else
            _sql.Bind_Text(this, index, obj.ToString());

          break;
        case DbType.Decimal: // Dont store decimal as double ... loses precision
          _sql.Bind_Text(this, index, Convert.ToDecimal(obj, CultureInfo.CurrentCulture).ToString(CultureInfo.InvariantCulture));
          break;
        default:
          _sql.Bind_Text(this, index, obj.ToString());
          break;
      }
    }

    internal string[] TypeDefinitions
    {
      get { return _types; }
    }

    internal void SetTypes(string typedefs)
    {
      int pos = typedefs.IndexOf("TYPES", 0, StringComparison.OrdinalIgnoreCase);
      if (pos == -1) throw new ArgumentOutOfRangeException();

      string[] types = typedefs.Substring(pos + 6).Replace(" ", "").Replace(";", "").Replace("\"", "").Replace("[", "").Replace("]", "").Replace("`","").Split(',', '\r', '\n', '\t');

      int n;
      for (n = 0; n < types.Length; n++)
      {
        if (String.IsNullOrEmpty(types[n]) == true)
          types[n] = null;
      }
      _types = types;
    }
  }
}










|






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

<
<
<

<
<
<
<

<
>
|
<
<
<
|
|
<
<
<
|
>





<






<
<
<





|
|

|

<







<
|
<
<
<
<
<

<
<
<
|

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

<
<
<
<
<
<
<
|
<
<
|
<
<
|
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
|
>
|
|
|
<















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






<
<
<

<







<
<
<
|




<
<
<
<
|
<

|
<
<
|
|

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




|
|




<
<
<
<
<
<
<
<
<
<





|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
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


















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

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;

  /// <summary>
  /// Represents a single SQL statement in SQLite.
  /// </summary>
  internal sealed class SQLiteStatement : IDisposable
  {



    internal SQLiteBase                          _sql;



    internal string                              _sqlStatement;



    internal int                                 _sqlite_stmt;



    internal int                                 _unnamedParameterStart;



    internal string[]          _paramNames;



    internal SQLiteParameter[] _paramValues;






    internal SQLiteStatement(SQLiteBase sqlbase, int stmt, string strCommand, ref int nCmdStart)
    {



      _paramNames = null;
      _paramValues = null;




      _unnamedParameterStart   = nCmdStart;
      _sql     = sqlbase;
      _sqlite_stmt = stmt;
      _sqlStatement  = strCommand;

      // Determine parameters for this statement (if any) and prepare space for them.

      int n = _sql.Bind_ParamCount(this);
      int x;
      string s;

      if (n > 0)
      {



        _paramNames = new string[n];
        _paramValues = new SQLiteParameter[n];

        for (x = 0; x < n; x++)
        {
          s = _sql.Bind_ParamName(this, x);
          if (s == null || s == "")
          {
            s = String.Format(";{0}", nCmdStart);
            nCmdStart++;

          }
          _paramNames[x] = s;
          _paramValues[x] = null;
        }
      }
    }


    internal void MapParameter(string s, SQLiteParameter p)





    {



      if (_paramNames == null) return;


      for (int n = 0; n < _paramNames.Length; n++)



      {

        if (String.Compare(_paramNames[n], s, true) == 0)



        {

          _paramValues[n] = p;









          break;




        }
      }




    }












    #region IDisposable Members


    public void Dispose()


    {

      _sql.Finalize(this);







      









      _paramNames = null;




      _paramValues = null;


      GC.SuppressFinalize(this);
    }
    #endregion
    

    /// <summary>
    ///  Bind all parameters, making sure the caller didn't miss any
    /// </summary>
    internal void BindParameters()
    {
      if (_paramNames == null) return;

      int x = _paramNames.Length;
      for (int n = 0; n < x; n++)
      {
        BindParameter(n + 1, _paramValues[n]);
      }
    }

    /// <summary>























































    /// Perform the bind operation for an individual parameter
    /// </summary>
    /// <param name="index">The index of the parameter to bind</param>
    /// <param name="param">The parameter we're binding</param>
    private void BindParameter(int index, SQLiteParameter param)
    {



      object obj = param.Value;


      if (Convert.IsDBNull(obj) || obj == null)
      {
        _sql.Bind_Null(this, index);
        return;
      }




      switch (param.DbType)
      {
        case DbType.Date:
        case DbType.Time:
        case DbType.DateTime:




            _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj));

          break;
        case DbType.Int64:


        case DbType.UInt64:
          _sql.Bind_Int64(this, index, Convert.ToInt64(obj));
          break;
        case DbType.Boolean:


        case DbType.Int16:


        case DbType.Int32:


        case DbType.UInt16:


        case DbType.UInt32:


        case DbType.SByte:


        case DbType.Byte:
            _sql.Bind_Int32(this, index, Convert.ToInt32(obj));
          break;
        case DbType.Single:
        case DbType.Double:
        case DbType.Currency:
        case DbType.Decimal:
          _sql.Bind_Double(this, index, Convert.ToDouble(obj));
          break;
        case DbType.Binary:
          _sql.Bind_Blob(this, index, (byte[])obj);
          break;










        default:
          _sql.Bind_Text(this, index, obj.ToString());
          break;
      }
    }
  }



}


















Changes to System.Data.SQLite/SQLiteTransaction.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Threading;

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

    /// <summary>
    /// Constructs the transaction object, binding it to the supplied connection
    /// </summary>
    /// <param name="connection">The connection to open a transaction on</param>
    /// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>
    internal SQLiteTransaction(SQLiteConnection connection, bool deferredLock)
    {
      _cnn = connection;
      _version = _cnn._version;

      _level = (deferredLock == true) ? IsolationLevel.ReadCommitted : IsolationLevel.Serializable;

      if (_cnn._transactionLevel++ == 0)
      {
        try
        {
          using (SQLiteCommand cmd = _cnn.CreateCommand())
          {
            if (!deferredLock)
              cmd.CommandText = "BEGIN IMMEDIATE";
            else
              cmd.CommandText = "BEGIN";

            cmd.ExecuteNonQuery();
          }
        }
        catch (SQLiteException)
        {
          _cnn._transactionLevel--;
          _cnn = null;
          throw;
        }
      }
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
#if THROW_ON_DISPOSED
        if (disposed)
            throw new ObjectDisposedException(typeof(SQLiteTransaction).Name);
#endif
    }

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

    /// <summary>
    /// Disposes the transaction.  If it is currently active, any changes are rolled back.
    /// </summary>
    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    if (IsValid(false))
                    {
                        IssueRollback();

                    }
                }

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

                disposed = true;
            }
        }
        finally
        {
            base.Dispose(disposing);

        }
    }
    #endregion

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

    /// <summary>
    /// Commits the current transaction.
    /// </summary>
    public override void Commit()
    {
      CheckDisposed();
      IsValid(true);

      if (_cnn._transactionLevel - 1 == 0)
      {
        using (SQLiteCommand cmd = _cnn.CreateCommand())

        {
          cmd.CommandText = "COMMIT";
          cmd.ExecuteNonQuery();
        }




      }
      _cnn._transactionLevel--;
      _cnn = null;

    }

    /// <summary>
    /// Returns the underlying connection to which this transaction applies.
    /// </summary>
    public new SQLiteConnection Connection
    {
      get { CheckDisposed(); return _cnn; }
    }

    /// <summary>
    /// Forwards to the local Connection property
    /// </summary>
    protected override DbConnection DbConnection
    {
      get { return Connection; }


    }

    /// <summary>
    /// Gets the isolation level of the transaction.  SQLite only supports Serializable transactions.
    /// </summary>
    public override IsolationLevel IsolationLevel
    {
      get { CheckDisposed(); return _level; }
    }

    /// <summary>
    /// Rolls back the active transaction.
    /// </summary>
    public override void Rollback()
    {
      CheckDisposed();
      IsValid(true);
      IssueRollback();
    }

    internal void IssueRollback()
    {
      SQLiteConnection cnn = Interlocked.Exchange(ref _cnn, null);

      if (cnn != null)
      {
        using (SQLiteCommand cmd = cnn.CreateCommand())
        {
          cmd.CommandText = "ROLLBACK";
          cmd.ExecuteNonQuery();
        }
        cnn._transactionLevel = 0;
      }
    }

    internal bool IsValid(bool throwError)
    {

      if (_cnn == null)
      {
        if (throwError == true) throw new ArgumentNullException("No connection associated with this transaction");
        else return false;
      }

      if (_cnn._version != _version)
      {
        if (throwError == true) throw new SQLiteException((int)SQLiteErrorCode.Misuse, "The connection was closed and re-opened, changes were already rolled back");
        else return false;
      }
      if (_cnn.State != ConnectionState.Open)
      {
        if (throwError == true) throw new SQLiteException((int)SQLiteErrorCode.Misuse, "Connection was closed");
        else return false;
      }

      if (_cnn._transactionLevel == 0 || _cnn._sql.AutoCommit == true)
      {
        _cnn._transactionLevel = 0; // Make sure the transaction level is reset before returning
        if (throwError == true) throw new SQLiteException((int)SQLiteErrorCode.Misuse, "No transaction is active on this connection");
        else return false;
      }

      return true;
    }
  }
}












<






<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
|
<
<
<
>
|
<
|
<
<
<
|
<
<
<
<
<
|
>
|

<
<
<






<
<
|
|
|
<
>
|
<
|
|
>
>
>
>

<
<
>





|

|



|

|

|
>
>



|



|







<
<
|
<
|
<
|
<
|
<

<
<
|
<
|
<
<
<
|
<
|
>
|
<
<
<

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



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

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


  /// <summary>
  /// SQLite implementation of DbTransaction.
  /// </summary>
  public sealed class SQLiteTransaction : DbTransaction
  {



    private SQLiteConnection _cnn;

















































    internal SQLiteTransaction(SQLiteConnection cnn)

    {





      try
      {







        cnn._sql.Execute("BEGIN");



        _cnn = cnn;
      }

      catch (SQLiteException e)



      {





        BaseDispose();
        throw (e);
      }
    }




    /// <summary>
    /// Commits the current transaction.
    /// </summary>
    public override void Commit()
    {


      if (_cnn == null)
        throw new ArgumentNullException();


      try
      {

        _cnn._sql.Execute("COMMIT");
      }
      catch (SQLiteException e)
      {
        BaseDispose();
        throw (e);
      }


      BaseDispose();
    }

    /// <summary>
    /// Returns the underlying connection to which this transaction applies.
    /// </summary>
    protected override DbConnection DbConnection
    {
      get { return _cnn; }
    }

    /// <summary>
    /// Disposes the transaction.  If it is currently active, any changes are rolled back.
    /// </summary>
    public override void Dispose()
    {
      if (_cnn != null) 
        Rollback();
      GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Gets the isolation level of the transaction.  SQLite does not support isolation levels, so this always returns Unspecified.
    /// </summary>
    public override IsolationLevel IsolationLevel
    {
      get { return IsolationLevel.Unspecified; }
    }

    /// <summary>
    /// Rolls back the active transaction.
    /// </summary>
    public override void Rollback()
    {


      if (_cnn == null)

        throw new ArgumentNullException();



      try

      {


        _cnn._sql.Execute("ROLLBACK");

      }



      catch (SQLiteException e)

      {
        BaseDispose();
        throw (e);



      }
      BaseDispose();




    }





    private void BaseDispose()

    {
      _cnn._activeTransaction = null;



      _cnn = null;

    }
  }
}
Deleted System.Data.SQLite/SR.Designer.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
/********************************************************
 * 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!
 ********************************************************/

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace System.Data.SQLite {
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class SR {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal SR() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Data.SQLite.SR", typeof(SR).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; standalone=&quot;yes&quot;?&gt;
        ///&lt;DocumentElement&gt;
        ///  &lt;DataTypes&gt;
        ///    &lt;TypeName&gt;smallint&lt;/TypeName&gt;
        ///    &lt;ProviderDbType&gt;10&lt;/ProviderDbType&gt;
        ///    &lt;ColumnSize&gt;5&lt;/ColumnSize&gt;
        ///    &lt;DataType&gt;System.Int16&lt;/DataType&gt;
        ///    &lt;CreateFormat&gt;smallint&lt;/CreateFormat&gt;
        ///    &lt;IsAutoIncrementable&gt;false&lt;/IsAutoIncrementable&gt;
        ///    &lt;IsCaseSensitive&gt;false&lt;/IsCaseSensitive&gt;
        ///    &lt;IsFixedLength&gt;true&lt;/IsFixedLength&gt;
        ///    &lt;IsFixedPrecisionScale&gt;true&lt;/IsFixedPrecisionScale&gt;
        ///    &lt;IsLong&gt;false&lt;/IsLong&gt;
        ///    &lt;IsNullable&gt;true&lt;/ [rest of string was truncated]&quot;;.
        /// </summary>
        internal static string DataTypes {
            get {
                return ResourceManager.GetString("DataTypes", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE.
        /// </summary>
        internal static string Keywords {
            get {
                return ResourceManager.GetString("Keywords", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
        ///&lt;DocumentElement&gt;
        ///  &lt;MetaDataCollections&gt;
        ///    &lt;CollectionName&gt;MetaDataCollections&lt;/CollectionName&gt;
        ///    &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;
        ///    &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;
        ///  &lt;/MetaDataCollections&gt;
        ///  &lt;MetaDataCollections&gt;
        ///    &lt;CollectionName&gt;DataSourceInformation&lt;/CollectionName&gt;
        ///    &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;
        ///    &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;
        ///  &lt;/MetaDataCollections&gt;
        ///  &lt;MetaDataC [rest of string was truncated]&quot;;.
        /// </summary>
        internal static string MetaDataCollections {
            get {
                return ResourceManager.GetString("MetaDataCollections", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































Deleted System.Data.SQLite/SR.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <data name="DataTypes" type="System.Resources.ResXFileRef, System.Windows.Forms">
    <value>DataTypes.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
  </data>
  <data name="Keywords" xml:space="preserve">
    <value>ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE</value>
  </data>
  <data name="MetaDataCollections" type="System.Resources.ResXFileRef, System.Windows.Forms">
    <value>MetaDataCollections.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































Deleted System.Data.SQLite/System.Data.SQLite.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * System.Data.SQLite.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AC139952-261A-4463-B6FA-AEBC25283A66}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>System.Data.SQLite</RootNamespace>
    <AssemblyName>System.Data.SQLite</AssemblyName>
    <OldToolsVersion>2.0</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)System.Data.SQLite.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.References.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Files.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































Deleted System.Data.SQLite/System.Data.SQLite.2010.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * System.Data.SQLite.2010.csproj -
 *
 * 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>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.30319</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AC139952-261A-4463-B6FA-AEBC25283A66}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>System.Data.SQLite</RootNamespace>
    <AssemblyName>System.Data.SQLite</AssemblyName>
    <OldToolsVersion>3.5</OldToolsVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <ConfigurationYear>2010</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)System.Data.SQLite.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.References.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Files.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































Deleted System.Data.SQLite/System.Data.SQLite.CF.snk.

cannot compute difference between binary files

Deleted System.Data.SQLite/System.Data.SQLite.Compact.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * System.Data.SQLite.Compact.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AC139951-261A-4463-B6FA-AEBC25283A66}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>System.Data.SQLite</RootNamespace>
    <AssemblyName>System.Data.SQLite</AssemblyName>
    <ProjectTypeGuids>{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <PlatformFamilyName>WindowsCE</PlatformFamilyName>
    <PlatformID>E2BECB1F-8C8C-41ba-B736-9BE7D946A398</PlatformID>
    <OSVersion>5.0</OSVersion>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <OldToolsVersion>2.0</OldToolsVersion>
    <NativePlatformName>Windows CE</NativePlatformName>
    <FormFactorID></FormFactorID>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <UseInteropDll>false</UseInteropDll>
    <UseSqliteStandard>false</UseSqliteStandard>
    <IsCompactFramework>true</IsCompactFramework>
    <ConfigurationYear>2008</ConfigurationYear>
    <ConfigurationSuffix>Compact</ConfigurationSuffix>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)System.Data.SQLite.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE;$(PlatformFamilyName)</DefineConstants>
    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <ErrorReport>prompt</ErrorReport>
    <GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE;$(PlatformFamilyName)</DefineConstants>
    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <ErrorReport>prompt</ErrorReport>
    <GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
  </PropertyGroup>
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.References.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Files.targets" />
  <Import Condition="'$(TargetFrameworkVersion)' == 'v1.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.v1.targets" />
  <Import Condition="'$(TargetFrameworkVersion)' == 'v2.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
  <Import Condition="'$(TargetFrameworkVersion)' == 'v3.5'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
  <ProjectExtensions>
    <VisualStudio>
      <FlavorProperties GUID="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}">
        <HostingProcess disable="1" />
      </FlavorProperties>
    </VisualStudio>
  </ProjectExtensions>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































Deleted System.Data.SQLite/System.Data.SQLite.Files.targets.
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
<!--
 *
 * System.Data.SQLite.Files.targets -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!--
  ******************************************************************************
  **                            Core Files (Common)                           **
  ******************************************************************************
  -->

  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="SQLite3.cs" />
    <Compile Include="SQLite3_UTF16.cs" />
    <Compile Include="SQLiteBase.cs" />
    <Compile Include="SQLiteCommand.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteCommandBuilder.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteConnection.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteConnectionPool.cs" />
    <Compile Include="SQLiteConnectionStringBuilder.cs" />
    <Compile Include="SQLiteConvert.cs" />
    <Compile Include="SQLiteDataAdapter.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteDataReader.cs" />
    <Compile Include="SQLiteException.cs" />
    <Compile Include="SQLiteFactory.cs" />
    <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="SQLiteStatement.cs" />
    <Compile Include="SQLiteTransaction.cs" />
    <Compile Include="SR.Designer.cs">
      <DependentUpon>SR.resx</DependentUpon>
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
    </Compile>
    <Compile Include="UnsafeNativeMethods.cs" />
    <EmbeddedResource Include="SR.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>SR.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>

  <!--
  ******************************************************************************
  **                        Core Files (Full Framework)                       **
  ******************************************************************************
  -->

  <ItemGroup Condition="'$(IsCompactFramework)' == 'false'">
    <Compile Include="SQLiteEnlistment.cs" />
    <Compile Include="LINQ\SQLiteConnection_Linq.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="LINQ\SQLiteFactory_Linq.cs">
      <SubType>Code</SubType>
    </Compile>
    <EmbeddedResource Include="SQLiteCommand.bmp" />
    <EmbeddedResource Include="SQLiteConnection.bmp" />
    <EmbeddedResource Include="SQLiteDataAdapter.bmp" />
  </ItemGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































Deleted System.Data.SQLite/System.Data.SQLite.Module.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * System.Data.SQLite.Module.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AC139952-261A-4463-B6FA-AEBC25284A66}</ProjectGuid>
    <OutputType>Module</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>System.Data.SQLite</RootNamespace>
    <AssemblyName>System.Data.SQLite</AssemblyName>
    <OldToolsVersion>2.0</OldToolsVersion>
    <SignAssembly>false</SignAssembly>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
    <ConfigurationSuffix>Module</ConfigurationSuffix>
    <UseInteropDll>false</UseInteropDll>
    <UseSqliteStandard>false</UseSqliteStandard>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)System.Data.SQLite.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.References.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Files.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































Deleted System.Data.SQLite/System.Data.SQLite.Module.2010.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * System.Data.SQLite.Module.2010.csproj -
 *
 * 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>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.30319</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AC139952-261A-4463-B6FA-AEBC25284A66}</ProjectGuid>
    <OutputType>Module</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>System.Data.SQLite</RootNamespace>
    <AssemblyName>System.Data.SQLite</AssemblyName>
    <OldToolsVersion>3.5</OldToolsVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <SignAssembly>false</SignAssembly>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <ConfigurationYear>2010</ConfigurationYear>
    <ConfigurationSuffix>Module</ConfigurationSuffix>
    <UseInteropDll>false</UseInteropDll>
    <UseSqliteStandard>false</UseSqliteStandard>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
    <DocumentationFile>$(BinaryOutputPath)System.Data.SQLite.xml</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.References.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildProjectDirectory)\System.Data.SQLite.Files.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































Deleted System.Data.SQLite/System.Data.SQLite.Properties.targets.
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
<!--
 *
 * System.Data.SQLite.Properties.targets -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!--
      NOTE: Only use functionality available in the .NET Framework 2.0?  By
            default, this is disabled.  This must be enabled to successfully
            build the project using Visual Studio 2008 and/or the .NET
            Framework 2.0 (if necessary, it will typically be enabled from
            within the project file itself).
  -->
  <PropertyGroup Condition="'$(NetFx20)' != 'false' Or
                            '$(TargetFrameworkVersion)' == 'v2.0' Or
                            '$(TargetFrameworkVersion)' == 'v3.5'">
    <DefineConstants>$(DefineConstants);NET_20</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: For interaction with the native SQLite implementation, use the
            custom build interop DLL (i.e. "SQLite.Interop.DLL")?
  -->
  <PropertyGroup Condition="'$(UseInteropDll)' != 'false'">
    <DefineConstants>$(DefineConstants);USE_INTEROP_DLL</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: For interaction with the native SQLite implementation, use the
            standard DLL (i.e. "sqlite3.dll")?
  -->
  <PropertyGroup Condition="'$(UseSqliteStandard)' != 'false'">
    <DefineConstants>$(DefineConstants);SQLITE_STANDARD</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: Is the project being built to support the .NET Compact Framework?
  -->
  <PropertyGroup Condition="'$(IsCompactFramework)' != 'false'">
    <DefineConstants>$(DefineConstants);PLATFORM_COMPACTFRAMEWORK</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: Emit an AssemblyFlags attribute that includes the Retargetable
            flag from the AssemblyNameFlags enumeration?
  -->
  <PropertyGroup Condition="'$(IsRetargetable)' != 'false'">
    <DefineConstants>$(DefineConstants);RETARGETABLE</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: Throw an exception when somebody tries to access a disposed object?
  -->
  <PropertyGroup Condition="'$(ThrowOnDisposed)' != 'false'">
    <DefineConstants>$(DefineConstants);THROW_ON_DISPOSED</DefineConstants>
  </PropertyGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































Deleted System.Data.SQLite/System.Data.SQLite.References.targets.
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
<!--
 *
 * System.Data.SQLite.References.targets -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!--
  ******************************************************************************
  **                     Core References (Full Framework)                     **
  ******************************************************************************
  -->

  <ItemGroup Condition="'$(IsCompactFramework)' == 'false'">
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Transactions" />
    <Reference Include="System.Xml" />
  </ItemGroup>

  <!--
  ******************************************************************************
  **                    Core References (Compact Framework)                   **
  ******************************************************************************
  -->

  <ItemGroup Condition="'$(IsCompactFramework)' != 'false'">
    <Reference Include="mscorlib" />
    <Reference Include="System">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Data">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Xml">
      <Private>False</Private>
    </Reference>
  </ItemGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































Added System.Data.SQLite/System.Data.SQLite.csproj.




















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.41202</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AC139951-261A-4463-B6FA-AEBC25283A66}</ProjectGuid>
    <OutputType>Library</OutputType>
    <RootNamespace>System.Data.SQLite</RootNamespace>
    <AssemblyName>System.Data.SQLite</AssemblyName>
    <WarningLevel>4</WarningLevel>
    <SignAssembly>true</SignAssembly>
    <AssemblyOriginatorKeyFile>System.Data.SQLite.snk</AssemblyOriginatorKeyFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>.\bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <PlatformTarget>x86</PlatformTarget>
    <DocumentationFile>bin\Debug\System.Data.SQLite.XML</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>.\bin\Release\</OutputPath>
    <DefineConstants>
    </DefineConstants>
    <PlatformTarget>x86</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
    <NoStdLib>false</NoStdLib>
    <DocumentationFile>bin\Release\System.Data.SQLite.XML</DocumentationFile>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.XML" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <None Include="System.Data.SQLite.snk" />
    <Compile Include="SQLite3.cs" />
    <Compile Include="SQLite3_UTF16.cs" />
    <Compile Include="SQLiteBase.cs" />
    <Compile Include="SQLiteCommand.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteCommandBuilder.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteConnectionStringBuilder.cs">
    </Compile>
    <Compile Include="SQLiteConvert.cs" />
    <Compile Include="SQLiteFactory.cs" />
    <Compile Include="SQLiteFunction.cs" />
    <Compile Include="SQLiteFunctionAttribute.cs" />
    <Compile Include="SQLiteStatement.cs" />
    <Compile Include="SQLiteConnection.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteDataAdapter.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteDataReader.cs" />
    <Compile Include="SQLiteException.cs" />
    <Compile Include="SQLiteParameter.cs" />
    <Compile Include="SQLiteParameterCollection.cs" />
    <Compile Include="SQLiteTransaction.cs" />
    <Compile Include="UnsafeNativeMethods.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>
Added System.Data.SQLite/System.Data.SQLite.csproj.user.














>
>
>
>
>
>
>
1
2
3
4
5
6
7
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <LastOpenVersion>8.0.41202</LastOpenVersion>
    <ProjectView>ProjectFiles</ProjectView>
    <ProjectTrust>0</ProjectTrust>
  </PropertyGroup>
</Project>
Changes to System.Data.SQLite/System.Data.SQLite.snk.

cannot compute difference between binary files

Changes to System.Data.SQLite/UnsafeNativeMethods.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
#if DEBUG
  using System.Diagnostics;
#endif

#if !PLATFORM_COMPACTFRAMEWORK && !DEBUG
  using System.Security;
#endif

  using System.Runtime.InteropServices;

#if !PLATFORM_COMPACTFRAMEWORK && !DEBUG
  [SuppressUnmanagedCodeSecurity]
#endif
  internal static class UnsafeNativeMethods
  {
#if !SQLITE_STANDARD

#if !USE_INTEROP_DLL

#if !PLATFORM_COMPACTFRAMEWORK
    private const string SQLITE_DLL = "System.Data.SQLite.dll";
#else
    internal const string SQLITE_DLL = "SQLite.Interop.077.dll";
#endif // PLATFORM_COMPACTFRAMEWORK

#else
    private const string SQLITE_DLL = "SQLite.Interop.dll";
#endif // USE_INTEROP_DLL

#else
    private const string SQLITE_DLL = "sqlite3";
#endif

    // This section uses interop calls that also fetch text length to optimize conversion.  
    // When using the standard dll, we can replace these calls with normal sqlite calls and 
    // do unoptimized conversions instead afterwards
    #region interop added textlength calls

#if !SQLITE_STANDARD

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_bind_parameter_name_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_database_name_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_database_name16_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_decltype_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_decltype16_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_name_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_name16_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_origin_name_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_origin_name16_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_table_name_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_table_name16_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_text_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_text16_interop(IntPtr stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_errmsg_interop(IntPtr db, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_prepare_interop(IntPtr db, IntPtr pSql, int nBytes, out IntPtr stmt, out IntPtr ptrRemain, out int nRemain);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_table_column_metadata_interop(IntPtr db, byte[] dbName, byte[] tblName, byte[] colName, out IntPtr ptrDataType, out IntPtr ptrCollSeq, out int notNull, out int primaryKey, out int autoInc, out int dtLen, out int csLen);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_value_text_interop(IntPtr p, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_value_text16_interop(IntPtr p, out int len);

#endif
// !SQLITE_STANDARD

    #endregion

    // 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 int sqlite3_close_interop(IntPtr db);

    [DllImport(SQLITE_DLL)]
    internal static extern int 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)]
    internal static extern int sqlite3_finalize_interop(IntPtr stmt);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_open_interop(byte[] utf8Filename, int flags, out IntPtr db);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_open16_interop(byte[] utf8Filename, int flags, out IntPtr db);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_reset_interop(IntPtr stmt);

#endif
// !SQLITE_STANDARD

    #endregion

    // The standard api call equivalents of the above interop calls
    #region standard versions of interop functions

#if SQLITE_STANDARD

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_close(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_create_function(IntPtr db, byte[] strName, int nArgs, int nType, IntPtr pvUser, SQLiteCallback func, SQLiteCallback fstep, SQLiteFinalCallback ffinal);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_finalize(IntPtr stmt);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_open_v2(byte[] utf8Filename, out IntPtr db, int flags, IntPtr vfs);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
#else
    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
#endif
    internal static extern int sqlite3_open16(string fileName, out IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_reset(IntPtr stmt);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_bind_parameter_name(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_database_name(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_database_name16(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_decltype(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_decltype16(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_name(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_name16(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_origin_name(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_origin_name16(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_table_name(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_table_name16(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_text(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_text16(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_errmsg(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_prepare(IntPtr db, IntPtr pSql, int nBytes, out IntPtr stmt, out IntPtr ptrRemain);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_table_column_metadata(IntPtr db, byte[] dbName, byte[] tblName, byte[] colName, out IntPtr ptrDataType, out IntPtr ptrCollSeq, out int notNull, out int primaryKey, out int autoInc);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_value_text(IntPtr p);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_value_text16(IntPtr p);

#endif
// SQLITE_STANDARD

    #endregion

    // These functions are custom and have no equivalent standard library method.
    // All of them are "nice to haves" and not necessarily "need to haves".
    #region no equivalent standard method

#if !SQLITE_STANDARD

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_context_collseq(IntPtr context, out int type, out int enc, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_context_collcompare(IntPtr context, byte[] p1, int p1len, byte[] p2, int p2len);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_cursor_rowid(IntPtr stmt, int cursor, out long rowid);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_index_column_info_interop(IntPtr db, byte[] catalog, byte[] IndexName, byte[] ColumnName, out int sortOrder, out int onError, out IntPtr Collation, out int colllen);

    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_resetall_interop(IntPtr db);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_table_cursor(IntPtr stmt, int db, int tableRootPage);

#endif
// !SQLITE_STANDARD

    #endregion

    // Standard API calls global across versions.  There are a few instances of interop calls
    // scattered in here, but they are only active when PLATFORM_COMPACTFRAMEWORK is declared.
    #region standard sqlite api calls

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_libversion();

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_sourceid();

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_interrupt(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern long sqlite3_last_insert_rowid(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_changes(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern long sqlite3_memory_used();

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern long sqlite3_memory_highwater(int resetFlag);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_shutdown();

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_busy_timeout(IntPtr db, int ms);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_bind_blob(IntPtr stmt, int index, Byte[] value, int nSize, IntPtr nTransient);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern int sqlite3_bind_double(IntPtr stmt, int index, double value);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_bind_double_interop(IntPtr stmt, int index, ref double value);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_bind_int(IntPtr stmt, int index, int value);

    //
    // NOTE: This really just calls "sqlite3_bind_int"; however, it has the
    //       correct type signature for an unsigned (32-bit) integer.
    //
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, EntryPoint = "sqlite3_bind_int", CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL, EntryPoint = "sqlite3_bind_int")]
#endif
    internal static extern int sqlite3_bind_uint(IntPtr stmt, int index, uint value);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern int sqlite3_bind_int64(IntPtr stmt, int index, long value);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_bind_int64_interop(IntPtr stmt, int index, ref long value);
#endif

    //
    // NOTE: This really just calls "sqlite3_bind_int64"; however, it has the
    //       correct type signature for an unsigned long (64-bit) integer.
    //
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, EntryPoint = "sqlite3_bind_int64", CallingConvention = CallingConvention.Cdecl)]
    internal static extern int sqlite3_bind_uint64(IntPtr stmt, int index, ulong value);
#else
    [DllImport(SQLITE_DLL, EntryPoint = "sqlite3_bind_int64_interop")]
    internal static extern int sqlite3_bind_uint64_interop(IntPtr stmt, int index, ref ulong value);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_bind_null(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_bind_text(IntPtr stmt, int index, byte[] value, int nlen, IntPtr pvReserved);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_bind_parameter_count(IntPtr stmt);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_bind_parameter_index(IntPtr stmt, byte[] strName);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_column_count(IntPtr stmt);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_step(IntPtr stmt);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern double sqlite3_column_double(IntPtr stmt, int index);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_column_double_interop(IntPtr stmt, int index, out double value);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_column_int(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern long sqlite3_column_int64(IntPtr stmt, int index);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_column_int64_interop(IntPtr stmt, int index, out long value);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_column_blob(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_column_bytes(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern TypeAffinity sqlite3_column_type(IntPtr stmt, int index);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_create_collation(IntPtr db, byte[] strName, int nType, IntPtr pvUser, SQLiteCollation func);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_aggregate_count(IntPtr context);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_value_blob(IntPtr p);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_value_bytes(IntPtr p);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern double sqlite3_value_double(IntPtr p);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_value_double_interop(IntPtr p, out double value);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_value_int(IntPtr p);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern long sqlite3_value_int64(IntPtr p);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_value_int64_interop(IntPtr p, out Int64 value);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern TypeAffinity sqlite3_value_type(IntPtr p);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_result_blob(IntPtr context, byte[] value, int nSize, IntPtr pvReserved);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern void sqlite3_result_double(IntPtr context, double value);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_result_double_interop(IntPtr context, ref double value);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_result_error(IntPtr context, byte[] strErr, int nLen);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_result_int(IntPtr context, int value);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern void sqlite3_result_int64(IntPtr context, long value);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_result_int64_interop(IntPtr context, ref Int64 value);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_result_null(IntPtr context);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_result_text(IntPtr context, byte[] value, int nLen, IntPtr pvReserved);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_aggregate_context(IntPtr context, int nBytes);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
#else
    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
#endif
    internal static extern int sqlite3_bind_text16(IntPtr stmt, int index, string value, int nlen, IntPtr pvReserved);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
#else
    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
#endif
    internal static extern void sqlite3_result_error16(IntPtr context, string strName, int nLen);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
#else
    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
#endif
    internal static extern void sqlite3_result_text16(IntPtr context, string strName, int nLen, IntPtr pvReserved);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_key(IntPtr db, byte[] key, int keylen);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_rekey(IntPtr db, byte[] key, int keylen);

#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
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_commit_hook(IntPtr db, SQLiteCommitCallback func, IntPtr pvUser);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_trace(IntPtr db, SQLiteTraceCallback func, IntPtr pvUser);

    // Since sqlite3_config() takes a variable argument list, we have to overload declarations
    // for all possible calls.  For now, we are only exposing the SQLITE_CONFIG_LOG call.
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_config(int op, SQLiteLogCallback func, IntPtr pvUser);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_rollback_hook(IntPtr db, SQLiteRollbackCallback func, IntPtr pvUser);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [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 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 int 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_get_autocommit(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_extended_result_codes(IntPtr db, int onoff);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_errcode(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_extended_errcode(IntPtr db);

    // Since sqlite3_log() takes a variable argument list, we have to overload declarations
    // for all possible calls.  For now, we are only exposing a single string, and 
    // depend on the caller to format the string.
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_log(int iErrCode, byte[] zFormat);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_file_control(IntPtr db, byte[] zDbName, int op, IntPtr pArg);

    #endregion
  }

#if PLATFORM_COMPACTFRAMEWORK
  internal abstract class CriticalHandle : IDisposable
  {
    private bool _isClosed;
    protected IntPtr handle;
    
    protected CriticalHandle(IntPtr invalidHandleValue)
    {
      handle = invalidHandleValue;
      _isClosed = false;
    }

    ~CriticalHandle()
    {
      Dispose(false);
    }

    private void Cleanup()
    {
      if (!IsClosed)
      {
        this._isClosed = true;
        if (!IsInvalid)
        {
          ReleaseHandle();
          GC.SuppressFinalize(this);
        }
      }
    }

    public void Close()
    {
      Dispose(true);
    }

    public void Dispose()
    {
      Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
      Cleanup();
    }

    protected abstract bool ReleaseHandle();

    protected void SetHandle(IntPtr value)
    {
      handle = value;
    }

    public void SetHandleAsInvalid()
    {
      _isClosed = true;
      GC.SuppressFinalize(this);
    }

    public bool IsClosed
    {
      get { return _isClosed; }
    }

    public abstract bool IsInvalid
    {
      get;
    }

  }

#endif

  // Handles the unmanaged database pointer, and provides finalization support for it.
  internal class SQLiteConnectionHandle : CriticalHandle
  {
    public static implicit operator IntPtr(SQLiteConnectionHandle db)
    {
      return db.handle;
    }

    public static implicit operator SQLiteConnectionHandle(IntPtr db)
    {
      return new SQLiteConnectionHandle(db);
    }

    private SQLiteConnectionHandle(IntPtr db)
      : this()
    {
      SetHandle(db);
    }

    internal SQLiteConnectionHandle()
      : base(IntPtr.Zero)
    {
    }

    protected override bool ReleaseHandle()
    {
      try
      {
        SQLiteBase.CloseConnection(this);

#if DEBUG
        try
        {
          Trace.WriteLine(String.Format(
              "CloseConnection: {0}", handle));
        }
        catch
        {
        }
#endif

#if DEBUG
        return true;
#endif
      }
#if DEBUG
      catch (SQLiteException e)
#else
      catch (SQLiteException)
#endif
      {
#if DEBUG
        try
        {
          Trace.WriteLine(String.Format(
              "CloseConnection: {0}, exception: {1}",
              handle, e));
        }
        catch
        {
        }
#endif
      }
#if DEBUG
      return false;
#else
      return true;
#endif
    }

    public override bool IsInvalid
    {
      get { return (handle == IntPtr.Zero); }
    }
  }

  // Provides finalization support for unmanaged SQLite statements.
  internal class SQLiteStatementHandle : CriticalHandle
  {
    public static implicit operator IntPtr(SQLiteStatementHandle stmt)
    {
      return stmt.handle;
    }

    public static implicit operator SQLiteStatementHandle(IntPtr stmt)
    {
      return new SQLiteStatementHandle(stmt);
    }

    private SQLiteStatementHandle(IntPtr stmt)
      : this()

    {
      SetHandle(stmt);
    }

    internal SQLiteStatementHandle()
      : base(IntPtr.Zero)
    {
    }

    protected override bool ReleaseHandle()
    {
      try
      {
        SQLiteBase.FinalizeStatement(this);

#if DEBUG
        try
        {
          Trace.WriteLine(String.Format(
              "FinalizeStatement: {0}", handle));
        }
        catch
        {
        }
#endif

#if DEBUG
        return true;
#endif
      }
#if DEBUG
      catch (SQLiteException e)
#else
      catch (SQLiteException)
#endif
      {
#if DEBUG
        try
        {
          Trace.WriteLine(String.Format(
              "FinalizeStatement: {0}, exception: {1}",
              handle, e));
        }
        catch
        {
        }
#endif
      }
#if DEBUG
      return false;
#else
      return true;
#endif
    }

    public override bool IsInvalid
    {
      get { return (handle == IntPtr.Zero); }
    }
  }
}










<
<
<
<
<

<
<


<

<
|

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

<
<
<
<
<
<
<
<
<
<
<

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


<
|
<
<


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


<
<
<
|


<
|
<
<


|
<
<
<
<
<

<
<
<
<
<
<
<
<

<
|

<
<
<

<
<
<
<
<
<
<
<
|

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

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

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
<
<
<
<
<
<
<
|

<
<
<

<
<
<
<
<
<
<
<
|

<
<
<

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


|


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

<
<
<

<
|

<
<
<

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

<
<
<
<
<
<
<
<
<
<

<
|

<
<
<

<
|

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<
<

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

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
|

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
|

<
<
<
<

<
<
<
<
<
<
<
<
|

<
<
<
<

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

<
<
<

<
|

<
<
<

<
|

<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
|

<
<
<
<

<
<
<
<
<
<
<
<
|

<
<
<

<
<
|
<
<
<
<
<
<
<

<
<
<

<
<
<
<
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<

<
|

<
<
<

<
|

<
<
<

<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

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

<
<
<

<
<
|
<
<
<
<
<
<
<
<

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
<
|
<
<
<
<
<
<

<
<
<

<
|

<
<
<
<
<
<
<
<
<
<

<
|

<
<
<

<
|

<
<
<
<
<
<

<
|

<
<
<

<
|

<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
|
<
|
<
<
|
<
|
<
|
<
<
|
<
<
<
<
<
|
<
|
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<
>
|
<
<
|
|
<
|
<
|
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<


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

namespace System.Data.SQLite
{
  using System;





  using System.Security;


  using System.Runtime.InteropServices;


  [SuppressUnmanagedCodeSecurity]

  internal class UnsafeNativeMethods
  {











    private const string SQLITE_DLL = "SQLite.Interop.DLL";













    [DllImport(SQLITE_DLL)]















    internal static extern IntPtr sqlite3_libversion_interop(out int len);

    [DllImport(SQLITE_DLL)]

    internal static extern void sqlite3_free_interop(IntPtr p);



    [DllImport(SQLITE_DLL)]









































    internal static extern int sqlite3_open_interop(byte[] utf8Filename, out int db);

    [DllImport(SQLITE_DLL)]



    internal static extern int sqlite3_close_interop(int db);

    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_exec_interop(int db, byte[] strSql, int pvCallback, int pvParam, out IntPtr errMsg, out int len);



    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_errmsg_interop(int db, out int len);














    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_changes_interop(int db);




    [DllImport(SQLITE_DLL)]








    internal static extern int sqlite3_busy_timeout_interop(int db, int ms);




    [DllImport(SQLITE_DLL)]


    internal static extern int sqlite3_prepare_interop(int db, byte[] strSql, int nBytes, out int stmt, out IntPtr ptrRemain, out int nRemain);










    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_bind_blob_interop(int stmt, int index, Byte[] value, int nSize, int nTransient);

























    [DllImport(SQLITE_DLL)]


    internal static extern int sqlite3_bind_double_interop(int stmt, int index, ref double value);










    [DllImport(SQLITE_DLL)]


    internal static extern int sqlite3_bind_int_interop(int stmt, int index, int value);










    [DllImport(SQLITE_DLL)]


    internal static extern int sqlite3_bind_int64_interop(int stmt, int index, ref long value);










    [DllImport(SQLITE_DLL)]


    internal static extern int sqlite3_bind_null_interop(int stmt, int index);










    [DllImport(SQLITE_DLL)]


    internal static extern int sqlite3_bind_text_interop(int stmt, int index, byte[] value, int nlen, int pvReserved);










    [DllImport(SQLITE_DLL)]








    internal static extern int sqlite3_bind_parameter_count_interop(int stmt);




    [DllImport(SQLITE_DLL)]








    internal static extern IntPtr sqlite3_bind_parameter_name_interop(int stmt, int index, out int len);




    [DllImport(SQLITE_DLL)]


















    internal static extern int sqlite3_bind_parameter_index_interop(int stmt, byte[] strName);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_column_count_interop(int stmt);

    [DllImport(SQLITE_DLL)]






















    internal static extern IntPtr sqlite3_column_name_interop(int stmt, int index, out int len);




    [DllImport(SQLITE_DLL)]

    internal static extern IntPtr sqlite3_column_decltype_interop(int stmt, int index, out int len);




    [DllImport(SQLITE_DLL)]















    internal static extern int sqlite3_step_interop(int stmt);











    [DllImport(SQLITE_DLL)]

    internal static extern void sqlite3_column_double_interop(int stmt, int index, out double value);




    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_column_int_interop(int stmt, int index);




    [DllImport(SQLITE_DLL)]


    internal static extern void sqlite3_column_int64_interop(int stmt, int index, out long value);











    [DllImport(SQLITE_DLL)]


    internal static extern IntPtr sqlite3_column_text_interop(int stmt, int index, out int len);









































    [DllImport(SQLITE_DLL)]


    internal static extern IntPtr sqlite3_column_blob_interop(int stmt, int index);










    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_column_bytes_interop(int stmt, int index);




    [DllImport(SQLITE_DLL)]


    internal static extern TypeAffinity sqlite3_column_type_interop(int stmt, int index);










    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_finalize_interop(int stmt);





    [DllImport(SQLITE_DLL)]








    internal static extern int sqlite3_reset_interop(int stmt);





    [DllImport(SQLITE_DLL)]





























    internal static extern int sqlite3_create_collation_interop(int db, byte[] strName, int nType, int nArgs, SQLiteCollation func, out int nCookie);




    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_create_function_interop(int db, byte[] strName, int nArgs, int nType, SQLiteCallback func, SQLiteCallback fstep, SQLiteCallback ffinal, out int nCookie);




    [DllImport(SQLITE_DLL)]

    internal static extern void sqlite3_function_free_callbackcookie(int nCookie);












    [DllImport(SQLITE_DLL)]








    internal static extern int sqlite3_aggregate_count_interop(int context);





    [DllImport(SQLITE_DLL)]








    internal static extern IntPtr sqlite3_value_blob_interop(int p);




    [DllImport(SQLITE_DLL)]


    internal static extern int sqlite3_value_bytes_interop(int p);











    [DllImport(SQLITE_DLL)]








    internal static extern void sqlite3_value_double_interop(int p, out double value);












    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_value_int_interop(int p);




    [DllImport(SQLITE_DLL)]

    internal static extern void sqlite3_value_int64_interop(int p, out Int64 value);




    [DllImport(SQLITE_DLL)]

    internal static extern IntPtr sqlite3_value_text_interop(int p, out int len);

























    [DllImport(SQLITE_DLL)]


    internal static extern TypeAffinity sqlite3_value_type_interop(int p);
























    [DllImport(SQLITE_DLL)]


    internal static extern void sqlite3_result_blob_interop(int context, byte[] value, int nSize, int pvReserved);












    [DllImport(SQLITE_DLL)]


    internal static extern void sqlite3_result_double_interop(int context, ref double value);










    [DllImport(SQLITE_DLL)]


    internal static extern void sqlite3_result_error_interop(int context, byte[] strErr, int nLen);










    [DllImport(SQLITE_DLL)]

    internal static extern void sqlite3_result_int_interop(int context, int value);











    [DllImport(SQLITE_DLL)]

    internal static extern void sqlite3_result_int64_interop(int context, ref Int64 value);




    [DllImport(SQLITE_DLL)]

    internal static extern void sqlite3_result_null_interop(int context);







    [DllImport(SQLITE_DLL)]

    internal static extern void sqlite3_result_text_interop(int context, byte[] value, int nLen, int pvReserved);




    [DllImport(SQLITE_DLL)]

    internal static extern int sqlite3_aggregate_context_interop(int context, int nBytes);



    [DllImport(SQLITE_DLL)]





    internal static extern void sqlite3_realcolnames(int db, int bset);




























    [DllImport(SQLITE_DLL)]




    internal static extern IntPtr sqlite3_column_text16_interop(int stmt, int index);




    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]

    internal static extern int sqlite3_open16_interop(string utf16Filename, out int db);




    [DllImport(SQLITE_DLL)]





    internal static extern IntPtr sqlite3_errmsg16_interop(int db);




    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]




    internal static extern int sqlite3_prepare16_interop(int db, string strSql, int sqlLen, out int stmt, out IntPtr ptrRemain);



























    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_bind_text16_interop(int stmt, int index, string value, int nlen, int nTransient);




    [DllImport(SQLITE_DLL)]










    internal static extern IntPtr sqlite3_column_name16_interop(int stmt, int index);







    [DllImport(SQLITE_DLL)]




















    internal static extern IntPtr sqlite3_column_decltype16_interop(int stmt, int index);





    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]







    internal static extern int sqlite3_create_collation16_interop(int db, string strName, int nType, int nArgs, SQLiteCollation func, out int nCookie);




    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]


    internal static extern int sqlite3_create_function16_interop(int db, string strName, int nArgs, int nType, SQLiteCallback func, SQLiteCallback funcstep, SQLiteCallback funcfinal, out int nCookie);



    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_value_text16_interop(int p);



    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]





    internal static extern void sqlite3_result_error16_interop(int context, string strName, int nLen);










    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]




























    internal static extern void sqlite3_result_text16_interop(int context, string strName, int nLen, int pvReserved);




  }
}
Deleted Tests/Installer_Test_Vs2008.log.
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
Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled.
Installer.exe: #2: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]"
Installer.exe: #3: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]"
Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727", writable = False
Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = False
Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "SQLite"
Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True
Installer.exe: #10: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "System.Data.SQLite"
Installer.exe: #11: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\System.Data.SQLite", name = <null>, value = "[file nativename [getBuildDirectory]]"
Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727", writable = False
Installer.exe: #13: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #14: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #17: Installer.RemoveDbProviderFactory: element = <null>
Installer.exe: #18: Installer.AddDbProviderFactory: element = <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=[file version $systemDataSQLiteDllFile], Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
Installer.exe: #19: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #20: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #21: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Packages", writable = True
Installer.exe: #23: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}"
Installer.exe: #24: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = <null>, value = "System.Data.SQLite Designer Package"
Installer.exe: #25: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "Class", value = "SQLite.Designer.SQLitePackage"
Installer.exe: #26: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]"
Installer.exe: #27: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ID", value = 400
Installer.exe: #28: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "InprocServer32", value = "[file nativename [file join $::env(windir) system32 mscoree.dll]]"
Installer.exe: #29: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CompanyName", value = "http://system.data.sqlite.org/"
Installer.exe: #30: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "MinEdition", value = "standard"
Installer.exe: #31: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductName", value = "System.Data.SQLite Designer Package"
Installer.exe: #32: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductVersion", value = "1.0"
Installer.exe: #33: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", subKeyName = "Toolbox"
Installer.exe: #34: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\Toolbox", name = "Default Items", value = 3
Installer.exe: #35: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Menus", writable = True
Installer.exe: #36: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", value = ", 1000, 3"
Installer.exe: #37: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Services", writable = True
Installer.exe: #38: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}"
Installer.exe: #39: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = <null>, value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}"
Installer.exe: #40: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = "Name", value = "System.Data.SQLite Designer Service"
Installer.exe: #41: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #42: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #43: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #44: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "DataSources", writable = True
Installer.exe: #45: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}"
Installer.exe: #46: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", name = <null>, value = "System.Data.SQLite Database File"
Installer.exe: #47: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", subKeyName = "SupportingProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}"
Installer.exe: #48: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #49: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #50: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #51: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "DataProviders", writable = True
Installer.exe: #52: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}"
Installer.exe: #53: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = <null>, value = ".NET Framework Data Provider for SQLite"
Installer.exe: #54: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "InvariantName", value = "System.Data.SQLite"
Installer.exe: #55: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "Technology", value = "{77ab9a9d-78b9-4ba7-91ac-873f5338f1d2}"
Installer.exe: #56: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]"
Installer.exe: #57: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "FactoryService", value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}"
Installer.exe: #58: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionUIControl"
Installer.exe: #59: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionProperties"
Installer.exe: #60: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionSupport"
Installer.exe: #61: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataObjectSupport"
Installer.exe: #62: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataViewSupport"
Installer.exe: #63: Installer.Main: subKeysCreated = 12, subKeysDeleted = 1, keyValuesSet = 20, keyValuesDeleted = 0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted Tests/Installer_Test_Vs2010.log.
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
Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled.
Installer.exe: #2: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]"
Installer.exe: #3: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]"
Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319", writable = False
Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = False
Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "SQLite"
Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = True
Installer.exe: #10: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "System.Data.SQLite"
Installer.exe: #11: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\System.Data.SQLite", name = <null>, value = "[file nativename [getBuildDirectory]]"
Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319", writable = False
Installer.exe: #13: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #14: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #17: Installer.RemoveDbProviderFactory: element = <null>
Installer.exe: #18: Installer.AddDbProviderFactory: element = <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=[file version $systemDataSQLiteDllFile], Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
Installer.exe: #19: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #20: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #21: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Packages", writable = True
Installer.exe: #23: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}"
Installer.exe: #24: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = <null>, value = "System.Data.SQLite Designer Package"
Installer.exe: #25: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "Class", value = "SQLite.Designer.SQLitePackage"
Installer.exe: #26: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]"
Installer.exe: #27: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ID", value = 400
Installer.exe: #28: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "InprocServer32", value = "[file nativename [file join $::env(windir) system32 mscoree.dll]]"
Installer.exe: #29: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CompanyName", value = "http://system.data.sqlite.org/"
Installer.exe: #30: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "MinEdition", value = "standard"
Installer.exe: #31: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductName", value = "System.Data.SQLite Designer Package"
Installer.exe: #32: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductVersion", value = "1.0"
Installer.exe: #33: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", subKeyName = "Toolbox"
Installer.exe: #34: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\Toolbox", name = "Default Items", value = 3
Installer.exe: #35: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Menus", writable = True
Installer.exe: #36: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", value = ", 1000, 3"
Installer.exe: #37: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Services", writable = True
Installer.exe: #38: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}"
Installer.exe: #39: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = <null>, value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}"
Installer.exe: #40: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = "Name", value = "System.Data.SQLite Designer Service"
Installer.exe: #41: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #42: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #43: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #44: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "DataSources", writable = True
Installer.exe: #45: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}"
Installer.exe: #46: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", name = <null>, value = "System.Data.SQLite Database File"
Installer.exe: #47: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", subKeyName = "SupportingProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}"
Installer.exe: #48: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #49: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #50: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #51: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "DataProviders", writable = True
Installer.exe: #52: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}"
Installer.exe: #53: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = <null>, value = ".NET Framework Data Provider for SQLite"
Installer.exe: #54: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "InvariantName", value = "System.Data.SQLite"
Installer.exe: #55: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "Technology", value = "{77ab9a9d-78b9-4ba7-91ac-873f5338f1d2}"
Installer.exe: #56: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]"
Installer.exe: #57: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "FactoryService", value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}"
Installer.exe: #58: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionUIControl"
Installer.exe: #59: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionProperties"
Installer.exe: #60: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionSupport"
Installer.exe: #61: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataObjectSupport"
Installer.exe: #62: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataViewSupport"
Installer.exe: #63: Installer.Main: subKeysCreated = 12, subKeysDeleted = 1, keyValuesSet = 20, keyValuesDeleted = 0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted Tests/Uninstaller_Test_Vs2008.log.
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
Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled.
Installer.exe: #2: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]"
Installer.exe: #3: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]"
Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727", writable = False
Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = False
Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "System.Data.SQLite"
Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727", writable = False
Installer.exe: #10: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #11: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #13: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #14: Installer.RemoveDbProviderFactory: element = <null>
Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #17: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #18: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Packages", writable = True
Installer.exe: #19: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}"
Installer.exe: #20: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Menus", writable = True
Installer.exe: #21: RegistryHelper.DeleteValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}"
Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Services", writable = True
Installer.exe: #23: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}"
Installer.exe: #24: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #25: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #26: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #27: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "DataSources", writable = True
Installer.exe: #28: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}"
Installer.exe: #29: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #30: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #31: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False
Installer.exe: #32: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "DataProviders", writable = True
Installer.exe: #33: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}"
Installer.exe: #34: Installer.Main: subKeysCreated = 0, subKeysDeleted = 5, keyValuesSet = 0, keyValuesDeleted = 1
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































Deleted Tests/Uninstaller_Test_Vs2010.log.
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
Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled.
Installer.exe: #2: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]"
Installer.exe: #3: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]"
Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319", writable = False
Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = False
Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "System.Data.SQLite"
Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319", writable = False
Installer.exe: #10: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #11: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False
Installer.exe: #13: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = <null>
Installer.exe: #14: Installer.RemoveDbProviderFactory: element = <null>
Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #17: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #18: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Packages", writable = True
Installer.exe: #19: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}"
Installer.exe: #20: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Menus", writable = True
Installer.exe: #21: RegistryHelper.DeleteValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}"
Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Services", writable = True
Installer.exe: #23: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}"
Installer.exe: #24: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #25: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #26: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #27: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "DataSources", writable = True
Installer.exe: #28: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}"
Installer.exe: #29: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #30: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = <null>
Installer.exe: #31: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False
Installer.exe: #32: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "DataProviders", writable = True
Installer.exe: #33: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}"
Installer.exe: #34: Installer.Main: subKeysCreated = 0, subKeysDeleted = 5, keyValuesSet = 0, keyValuesDeleted = 1
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































Deleted Tests/all.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
###############################################################################
#
# all.eagle --
#
# This file contains a top-level script to run all of the tests.
# Execute it by invoking "source all.eagle".
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Test Suite File
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

#
# NOTE: Pre-load the assembly and the necessary helper procedures now, so that
#       they do not count as being "leaked" (i.e. the test framework has no way
#       to know who procedures actually belong to).
#
package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

set no(prologue.eagle) true
set no(epilogue.eagle) true

#
# NOTE: Run the local test prologue, if any.
#
if {[file exists [file join $path prologue.eagle]]} then {
  source [file join $path prologue.eagle]
}

#
# NOTE: Run all the unit tests.
#
set test_time [time {
  runAllTests $test_channel $path \
      [getTestFiles [list $path] $test_flags(-file) $test_flags(-notFile)] \
      [list [file tail [info script]] *.tcl pkgIndex.eagle common.eagle \
      constraints.eagle epilogue.eagle prologue.eagle]
}]

#
# NOTE: Run the local test epilogue, if any.
#
if {[file exists [file join $path epilogue.eagle]]} then {
  source [file join $path epilogue.eagle]
}

tputs $test_channel [appendArgs "---- all tests completed in " $test_time \n]
unset test_time

unset no(epilogue.eagle)
unset no(prologue.eagle)

if {[array size no] == 0} then {unset no}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































Deleted Tests/basic.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
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
###############################################################################
#
# basic.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Setup the variables that refer to the various files required by the
#       tests in this file.
#
set testExeFile [getBuildFileName test.exe]
set testLinqExeFile [getBuildFileName testlinq.exe]
set testLinqOutFile [file nativename [file join $path testlinq.out]]
set northwindEfDbFile [file nativename [file join [file dirname $path] \
    testlinq northwindEF.db]]

#
# NOTE: Setup the test constraints specific to the tests in this file.
#
if {![haveConstraint [appendArgs file_ [file tail $testExeFile]]]} then {
  checkForFile $test_channel $testExeFile
}

if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then {
  checkForFile $test_channel $testLinqExeFile
}

if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then {
  checkForFile $test_channel $northwindEfDbFile
}

if {![haveConstraint [appendArgs file_ [file tail $testLinqOutFile]]]} then {
  checkForFile $test_channel $testLinqOutFile
}

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

runTest {test data-1.1 {unit tests from the 'test' project} -setup {
  catch {file delete [file join [file dirname $testExeFile] Test.db3]}

  set fileName [file join [getDatabaseDirectory] data-1.1.db]
  cleanupDb $fileName
} -body {
  set output ""

  set code [catch {
    #
    # NOTE: For the sake of backward compatibility, the "-autoRun" argument
    #       must be first.
    #
    testClrExec $testExeFile [list -eventflags Wait -directory \
        [file dirname $testExeFile] -stdout output -success 0] -autoRun \
        -fileName [appendArgs \" [file nativename $fileName] \"]
  } error]

  tlog "---- BEGIN STDOUT OUTPUT\n"
  tlog $output
  tlog "\n---- END STDOUT OUTPUT\n"

  list $code [expr {$code == 0 ? "" : $error}]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain code output error fileName
} -constraints {eagle file_test.exe} -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.
  #
  file copy -force $northwindEfDbFile \
      [file join [getBuildDirectory] [file tail $northwindEfDbFile]]

  #
  # NOTE: We need to make 100% sure that the console output encoding is the
  #       same as when the 'testlinq.out' file was created.
  #
  set savedEncoding [object invoke Console OutputEncoding]
  set encoding [object invoke System.Text.Encoding GetEncoding Windows-1252]

  object invoke Console OutputEncoding $encoding
} -body {
  set output ""

  set code [catch {
    testClrExec $testLinqExeFile [list -eventflags Wait -directory \
        [file dirname $testLinqExeFile] -stdout output -success 0]
  } error]

  tlog "---- BEGIN STDOUT OUTPUT\n"
  tlog $output
  tlog "\n---- END STDOUT OUTPUT\n"

  list $code [string equal $output [readFile $testLinqOutFile]] \
      [expr {$code == 0 ? "" : $error}]
} -cleanup {
  catch {object invoke Console OutputEncoding $savedEncoding}

  unset -nocomplain code output error savedEncoding encoding
} -constraints \
{eagle monoToDo file_testlinq.exe file_northwindEF.db file_testlinq.out} \
-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]

  lappend result [sql execute -execute scalar $db \
      "SELECT sqlite_source_id();"]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y, z);"
  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(1, 'foo', 1234);"

  sql execute -execute reader $db "SELECT x, y, z FROM t1;"

  foreach name [lsort [array names rows]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^\{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [0-9a-f]{40}\}\
\{1 \{\{x 1\} \{y foo\} \{z 1234\}\}\} \{count 1\} \{names \{x y z\}\}$}}

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

runTest {test data-1.4 {GetSchema with ReservedWords} -setup {
  setupDb [set fileName data-1.4.db]
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] data-1.4.db]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static DataTable GetReservedWords()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            return connection.GetSchema("ReservedWords");
          }
        }

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [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+$}}

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

runTest {test data-1.5 {GetSchema with ForeignKeys} -setup {
  setupDb [set fileName data-1.5.db]
} -body {
  sql execute $db {
    CREATE TABLE t1(
      x INTEGER REFERENCES t2 MATCH FULL
      ON UPDATE SET DEFAULT ON DELETE CASCADE
      DEFAULT 1
    );
  }

  sql execute $db "CREATE TABLE t2(x INTEGER REFERENCES t3);"

  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] data-1.5.db]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static DataRowCollection GetForeignKeys()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            return connection.GetSchema("ForeignKeys").Rows;
          }
        }

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        set rows [list]
        set foreignKeys [object invoke _Dynamic${id}.Test${id} GetForeignKeys]

        object foreach -alias foreignKey $foreignKeys {
          lappend rows [list \
              [$foreignKey Item CONSTRAINT_CATALOG] \
              [$foreignKey Item CONSTRAINT_NAME] \
              [$foreignKey Item TABLE_CATALOG] \
              [$foreignKey Item TABLE_NAME] \
              [$foreignKey Item CONSTRAINT_TYPE] \
              [$foreignKey Item IS_DEFERRABLE] \
              [$foreignKey Item INITIALLY_DEFERRED] \
              [$foreignKey Item FKEY_FROM_COLUMN] \
              [$foreignKey Item FKEY_TO_CATALOG] \
              [$foreignKey Item FKEY_TO_TABLE] \
              [$foreignKey Item FKEY_TO_COLUMN] \
              [$foreignKey Item FKEY_FROM_ORDINAL_POSITION] \
              [$foreignKey Item FKEY_ON_UPDATE] \
              [$foreignKey Item FKEY_ON_DELETE] \
              [$foreignKey Item FKEY_MATCH]]
        }

        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 main t1 \{FOREIGN KEY\} False False x main t2 \{\} 0 \{SET\
DEFAULT\} CASCADE NONE\} \{main FK_t2_0 main t2 \{FOREIGN KEY\} False False 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]
  set dataSource [file join [getDatabaseDirectory] data-1.6.db]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static bool TestSetAvRetry(
          ref int count,
          ref int interval
          )
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            //
            // NOTE: Set the requested retry parameter values.
            //
            if (connection.SetAvRetry(ref count, ref interval) != 0)
              return false;

            //
            // NOTE: Query the retry parameter values.
            //
            int newCount = -1; int newInterval = -1;

            if (connection.SetAvRetry(ref newCount, ref newInterval) != 0)
              return false;

            //
            // NOTE: Make sure the retry parameter values were set.
            //
            return (newCount == count && newInterval == interval);
          }
        }

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        set savedCount -1; set savedInterval -1

        object invoke _Dynamic${id}.Test${id} TestSetAvRetry \
            savedCount savedInterval

        set count 5; set interval 50

        object invoke _Dynamic${id}.Test${id} TestSetAvRetry \
            count interval
      } result] : [set result ""]}] $result
} -cleanup {
  if {[info exists savedCount]} then {
    #
    # NOTE: Restore the saved retry count, if possible.
    #
    catch {
      set interval -1
      object invoke _Dynamic${id}.Test${id} TestSetAvRetry savedCount interval
    }
  }

  if {[info exists savedInterval]} then {
    #
    # NOTE: Restore the saved retry interval, if possible.
    #
    catch {
      set count -1
      object invoke _Dynamic${id}.Test${id} TestSetAvRetry count savedInterval
    }
  }

  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\
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]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  set sql { \
    BEGIN EXCLUSIVE TRANSACTION; \
    CREATE TABLE t1(x INTEGER); \
    INSERT INTO t1 (x) VALUES(1); \
    SELECT * FROM t1; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = new SQLiteCommand("${sql}",
                connection))
            {
              command.ExecuteNonQuery();
            }
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        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 db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-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]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  set sql { \
    BEGIN EXCLUSIVE TRANSACTION; \
    CREATE TABLE t1(x INTEGER); \
    INSERT INTO t1 (x) VALUES(1); \
    SELECT * FROM t1; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = new SQLiteCommand("${sql}",
                connection))
            {
              using (SQLiteDataReader dataReader = command.ExecuteReader())
              {
                // do nothing.
              }
            }
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        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 db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-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]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  set sql { \
    BEGIN EXCLUSIVE TRANSACTION; \
    CREATE TABLE t1(x INTEGER); \
    INSERT INTO t1 (x) VALUES(1); \
    SELECT * FROM t1; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = new SQLiteCommand("${sql}",
                connection))
            {
              using (SQLiteDataReader dataReader = command.ExecuteReader(
                  CommandBehavior.CloseConnection))
              {
                // do nothing.
              }
            }
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        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 db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-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 [object invoke -flags +NonPublic -objectflags +NoDispose \
      Interpreter.GetActive.connections Item $db]

  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y, z);"

  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(1, 'foo', 1234);"
  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(2, 'bar', 5678);"
  lappend result [object invoke $connection Changes]

  sql execute $db "UPDATE t1 SET y = 'foobar';"
  lappend result [object invoke $connection Changes]

  sql execute -execute reader $db "SELECT x, y, z FROM t1;"
  lappend result [object invoke $connection Changes]

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result connection db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result {1 2 2 {1 {{x 1} {y foobar} {z 1234}}} {2 {{x 2} {y foobar} {z 5678}}}}}

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

runTest {test data-1.11 {LastInsertRowId property} -setup {
  setupDb [set fileName data-1.11.db]
} -body {
  set connection [object invoke -flags +NonPublic -objectflags +NoDispose \
      Interpreter.GetActive.connections Item $db]

  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y, z);"

  sql execute $db "CREATE TABLE t2(x INTEGER PRIMARY KEY AUTOINCREMENT, y, z);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(1, 'foo', 1234);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(2, 'bar', 5678);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "UPDATE t1 SET y = 'foobar';"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "INSERT INTO t2 (y, z) VALUES('foo', 1234);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "INSERT INTO t2 (y, z) VALUES('bar', 5678);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "UPDATE t2 SET y = 'foobar';"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute -execute reader $db "SELECT x, y, z FROM t1;"
  lappend result [object invoke $connection LastInsertRowId]

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  sql execute -execute reader $db "SELECT x, y, z FROM t2;"
  lappend result [object invoke $connection LastInsertRowId]

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result connection db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result {0 1 2 2 1 2 2 2 {1 {{x 1} {y foobar} {z 1234}}} {2 {{x 2} {y foobar}\
{z 5678}}} 2 {1 {{x 1} {y foobar} {z 1234}}} {2 {{x 2} {y foobar} {z 5678}}}}}

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

runTest {test data-1.12 {DateTime using Unix epoch} -setup {
  setupDb [set fileName data-1.12.db] "" UnixEpoch Utc
} -body {
  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y DATETIME);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(1, 1302825600);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(2, 1334448000);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(3, 1365984000);"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(4, ?);" \
      [list param1 Int32 1302825600]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(5, ?);" \
      [list param1 Int32 1334448000]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(6, ?);" \
      [list param1 Int32 1365984000]

  sql execute -verbatim $db "INSERT INTO t1 (x, y) VALUES(7, ?);" \
      [list param1 DateTime 1302825600]

  sql execute -verbatim $db "INSERT INTO t1 (x, y) VALUES(8, ?);" \
      [list param1 DateTime 1334448000]

  sql execute -verbatim $db "INSERT INTO t1 (x, y) VALUES(9, ?);" \
      [list param1 DateTime 1365984000]

  sql execute -execute reader -datetimeformat [getDateTimeFormat] $db \
      "SELECT x, y FROM t1 ORDER BY x;"

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result {{1 {{x 1} {y {2011-04-15 00:00:00Z}}}} {2 {{x 2} {y {2012-04-15\
00:00:00Z}}}} {3 {{x 3} {y {2013-04-15 00:00:00Z}}}} {4 {{x 4} {y {2011-04-15\
00:00:00Z}}}} {5 {{x 5} {y {2012-04-15 00:00:00Z}}}} {6 {{x 6} {y {2013-04-15\
00:00:00Z}}}} {7 {{x 7} {y {2011-04-15 00:00:00Z}}}} {8 {{x 8} {y {2012-04-15\
00:00:00Z}}}} {9 {{x 9} {y {2013-04-15 00:00:00Z}}}}}}

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

set date [clock format [clock seconds] -format yyyy-MM-dd]

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

runTest {test data-1.13 {DateTime using invariant culture} -setup {
  setupDb [set fileName data-1.13.db] "" InvariantCulture Utc
} -body {
  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y DATETIME);"

  sql execute $db \
      "INSERT INTO t1 (x, y) VALUES(1, 'Wednesday, 16 December 2009');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(2, '12:00:00');"

  sql execute $db \
      "INSERT INTO t1 (x, y) VALUES(3, 'Wednesday, 16 December 2009 12:00:00');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(4, '12/16/2009');"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(5, '12:00');"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(6, '12/16/2009 12:00');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(7, ?);" \
      [list param1 DateTime "Wednesday, 16 December 2009"]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(8, ?);" \
      [list param1 DateTime 12:00:00]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(9, ?);" \
      [list param1 DateTime "Wednesday, 16 December 2009 12:00:00"]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(10, ?);" \
      [list param1 DateTime 12/16/2009]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(11, ?);" \
      [list param1 DateTime 12:00]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(12, ?);" \
      [list param1 DateTime "12/16/2009 12:00"]

  sql execute -execute reader -datetimeformat [getDateTimeFormat] $db \
      "SELECT x, CAST(y AS TEXT) AS y2 FROM t1 ORDER BY x;"

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result [subst {{1 {{x 1} {y2 {Wednesday, 16 December 2009}}}} {2 {{x 2} {y2\
12:00:00}}} {3 {{x 3} {y2 {Wednesday, 16 December 2009 12:00:00}}}} {4 {{x 4}\
{y2 12/16/2009}}} {5 {{x 5} {y2 12:00}}} {6 {{x 6} {y2 {12/16/2009 12:00}}}} {7\
{{x 7} {y2 2009-12-16T00:00:00.0000000Z}}} {8 {{x 8} {y2\
${date}T12:00:00.0000000Z}}} {9 {{x 9} {y2 2009-12-16T12:00:00.0000000Z}}}\
{10 {{x 10} {y2 2009-12-16T00:00:00.0000000Z}}} {11 {{x 11} {y2\
${date}T12:00:00.0000000Z}}} {12 {{x 12} {y2 2009-12-16T12:00:00.0000000Z}}}}]}

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

runTest {test data-1.14 {DateTime using current culture} -setup {
  setupDb [set fileName data-1.14.db] "" CurrentCulture Utc
} -body {
  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y DATETIME);"

  sql execute $db \
      "INSERT INTO t1 (x, y) VALUES(1, 'Wednesday, 16 December 2009');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(2, '12:00:00');"

  sql execute $db \
      "INSERT INTO t1 (x, y) VALUES(3, 'Wednesday, 16 December 2009 12:00:00');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(4, '12/16/2009');"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(5, '12:00');"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(6, '12/16/2009 12:00');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(7, ?);" \
      [list param1 DateTime "Wednesday, 16 December 2009"]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(8, ?);" \
      [list param1 DateTime 12:00:00]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(9, ?);" \
      [list param1 DateTime "Wednesday, 16 December 2009 12:00:00"]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(10, ?);" \
      [list param1 DateTime 12/16/2009]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(11, ?);" \
      [list param1 DateTime 12:00]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(12, ?);" \
      [list param1 DateTime "12/16/2009 12:00"]

  sql execute -execute reader -datetimeformat [getDateTimeFormat] $db \
      "SELECT x, CAST(y AS TEXT) AS y2 FROM t1 ORDER BY x;"

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result db fileName
} -constraints \
{eagle culture.invariant monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -result [subst {{1 {{x 1} {y2 {Wednesday, 16 December\
2009}}}} {2 {{x 2} {y2 12:00:00}}} {3 {{x 3} {y2 {Wednesday, 16 December 2009\
12:00:00}}}} {4 {{x 4} {y2 12/16/2009}}} {5 {{x 5} {y2 12:00}}} {6 {{x 6} {y2\
{12/16/2009 12:00}}}} {7 {{x 7} {y2 2009-12-16T00:00:00.0000000Z}}} {8 {{x 8}\
{y2 ${date}T12:00:00.0000000Z}}} {9 {{x 9} {y2 2009-12-16T12:00:00.0000000Z}}}\
{10 {{x 10} {y2 2009-12-16T00:00:00.0000000Z}}} {11 {{x 11} {y2\
${date}T12:00:00.0000000Z}}} {12 {{x 12} {y2 2009-12-16T12:00:00.0000000Z}}}}]}

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

unset -nocomplain date

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

runTest {test data-1.15 {SQLiteConnectionStringBuilder DateTime} -body {
  set id [object invoke Interpreter.GetActive NextId]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static string GetConnectionString(
          string format,
          string kind
          )
        {
          SQLiteConnectionStringBuilder builder =
              new SQLiteConnectionStringBuilder();

          builder.Add("Date Source", "test.db");
          builder.Add("DateTimeFormat", format);
          builder.Add("DateTimeKind", kind);

          return builder.ToString();
        }

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} GetConnectionString \
            null null
      } result] : [set result ""]}] $result \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} GetConnectionString \
            Default null
      } result] : [set result ""]}] $result \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} GetConnectionString \
            null Unspecified
      } result] : [set result ""]}] $result \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} GetConnectionString \
            ISO8601 Utc
      } 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=ISO8601\} 0 \{Date\
Source=test\.db;DateTimeKind=Unspecified\} 0 \{Date\
Source=test\.db;DateTimeFormat=ISO8601;DateTimeKind=Utc\}$}}

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

runTest {test data-1.16 {SQLiteConnectionStringBuilder properties} -body {
  set id [object invoke Interpreter.GetActive NextId]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Data.SQLite;
    using System.Reflection;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static string GetConnectionString(
          string key,
          string value,
          string propertyName
          )
        {
          SQLiteConnectionStringBuilder builder =
              new SQLiteConnectionStringBuilder();

          if (key != null)
            builder.Add(key, value);

          object propertyValue = null;

          if (propertyName != null)
          {
            propertyValue = typeof(SQLiteConnectionStringBuilder).InvokeMember(
                propertyName, BindingFlags.Instance | BindingFlags.Public |
                BindingFlags.GetProperty, null, builder, null);
          }

          return String.Format("{0}, {1}", propertyValue, builder);
        }

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  lappend results $code [expr {[info exists errors] ? $errors : ""}]

  if {$code eq "Ok"} then {
    set keys [list null Version Synchronous UseUTF16Encoding Pooling \
                   BinaryGUID "Data Source" Uri "Default Timeout" \
                   Enlist FailIfMissing "Legacy Format" "Read Only" \
                   Password "Page Size" "Max Page Count" "Cache Size" \
                   DateTimeFormat DateTimeKind BaseSchemaName \
                   "Journal Mode" "Default IsolationLevel" "Foreign Keys"]

    set values [list null 3 Full True False \
                     True test.db test.db 60 \
                     False True False True \
                     secret 4096 1024 8192 \
                     UnixEpoch Utc sqlite_schema \
                     Memory Serializable False]

    set propertyNames [list null Version SyncMode UseUTF16Encoding Pooling \
                            BinaryGUID DataSource Uri DefaultTimeout \
                            Enlist FailIfMissing LegacyFormat ReadOnly \
                            Password PageSize MaxPageCount CacheSize \
                            DateTimeFormat DateTimeKind BaseSchemaName \
                            JournalMode DefaultIsolationLevel ForeignKeys]

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

      lappend results $code $result
    }
  }

  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 \{Full, Synchronous=Full\} 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 \{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 \{sqlite_schema, BaseSchemaName=sqlite_schema\} 0\
\{Memory, Journal Mode=Memory\} 0 \{Serializable, Default\
IsolationLevel=Serializable\} 0 \{False, Foreign Keys=False\}$}}

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

unset -nocomplain testExeFile testLinqExeFile northwindEfDbFile testLinqOutFile

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Tests/common.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
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
###############################################################################
#
# common.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

#
# NOTE: Use our own namespace here because even though we do not directly
#       support namespaces ourselves, we do not want to pollute the global
#       namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
  if {[isEagle]} then {
    ###########################################################################
    ############################ BEGIN Eagle ONLY #############################
    ###########################################################################

    proc getBuildYear {} {
      #
      # NOTE: See if the "year" setting has been overridden by the user (e.g. on
      #       the command line).  This helps control exactly which set of
      #       binaries we are testing, those produced using either the Visual
      #       Studio 2008 or Visual Studio 2010 build systems.  To override this
      #       value via the command line, enter a command similar to one of the
      #       following (all on one line):
      #
      #       EagleShell.exe -preInitialize "set test_year 2008"
      #         -file .\path\to\all.eagle
      #
      #       EagleShell.exe -preInitialize "set test_year 2010"
      #         -file .\path\to\all.eagle
      #
      #       EagleShell.exe -preInitialize "unset -nocomplain test_year"
      #         -file .\path\to\all.eagle
      #
      if {[info exists ::test_year] && [string length $::test_year] > 0} then {
        #
        # NOTE: Use the specified test year.  If this variable is not set, the
        #       default value will be based on whether or not Eagle has been
        #       compiled against the .NET Framework 2.0 or 4.0.
        #
        return $::test_year
      } else {
        #
        # NOTE: If Eagle has been compiled against the .NET Framework 4.0, use
        #       "2010" as the test year; otherwise, use "2008".  If another
        #       major [incompatible] version of the .NET Framework is released,
        #       this check will have to be changed.
        #
        return [expr {[haveConstraint imageRuntime40] ? "2010" : "2008"}]
      }
    }

    proc getBuildConfiguration {} {
      #
      # NOTE: See if the "configuration" setting has been overridden by the user
      #       (e.g. on the command line).  This helps control exactly which set
      #       of binaries we are testing (i.e. those built in the "Debug" or
      #       "Release" build configurations).  To override this value via the
      #       command line, enter a command similar to one of the following (all
      #       on one line):
      #
      #       EagleShell.exe -preInitialize "set test_configuration Debug"
      #         -file .\path\to\all.eagle
      #
      #       EagleShell.exe -preInitialize "set test_configuration Release"
      #         -file .\path\to\all.eagle
      #
      #       EagleShell.exe -file .\path\to\all.eagle -preTest
      #         "unset -nocomplain test_configuration"
      #
      if {[info exists ::test_configuration] && \
          [string length $::test_configuration] > 0} then {
        #
        # NOTE: Use the specified test configuration.  The default value used
        #       for this variable is "Release", as set by the test suite itself.
        #
        return $::test_configuration
      } else {
        #
        # NOTE: Normally, we will never hit this case because the value of the
        #       test configuration variable is always set by the test suite
        #       itself; however, it can be overridden using the unset command
        #       from the -preTest option to the test suite.
        #
        return $::eagle_platform(configuration)
      }
    }

    proc getBuildDirectory {} {
      #
      # NOTE: See if the "native" runtime option has been added.  If so, use the
      #       directory for the mixed-mode assembly (a.k.a. the native interop
      #       assembly).  To enable this option via the command line, enter a
      #       command similar to one of the following (all on one line):
      #
      #       EagleShell.exe -initialize -runtimeOption native
      #         -file .\path\to\all.eagle
      #
      #       To enable this option via the command line prior to the "beta 16"
      #       release of Eagle, the following command must be used instead
      #       (also all on one line):
      #
      #       EagleShell.exe -initialize -postInitialize
      #         "object invoke Interpreter.GetActive AddRuntimeOption native"
      #         -file .\path\to\all.eagle
      #
      if {[info exists ::build_directory] && \
          [string length $::build_directory] > 0} then {
        #
        # NOTE: The location of the build directory has been overridden;
        #       therefore, use it verbatim.
        #
        return $::build_directory
      } else {
        #
        # NOTE: Figure out the build base directory.  This will be the directory
        #       that contains the actual build output directory (e.g. "bin").
        #
        if {[info exists ::build_base_directory] && \
            [string length $::build_base_directory] > 0} then {
          #
          # NOTE: The location of the build base directory has been overridden;
          #       therefore, use it verbatim.
          #
          set path $::build_base_directory
        } elseif {[info exists ::common_directory] && \
            [string length $::common_directory] > 0} then {
          #
          # NOTE: Next, fallback to the parent directory of the one containing
          #       this file (i.e. "common.eagle"), if available.
          #
          set path [file dirname $::common_directory]
        } else {
          #
          # NOTE: Finally, fallback to the parent directory of the EagleTest
          #       path.  The EagleTest package guarantees that this variable
          #       will be set to the directory containing the first file to
          #       execute the [runTestPrologue] script library procedure.
          #
          set path [file dirname $::path]
        }

        if {[hasRuntimeOption native]} then {
          return [file join $path bin [getBuildYear] \
              [machineToPlatform $::tcl_platform(machine)] \
              [getBuildConfiguration]]
        } else {
          return [file join $path bin [getBuildYear] \
              [getBuildConfiguration] bin]
        }
      }
    }

    proc getBuildFileName { fileName } {
      return [file nativename \
          [file join [getBuildDirectory] [file tail $fileName]]]
    }

    proc getBinaryDirectory {} {
      #
      # NOTE: This procedure returns the directory where the test application
      #       itself (i.e. the Eagle shell) is located.  This will be used as
      #       the destination for the copied System.Data.SQLite native and
      #       managed assemblies (i.e. because this is one of the few places
      #       where the CLR will actually find and load them properly).
      #
      if {[info exists ::binary_directory] && \
          [string length $::binary_directory] > 0} then {
        #
        # NOTE: The location of the binary directory has been overridden;
        #       therefore, use it verbatim.
        #
        return $::binary_directory
      } else {
        return [info binary]
      }
    }

    proc getBinaryFileName { fileName } {
      return [file nativename \
          [file join [getBinaryDirectory] [file tail $fileName]]]
    }

    proc getDatabaseDirectory {} {
      #
      # NOTE: This procedure returns the directory where the test databases
      #       should be located.  By default, this just uses the temporary
      #       directory configured for this system.
      #
      if {[info exists ::database_directory] && \
          [string length $::database_directory] > 0} then {
        #
        # NOTE: The location of the database directory has been overridden;
        #       therefore, use it.
        #
        return [file normalize $::database_directory]
      } else {
        return [getTemporaryPath]
      }
    }

    proc getAppDomainPreamble { {prefix ""} {suffix ""} } {
      #
      # NOTE: This procedure returns a test setup script suitable for evaluation
      #       by a test interpreter created in an isolated application domain.
      #       The script being returned will be surrounded by the prefix and
      #       suffix "script fragments" specified by the caller, if any.  The
      #       entire script being returned will be substituted via [subst], in
      #       the context of the caller.  This step is necessary so that some
      #       limited context information, primarily related to the test build
      #       directory, can be transferred to the interpreter in the isolated
      #       application domain, making it able to successfully run tests that
      #       require one or more of the files in the build directory.  Callers
      #       to this procedure should keep in mind that the test script being
      #       returned cannot only rely on any script library procedures not
      #       included in the EagleLibrary package (i.e. "init.eagle").  Also,
      #       all variable references and all "nested" commands (i.e. those in
      #       square brackets), unless they are specially quoted, will end up
      #       being evaluated in the context of the calling interpreter and not
      #       the test interpreter created in the isolated application domain.
      #
      return [uplevel 1 [list subst [appendArgs $prefix {
        if {[hasRuntimeOption native]} then {
          object invoke Interpreter.GetActive AddRuntimeOption native
        }

        set ::path {$::path}
        set ::test_year {[getBuildYear]}
        set ::test_configuration {[getBuildConfiguration]}
      } $suffix]]]
    }

    proc tryCopyBuildFile { fileName } {
      #
      # NOTE: If we cannot copy the assembly then it is probably already loaded.
      #
      set sourceFileName [getBuildFileName $fileName]

      if {![file exists $sourceFileName]} then {
        tputs $::test_channel [appendArgs \
            "---- skipped copying build file \"" $sourceFileName \
            "\", it does not exist\n"]

        return
      }

      set targetFileName [getBinaryFileName $fileName]

      if {[catch {
          file copy -force $sourceFileName $targetFileName}] == 0} then {
        tputs $::test_channel [appendArgs \
            "---- copied build file from \"" $sourceFileName "\" to \"" \
            $targetFileName \"\n]
      } else {
        tputs $::test_channel [appendArgs \
            "---- failed to copy build file from \"" $sourceFileName \
            "\" to \"" $targetFileName \"\n]
      }
    }

    proc tryDeleteBinaryFile { fileName } {
      set fileName [getBinaryFileName $fileName]

      if {![file exists $fileName]} then {
        tputs $::test_channel [appendArgs \
            "---- skipped deleting binary file \"" $fileName \
            "\", it does not exist\n"]

        return
      }

      if {[catch {file delete $fileName}] == 0} then {
        tputs $::test_channel [appendArgs \
            "---- deleted binary file \"" $fileName \"\n]
      } else {
        tputs $::test_channel [appendArgs \
            "---- failed to delete binary file \"" $fileName \"\n]
      }
    }

    proc tryCopyAssembly { fileName {pdb true} } {
      tryCopyBuildFile $fileName

      if {$pdb} then {
        tryCopyBuildFile [appendArgs [file rootname $fileName] .pdb]
      }
    }

    proc tryDeleteAssembly { fileName {pdb true} } {
      tryDeleteBinaryFile $fileName

      if {$pdb} then {
        tryDeleteBinaryFile [appendArgs [file rootname $fileName] .pdb]
      }
    }

    proc tryLoadAssembly { fileName } {
      set fileName [getBinaryFileName $fileName]

      if {[catch {set assembly \
          [object load -loadtype File -alias $fileName]}] == 0} then {
        #
        # NOTE: Now, add the necessary test constraint.
        #
        addConstraint [file rootname [file tail $fileName]]

        #
        # NOTE: Grab the image runtime version from the assembly because
        #       several tests rely on it having a certain value.
        #
        addConstraint [appendArgs [file tail $fileName] _ \
            [$assembly ImageRuntimeVersion]]

        #
        # NOTE: Return the full path of the loaded file.
        #
        return $fileName
      }

      return ""
    }

    proc checkForSQLite { channel } {
      tputs $channel "---- checking for core SQLite library... "

      if {[catch {object invoke -flags +NonPublic System.Data.SQLite.SQLite3 \
              SQLiteVersion} version] == 0} then {
        #
        # 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: Yes, the SQLite core library appears to be available.
        #
        addConstraint SQLite

        tputs $channel [appendArgs "yes (" $version " " $sourceId ")\n"]
      } else {
        tputs $channel no\n
      }
    }

    proc getDateTimeFormat {} {
      #
      # NOTE: This procedure simply returns the "default" DateTime format used
      #       by the test suite.
      #
      if {[info exists ::datetime_format] && \
          [string length $::datetime_format] > 0} then {
        #
        # NOTE: Return the manually overridden value for the DateTime format.
        #
        return $::datetime_format
      } else {
        #
        # NOTE: Return an ISO8601 DateTime format compatible with SQLite,
        #       System.Data.SQLite, and suitable for round-tripping with the
        #       DateTime class of the framework.  If this value is changed,
        #       various tests may fail.
        #
        return "yyyy-MM-dd HH:mm:ss.FFFFFFFK"
      }
    }

    proc enumerableToList { enumerable } {
      set result [list]

      if {[string length $enumerable] == 0 || $enumerable eq "null"} then {
        return $result
      }

      object foreach -alias item $enumerable {
        if {[string length $item] > 0} then {
          lappend result [$item ToString]
        }
      }

      return $result
    }

    proc compileCSharpWith {
            text memory symbols strict resultsVarName errorsVarName fileNames
            args } {
      #
      # NOTE: Create the base command to evaluate and add the property settings
      #       that are almost always needed by our unit tests (i.e. the System
      #       and System.Data assembly references).
      #
      set command [list compileCSharp $text $memory $symbols $strict results \
          errors ReferencedAssemblies.Add System.dll ReferencedAssemblies.Add \
          System.Data.dll ReferencedAssemblies.Add System.Xml.dll]

      #
      # NOTE: Add all the provided file names as assembly references.
      #
      foreach fileName $fileNames {
        lappend command ReferencedAssemblies.Add [getBinaryFileName $fileName]
      }

      #
      # NOTE: Add the extra arguments, if any, to the command to evaluate.
      #
      eval lappend command $args

      #
      # NOTE: Alias the compiler local results and errors variables to the
      #       variable names provided by our caller.
      #
      upvar 1 $resultsVarName results
      upvar 1 $errorsVarName errors

      #
      # NOTE: Evaluate the constructed [compileCSharp] command and return the
      #       result.
      #
      eval $command
    }

    proc setupDb {
            fileName {mode ""} {dateTimeFormat ""} {dateTimeKind ""} {extra ""}
            {delete true} {varName db}} {
      #
      # NOTE: For now, all test databases used by the test suite are placed into
      #       the temporary directory.  Each database used by a test should be
      #       cleaned up by that test using the "cleanupDb" procedure, below.
      #
      set fileName [file join [getDatabaseDirectory] [file tail $fileName]]

      #
      # NOTE: By default, delete any pre-existing database with the same file
      #       name if it currently exists.
      #
      if {$delete && [file exists $fileName]} then {
        if {[catch {file delete $fileName} error]} then {
          #
          # NOTE: We somehow failed to delete the file, report why.
          #
          tputs $::test_channel [appendArgs \
              "==== WARNING: failed to delete database file \"" $fileName \
              "\" during setup, error: " \n\t $error \n]
        }
      }

      #
      # NOTE: Refer to the specified variable (e.g. "db") in the context of the
      #       caller.  The handle to the opened database will be stored there.
      #
      upvar 1 $varName db

      #
      # NOTE: Start building the connection string.  The only required portion
      #       of the connection string is the database file name itself.
      #
      set connection {Data Source=${fileName}}

      #
      # NOTE: If the caller specified a journal mode, add the necessary portion
      #       of the connection string now.
      #
      if {[string length $mode] > 0} then {
        append connection {;Journal Mode=${mode}}
      }

      #
      # NOTE: If the caller specified a DateTime format, add the necessary
      #       portion of the connection string now.
      #
      if {[string length $dateTimeFormat] > 0} then {
        append connection {;DateTimeFormat=${dateTimeFormat}}
      }

      #
      # NOTE: If the caller specified a DateTimeKind, add the necessary portion
      #       of the connection string now.
      #
      if {[string length $dateTimeKind] > 0} then {
        append connection {;DateTimeKind=${dateTimeKind}}
      }

      #
      # NOTE: If the caller specified an extra payload to the connection string,
      #       append it now.
      #
      if {[string length $extra] > 0} then {
        append connection \; $extra
      }

      #
      # NOTE: Open the database connection now, placing the opaque handle value
      #       into the variable specified by the caller.
      #
      set db [sql open -type SQLite [subst $connection]]
    }

    proc cleanupDb { fileName {varName db} } {
      #
      # NOTE: Refer to the specified variable (e.g. "db") in the context of the
      #       caller.  The handle to the opened database is stored there.
      #
      upvar 1 $varName db

      #
      # NOTE: Close the connection to the database now.  This should allow us to
      #       delete the underlying database file.
      #
      if {[info exists db] && [catch {sql close $db} error]} then {
        #
        # NOTE: We somehow failed to close the database, report why.
        #
        tputs $::test_channel [appendArgs \
            "==== WARNING: failed to close database \"" $db "\", error: " \
            \n\t $error \n]
      }

      #
      # NOTE: Build the full path to the database file name.  For now, all test
      #       database files are stored in the temporary directory.
      #
      set fileName [file join [getDatabaseDirectory] [file tail $fileName]]

      if {[file exists $fileName]} then {
        #
        # NOTE: Attempt to delete the test database file now.
        #
        if {[set code [catch {file delete $fileName} error]]} then {
          #
          # NOTE: We somehow failed to delete the file, report why.
          #
          tputs $::test_channel [appendArgs \
              "==== WARNING: failed to delete database file \"" $fileName \
              "\" during cleanup, error: " \n\t $error \n]
        }
      } else {
        #
        # NOTE: The file does not exist, success!
        #
        set code 0
      }

      return $code
    }

    proc reportSQLiteResources { channel {quiet false} {collect true} } {
      #
      # NOTE: Skip all output if we are running in "quiet" mode.
      #
      if {!$quiet} then {
        tputs $channel "---- current memory in use by SQLite... "
      }

      if {[catch {object invoke -flags +NonPublic \
              System.Data.SQLite.UnsafeNativeMethods \
              sqlite3_memory_used} memory] == 0} then {
        if {!$quiet} then {
          tputs $channel [appendArgs $memory " bytes\n"]
        }
      } else {
        #
        # NOTE: Maybe the SQLite native library is unavailable?
        #
        set memory unknown

        if {!$quiet} then {
          tputs $channel [appendArgs $memory \n]
        }
      }

      set result $memory; # NOTE: Return memory in-use to caller.

      if {!$quiet} then {
        tputs $channel "---- maximum memory in use by SQLite... "
      }

      if {[catch {object invoke -flags +NonPublic \
              System.Data.SQLite.UnsafeNativeMethods \
              sqlite3_memory_highwater 0} memory] == 0} then {
        if {!$quiet} then {
          tputs $channel [appendArgs $memory " bytes\n"]
        }
      } else {
        #
        # NOTE: Maybe the SQLite native library is unavailable?
        #
        set memory unknown

        if {!$quiet} then {
          tputs $channel [appendArgs $memory \n]
        }
      }

      if {$collect} then {
        if {[catch {object invoke GC GetTotalMemory true} error]} then {
          tputs $channel [appendArgs \
              "==== WARNING: failed full garbage collection, error: " \
              \n\t $error \n]
        }
      }

      if {!$quiet} then {
        tputs $channel "---- current memory in use by the CLR... "
      }

      if {[catch {object invoke GC GetTotalMemory false} memory] == 0} then {
        if {[string is integer -strict $memory]} then {
          if {!$quiet} then {
            tputs $channel [appendArgs $memory " bytes\n"]
          }
        } else {
          set memory invalid

          if {!$quiet} then {
            tputs $channel [appendArgs $memory \n]
          }
        }
      } else {
        set memory unknown

        if {!$quiet} then {
          tputs $channel [appendArgs $memory \n]
        }
      }

      return $result
    }

    proc runSQLiteTestPrologue {} {
      #
      # NOTE: Skip running our custom prologue if the main one has been skipped.
      #
      if {![info exists ::no(prologue.eagle)]} then {
        #
        # NOTE: Skip all System.Data.SQLite related file handling (deleting,
        #       copying, and loading) if we are so instructed.
        #
        if {![info exists ::no(sqliteFiles)]} then {
          #
          # NOTE: Skip trying to delete any files if we are so instructed.
          #
          if {![info exists ::no(deleteSqliteFiles)]} then {
            tryDeleteAssembly sqlite3.dll
            tryDeleteAssembly SQLite.Interop.dll
            tryDeleteAssembly System.Data.SQLite.dll
            tryDeleteAssembly System.Data.SQLite.Linq.dll
          }

          #
          # NOTE: Skip trying to copy any files if we are so instructed.
          #
          if {![info exists ::no(copySqliteFiles)]} then {
            tryCopyAssembly sqlite3.dll
            tryCopyAssembly SQLite.Interop.dll
            tryCopyAssembly System.Data.SQLite.dll
            tryCopyAssembly System.Data.SQLite.Linq.dll
          }

          #
          # NOTE: Skip trying to load any files if we are so instructed.
          #
          if {![info exists ::no(loadSqliteFiles)]} then {
            tryLoadAssembly System.Data.SQLite.dll
            tryLoadAssembly System.Data.SQLite.Linq.dll
          }
        }

        catch {
          tputs $::test_channel [appendArgs \
              "---- file version of \"SQLite.Interop.dll\"... " \
              [file version [getBinaryFileName SQLite.Interop.dll]] \n]
        }

        catch {
          tputs $::test_channel [appendArgs \
              "---- file version of \"System.Data.SQLite.dll\"... " \
              [file version [getBinaryFileName System.Data.SQLite.dll]] \n]
        }

        catch {
          tputs $::test_channel [appendArgs \
              "---- file version of \"System.Data.SQLite.Linq.dll\"... " \
              [file version [getBinaryFileName System.Data.SQLite.Linq.dll]] \n]
        }

        set assemblies [object invoke AppDomain.CurrentDomain GetAssemblies]

        object foreach assembly $assemblies {
          if {[string match \{System.Data.SQLite* $assembly]} then {
            tputs $::test_channel [appendArgs \
                "---- found assembly: " $assembly \n]
          }
        }

        #
        # 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

        #
        # NOTE: Report the resource usage prior to running any tests.
        #
        reportSQLiteResources $::test_channel

        #
        # NOTE: Show the active test constraints.
        #
        tputs $::test_channel [appendArgs "---- constraints: " \
            [formatList [lsort [getConstraints]]] \n]
      }
    }

    proc runSQLiteTestEpilogue {} {
      #
      # NOTE: Skip running our custom epilogue if the main one has been skipped.
      #
      if {![info exists ::no(epilogue.eagle)]} then {
        #
        # NOTE: Also report the resource usage after running the tests.
        #
        reportSQLiteResources $::test_channel
      }
    }

    ###########################################################################
    ############################# END Eagle ONLY ##############################
    ###########################################################################
  }

  #
  # NOTE: Save the name of the directory containing this file.
  #
  set ::common_directory [file dirname [info script]]

  #
  # NOTE: Provide the System.Data.SQLite test package to the interpreter.
  #
  package provide System.Data.SQLite.Test 1.0
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Tests/installer.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
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
###############################################################################
#
# installer.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Setup the variables that refer to the various files required by the
#       tests in this file.
#
set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll]
set installerExeFile [getBuildFileName Installer.exe]
set testInstallVs2008LogFile [file nativename [file join $path \
    Installer_Test_Vs2008.log]]
set testInstallVs2010LogFile [file nativename [file join $path \
    Installer_Test_Vs2010.log]]
set testUninstallVs2008LogFile [file nativename [file join $path \
    Uninstaller_Test_Vs2008.log]]
set testUninstallVs2010LogFile [file nativename [file join $path \
    Uninstaller_Test_Vs2010.log]]

#
# NOTE: Setup the test constraints specific to the tests in this file.
#
if {![haveConstraint [appendArgs file_ [file tail $installerExeFile]]]} then {
  checkForFile $test_channel $installerExeFile
}

if {![haveConstraint [appendArgs file_ \
    [file tail $testInstallVs2008LogFile]]]} then {
  checkForFile $test_channel $testInstallVs2008LogFile
}

if {![haveConstraint [appendArgs file_ \
    [file tail $testInstallVs2010LogFile]]]} then {
  checkForFile $test_channel $testInstallVs2010LogFile
}

if {![haveConstraint [appendArgs file_ \
    [file tail $testUninstallVs2008LogFile]]]} then {
  checkForFile $test_channel $testUninstallVs2008LogFile
}

if {![haveConstraint [appendArgs file_ \
    [file tail $testUninstallVs2010LogFile]]]} then {
  checkForFile $test_channel $testUninstallVs2010LogFile
}

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

runTest {test installer-1.1 {installer tool / Visual Studio 2008} -setup {
  set fileName [file join [getTemporaryPath] \
      [file tail $testInstallVs2008LogFile]]

  catch {file delete $fileName}
} -body {
  set output ""

  set code [catch {
    testClrExec $installerExeFile [list -eventflags Wait -stdout output \
        -success 0] -debugPriority Lowest -tracePriority High -install true \
        -noRuntimeVersion true -noCompact true -noNetFx40 true -noVs2010 true \
        -whatIf true -verbose true -confirm true \
        -logFileName [appendArgs \" [file nativename $fileName] \"] \
        -traceFormat [appendArgs \" "#{0}: {2}" \"]
  } error]

  tlog "---- BEGIN STDOUT OUTPUT\n"
  tlog $output
  tlog "\n---- END STDOUT OUTPUT\n"

  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testInstallVs2008LogFile]]] : $error}]
} -cleanup {
  catch {file delete $fileName}

  unset -nocomplain code output error fileName
} -constraints {eagle visualStudio2008 System.Data.SQLite.dll_v2.0.50727\
file_Installer.exe file_Installer_Test_Vs2008.log} -result {0 True}}

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

runTest {test installer-1.2 {uninstaller tool / Visual Studio 2008} -setup {
  set fileName [file join [getTemporaryPath] \
      [file tail $testUninstallVs2008LogFile]]

  catch {file delete $fileName}
} -body {
  set output ""

  set code [catch {
    testClrExec $installerExeFile [list -eventflags Wait -stdout output \
        -success 0] -debugPriority Lowest -tracePriority High -install false \
        -noRuntimeVersion true -noCompact true -noNetFx40 true -noVs2010 true \
        -whatIf true -verbose true -confirm true \
        -logFileName [appendArgs \" [file nativename $fileName] \"] \
        -traceFormat [appendArgs \" "#{0}: {2}" \"]
  } error]

  tlog "---- BEGIN STDOUT OUTPUT\n"
  tlog $output
  tlog "\n---- END STDOUT OUTPUT\n"

  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testUninstallVs2008LogFile]]] : $error}]
} -cleanup {
  catch {file delete $fileName}

  unset -nocomplain code output error fileName
} -constraints {eagle visualStudio2008 System.Data.SQLite.dll_v2.0.50727\
file_Installer.exe file_Uninstaller_Test_Vs2008.log} -result {0 True}}

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

runTest {test installer-1.3 {installer tool / Visual Studio 2010} -setup {
  set fileName [file join [getTemporaryPath] \
      [file tail $testInstallVs2010LogFile]]

  catch {file delete $fileName}
} -body {
  set output ""

  set code [catch {
    testClrExec $installerExeFile [list -eventflags Wait -stdout output \
        -success 0] -debugPriority Lowest -tracePriority High -install true \
        -noRuntimeVersion true -noCompact true -noNetFx20 true -noVs2008 true \
        -whatIf true -verbose true -confirm true \
        -logFileName [appendArgs \" [file nativename $fileName] \"] \
        -traceFormat [appendArgs \" "#{0}: {2}" \"]
  } error]

  tlog "---- BEGIN STDOUT OUTPUT\n"
  tlog $output
  tlog "\n---- END STDOUT OUTPUT\n"

  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testInstallVs2010LogFile]]] : $error}]
} -cleanup {
  catch {file delete $fileName}

  unset -nocomplain code output error fileName
} -constraints {eagle visualStudio2010 System.Data.SQLite.dll_v4.0.30319\
file_Installer.exe file_Installer_Test_Vs2010.log} -result {0 True}}

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

runTest {test installer-1.4 {uninstaller tool / Visual Studio 2010} -setup {
  set fileName [file join [getTemporaryPath] \
      [file tail $testUninstallVs2010LogFile]]

  catch {file delete $fileName}
} -body {
  set output ""

  set code [catch {
    testClrExec $installerExeFile [list -eventflags Wait -stdout output \
        -success 0] -debugPriority Lowest -tracePriority High -install false \
        -noRuntimeVersion true -noCompact true -noNetFx20 true -noVs2008 true \
        -whatIf true -verbose true -confirm true \
        -logFileName [appendArgs \" [file nativename $fileName] \"] \
        -traceFormat [appendArgs \" "#{0}: {2}" \"]
  } error]

  tlog "---- BEGIN STDOUT OUTPUT\n"
  tlog $output
  tlog "\n---- END STDOUT OUTPUT\n"

  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testUninstallVs2010LogFile]]] : $error}]
} -cleanup {
  catch {file delete $fileName}

  unset -nocomplain code output error fileName
} -constraints {eagle visualStudio2010 System.Data.SQLite.dll_v4.0.30319\
file_Installer.exe file_Uninstaller_Test_Vs2010.log} -result {0 True}}

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

unset -nocomplain testUninstallVs2010LogFile testUninstallVs2008LogFile \
    testInstallVs2010LogFile testInstallVs2008LogFile installerExeFile \
    systemDataSQLiteDllFile

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































Deleted Tests/nonWal.db.

cannot compute difference between binary files

Deleted Tests/pkgIndex.eagle.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
###############################################################################
#
# pkgIndex.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

if {![package vsatisfies [package provide Tcl] 8.4]} {return}
if {![package vsatisfies [package provide Eagle] 1.0]} {return}

package ifneeded System.Data.SQLite.Test 1.0 \
    [list source [file join $dir common.eagle]]
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted Tests/testlinq.out.
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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
WX3 6FW
87110
8010
8010
24100
4980
05487-020
50739
59000
1010
T2F 8M4
T2F 8M4
90110
31000
05442-030
97827
90110
1734
01307
1204
08737-363
02389-673
10100
04876-786
H1J 1C3
31000
8022
5020
42100

8010
T2F 8M4
82520
1756
S-844 67
WX1 6LT
67000
90110
44087
H1J 1C3
83720
99508
8010
42100
S-958 22
S-958 22
44087
02389-890
1010
67000
69004
01307
83720
CO7 6JX
31000
90110
14776
14776
B-6000
69004
S-844 67
3508
WX1 6LT
B-6000
1675
8200
05432-043
24100
14776
98124
13008
EC2 5NT
OX15 4NB
PO31 7PJ
05033
B-6000
5022
1756
69004
87110
59000
02389-890
99362
98124
EC2 5NT
4980
5022
05487-020
80805
5020
5022
1675
T2F 8M4
31000
05432-043
V3F 2K1
05634-030
60528
5022
3508
31000
68306
05033

98124
H1J 1C3
14776
05023
50739
68306
83720
13008
05442-030
70563
8010
01307

SW7 1RZ
05033
3012
4110
1010
60528
OX15 4NB
S-958 22
13008
90110
01307
97403
B-1180
5020
1010
WX3 6FW
S-844 67
60528
05023
60528
1204
EC2 5NT
EC2 5NT
01307
05454-876
14776
3508
97219
99362
69004
OX15 4NB
44087
01307
41101
1675
5022
90110
50739
83720
1734
60528
CO7 6JX
67000
80805
S-844 67
42100
02389-890
87110
H1J 1C3
67000

8022
87110
H1J 1C3
8010
S-958 22
05023
98034
04179
05033
98034
EC2 5NT
94117
50739
05442-030
68306
90110
67000
08737-363
42100
02389-673
01307
97403
H1J 1C3
8200
60528
60528
99508
8010
98124
5020
87110
EC2 5NT
97827
5022
8200
83720
1675
H1J 1C3
05634-030
83720
44087
44000
31000
01-012
83720
5022
68306
21240
97403
97403
H1J 1C3
H1J 1C3
V3F 2K1
PO31 7PJ
02389-890
80805
59801
05021
S-958 22
83720
67000
41101
14776
31000
70563
8010
59000
24100
90110
05487-020
4980
4110
70563
5022
1734
12209
08737-363
05454-876

02389-673
02389-890
B-1180
05442-030
70563
04876-786
80805
S-958 22
42100
97403
83720
01307
05487-020
97827

97219
13008
1675
97219
1204
8010
70563
1734
80805
44000
S-958 22
21240
PO31 7PJ
80805
05033
05023
83720
67000
99508
97403
05023
44000
50739
04876-786
5020

8200
S-958 22
05454-876
01307
12209
98124
01307
21240
98124
4980
8010
04179
83720

12209
S-844 67
05487-020
5022
99508
CO7 6JX
97201
04876-786
10100
83720

83720
83720
13008
1010
80805
14776
94117
02389-673
01307
83720
98124
H1J 1C3
05442-030
WX3 6FW
42100
05487-020
4980
13008
3012
13008
S-958 22
04876-786
94117

51100
75016
51100
98124
CO7 6JX
T2F 8M4
CO7 6JX
8200
01307
3012
5020
83720
PO31 7PJ
90110
1204
SW7 1RZ
10100
24100
13008
82520
83720
1204
05021
B-1180
87110
S-844 67
59000
8010
01307
50739
B-6000
CO7 6JX
8200
05454-876
8010
60528
8010
S-844 67
59801
8010
04876-786
S-958 22
04179
3508
90110
1010
05454-876
24100
1081
05487-020
31000
01307
59000
04876-786
80805
01-012
CO7 6JX
02389-673
8010
5022
52066
PO31 7PJ
14776
OX15 4NB
28023
1734
08737-363
OX15 4NB
97201
69004
10100
Around the Horn
B's Beverages
Consolidated Holdings
Eastern Connection
North/South
Seven Seas Imports
Around the Horn
7/4/1996 12:00:00 AM
7/5/1996 12:00:00 AM
7/8/1996 12:00:00 AM
7/8/1996 12:00:00 AM
7/9/1996 12:00:00 AM
7/10/1996 12:00:00 AM
7/11/1996 12:00:00 AM
7/12/1996 12:00:00 AM
7/15/1996 12:00:00 AM
7/16/1996 12:00:00 AM
7/17/1996 12:00:00 AM
7/18/1996 12:00:00 AM
7/19/1996 12:00:00 AM
7/19/1996 12:00:00 AM
7/22/1996 12:00:00 AM
7/23/1996 12:00:00 AM
7/24/1996 12:00:00 AM
7/25/1996 12:00:00 AM
7/26/1996 12:00:00 AM
7/29/1996 12:00:00 AM
7/30/1996 12:00:00 AM
7/31/1996 12:00:00 AM
8/1/1996 12:00:00 AM
8/1/1996 12:00:00 AM
8/2/1996 12:00:00 AM
8/5/1996 12:00:00 AM
8/6/1996 12:00:00 AM
8/7/1996 12:00:00 AM
8/8/1996 12:00:00 AM
8/9/1996 12:00:00 AM
8/12/1996 12:00:00 AM
8/13/1996 12:00:00 AM
8/14/1996 12:00:00 AM
8/14/1996 12:00:00 AM
8/15/1996 12:00:00 AM
8/16/1996 12:00:00 AM
8/19/1996 12:00:00 AM
8/20/1996 12:00:00 AM
8/21/1996 12:00:00 AM
8/22/1996 12:00:00 AM
8/23/1996 12:00:00 AM
8/26/1996 12:00:00 AM
8/27/1996 12:00:00 AM
8/27/1996 12:00:00 AM
8/28/1996 12:00:00 AM
8/29/1996 12:00:00 AM
8/30/1996 12:00:00 AM
9/2/1996 12:00:00 AM
9/3/1996 12:00:00 AM
9/4/1996 12:00:00 AM
9/5/1996 12:00:00 AM
9/6/1996 12:00:00 AM
9/9/1996 12:00:00 AM
9/9/1996 12:00:00 AM
9/10/1996 12:00:00 AM
9/11/1996 12:00:00 AM
9/12/1996 12:00:00 AM
9/13/1996 12:00:00 AM
9/16/1996 12:00:00 AM
9/17/1996 12:00:00 AM
9/18/1996 12:00:00 AM
9/19/1996 12:00:00 AM
9/20/1996 12:00:00 AM
9/20/1996 12:00:00 AM
9/23/1996 12:00:00 AM
9/24/1996 12:00:00 AM
9/25/1996 12:00:00 AM
9/26/1996 12:00:00 AM
9/27/1996 12:00:00 AM
9/30/1996 12:00:00 AM
10/1/1996 12:00:00 AM
10/2/1996 12:00:00 AM
10/3/1996 12:00:00 AM
10/3/1996 12:00:00 AM
10/4/1996 12:00:00 AM
10/7/1996 12:00:00 AM
10/8/1996 12:00:00 AM
10/9/1996 12:00:00 AM
10/10/1996 12:00:00 AM
10/11/1996 12:00:00 AM
10/14/1996 12:00:00 AM
10/15/1996 12:00:00 AM
10/16/1996 12:00:00 AM
10/16/1996 12:00:00 AM
10/17/1996 12:00:00 AM
10/18/1996 12:00:00 AM
10/21/1996 12:00:00 AM
10/22/1996 12:00:00 AM
10/23/1996 12:00:00 AM
10/24/1996 12:00:00 AM
10/25/1996 12:00:00 AM
10/28/1996 12:00:00 AM
10/29/1996 12:00:00 AM
10/29/1996 12:00:00 AM
10/30/1996 12:00:00 AM
10/31/1996 12:00:00 AM
11/1/1996 12:00:00 AM
11/4/1996 12:00:00 AM
11/5/1996 12:00:00 AM
11/6/1996 12:00:00 AM
11/7/1996 12:00:00 AM
11/8/1996 12:00:00 AM
11/11/1996 12:00:00 AM
11/11/1996 12:00:00 AM
11/12/1996 12:00:00 AM
11/13/1996 12:00:00 AM
11/14/1996 12:00:00 AM
11/15/1996 12:00:00 AM
11/18/1996 12:00:00 AM
11/19/1996 12:00:00 AM
11/20/1996 12:00:00 AM
11/21/1996 12:00:00 AM
11/22/1996 12:00:00 AM
11/22/1996 12:00:00 AM
11/25/1996 12:00:00 AM
11/26/1996 12:00:00 AM
11/26/1996 12:00:00 AM
11/27/1996 12:00:00 AM
11/28/1996 12:00:00 AM
11/28/1996 12:00:00 AM
11/29/1996 12:00:00 AM
12/2/1996 12:00:00 AM
12/3/1996 12:00:00 AM
12/3/1996 12:00:00 AM
12/4/1996 12:00:00 AM
12/5/1996 12:00:00 AM
12/5/1996 12:00:00 AM
12/6/1996 12:00:00 AM
12/9/1996 12:00:00 AM
12/9/1996 12:00:00 AM
12/10/1996 12:00:00 AM
12/11/1996 12:00:00 AM
12/12/1996 12:00:00 AM
12/12/1996 12:00:00 AM
12/13/1996 12:00:00 AM
12/16/1996 12:00:00 AM
12/16/1996 12:00:00 AM
12/17/1996 12:00:00 AM
12/18/1996 12:00:00 AM
12/18/1996 12:00:00 AM
12/19/1996 12:00:00 AM
12/20/1996 12:00:00 AM
12/23/1996 12:00:00 AM
12/23/1996 12:00:00 AM
12/24/1996 12:00:00 AM
12/25/1996 12:00:00 AM
12/25/1996 12:00:00 AM
12/26/1996 12:00:00 AM
12/27/1996 12:00:00 AM
12/27/1996 12:00:00 AM
12/30/1996 12:00:00 AM
12/31/1996 12:00:00 AM
26
26.78
70.29
9.8
41.89
24.39
257.26
18.44
13.55
27.36
145.04
55.92
299.09
69.19
65.06
176.48
27.2
65.53
Alfreds Futterkiste
Ana Trujillo Emparedados y helados
Antonio Moreno Taquería
Around the Horn
Berglunds snabbköp
Blauer See Delikatessen
Blondesddsl père et fils
Bólido Comidas preparadas
Bon app'
Bottom-Dollar Markets
B's Beverages
Cactus Comidas para llevar
Chop-suey Chinese
Comércio Mineiro
Consolidated Holdings
Drachenblut Delikatessen
Du monde entier
Eastern Connection
Ernst Handel
Familia Arquibaldo
Folies gourmandes
Folk och fä HB
Frankenversand
France restauration
Franchi S.p.A.
Furia Bacalhau e Frutos do Mar
Galería del gastrónomo
Godos Cocina Típica
Gourmet Lanchonetes
Great Lakes Food Market
GROSELLA-Restaurante
Hanari Carnes
HILARION-Abastos
Hungry Coyote Import Store
Hungry Owl All-Night Grocers
Island Trading
Königlich Essen
La maison d'Asie
Laughing Bacchus Wine Cellars
Lazy K Kountry Store
Lehmanns Marktstand
Let's Stop N Shop
LILA-Supermercado
LINO-Delicateses
Lonesome Pine Restaurant
Magazzini Alimentari Riuniti
Maison Dewey
Mère Paillarde
Morgenstern Gesundkost
North/South
Océano Atlántico Ltda.
Old World Delicatessen
Ottilies Käseladen
Pericles Comidas clásicas
Piccolo und mehr
Princesa Isabel Vinhos
Que Delícia
Queen Cozinha
QUICK-Stop
Rancho grande
Rattlesnake Canyon Grocery
Reggiani Caseifici
Ricardo Adocicados
Richter Supermarkt
Santé Gourmet
Save-a-lot Markets
Seven Seas Imports
Simons bistro
Spécialités du monde
Split Rail Beer & Ale
Suprêmes délices
The Big Cheese
The Cracker Box
Toms Spezialitäten
Tortuga Restaurante
Tradição Hipermercados
Trail's Head Gourmet Provisioners
Vaffeljernet
Victuailles en stock
Vins et alcools Chevalier
Die Wandernde Kuh
Wartian Herkku
Wellington Importadora
White Clover Markets
Wilman Kala
87110
8010
8010
24100
4980
05487-020
50739
59000
1010
T2F 8M4
T2F 8M4
90110
31000
05442-030
97827
90110
1734
01307
1204
08737-363
02389-673
10100
04876-786
H1J 1C3
31000
8022
5020
42100

8010
T2F 8M4
82520
1756
S-844 67
67000
90110
44087
H1J 1C3
83720
99508
8010
42100
S-958 22
S-958 22
44087
02389-890
1010
67000
69004
01307
83720
31000
90110
14776
14776
B-6000
69004
S-844 67
3508
B-6000
1675
8200
05432-043
24100
14776
98124
13008
B-6000
5022
1756
69004
87110
59000
02389-890
99362
98124
4980
5022
05487-020
80805
5020
5022
1675
T2F 8M4
31000
05432-043
V3F 2K1
05634-030
60528
5022
3508
31000
68306

98124
H1J 1C3
14776
50739
68306
83720
13008
05442-030
70563
8010
01307

3012
4110
1010
60528
S-958 22
13008
90110
01307
97403
B-1180
5020
1010
S-844 67
60528
60528
1204
01307
05454-876
14776
3508
97219
99362
69004
44087
01307
41101
1675
5022
90110
50739
83720
1734
60528
67000
80805
S-844 67
42100
02389-890
87110
H1J 1C3
67000

8022
87110
H1J 1C3
8010
S-958 22
98034
04179
98034
94117
50739
05442-030
68306
90110
67000
08737-363
42100
02389-673
01307
97403
H1J 1C3
8200
60528
60528
99508
8010
98124
5020
87110
97827
5022
8200
83720
1675
H1J 1C3
05634-030
83720
44087
44000
31000
83720
5022
68306
21240
97403
97403
H1J 1C3
H1J 1C3
V3F 2K1
02389-890
80805
59801
S-958 22
83720
67000
41101
14776
31000
70563
8010
59000
24100
90110
05487-020
4980
4110
70563
5022
1734
12209
08737-363
05454-876

02389-673
02389-890
B-1180
05442-030
70563
04876-786
80805
S-958 22
42100
97403
83720
01307
05487-020
97827

97219
13008
1675
97219
1204
8010
70563
1734
80805
44000
S-958 22
21240
80805
83720
67000
99508
97403
44000
50739
04876-786
5020

8200
S-958 22
05454-876
01307
12209
98124
01307
21240
98124
4980
8010
04179
83720

12209
S-844 67
05487-020
5022
99508
97201
04876-786
10100
83720

83720
83720
13008
1010
80805
14776
94117
02389-673
01307
83720
98124
H1J 1C3
05442-030
42100
05487-020
4980
13008
3012
13008
S-958 22
04876-786
94117

51100
75016
51100
98124
T2F 8M4
8200
01307
3012
5020
83720
90110
1204
10100
24100
13008
82520
83720
1204
B-1180
87110
S-844 67
59000
8010
01307
50739
B-6000
8200
05454-876
8010
60528
8010
S-844 67
59801
8010
04876-786
S-958 22
04179
3508
90110
1010
05454-876
24100
1081
05487-020
31000
01307
59000
04876-786
80805
02389-673
8010
5022
52066
14776
28023
1734
08737-363
97201
69004
10100
51100
44087
05454-876
69004
B-6000
05454-876
3012
1204
08737-363
5022
8010
05022
50739
02389-673
87110
8010
S-844 67
67000
90110
80805
1081
98124
90110
82520
87110
01307
51100
24100
05033
04179
S-958 22
60528
S-958 22
28001
28001
3508
60528
01307
01307
02389-890
42100
EC2 5NT
05432-043
02389-673
05634-030
05033
87110
51100
3508
67000

02389-890
24100
70563
B-6000
41101
05033
99508
28001
97219
05021

97201
44000
70563
01307
87110
PO31 7PJ
87110
97219
PO31 7PJ
05033
90110
PO31 7PJ
05033
14776
83720
14776
28023
S-844 67
1675
82520
3508
13008
H1J 1C3
90110
69004

1756
80805
99508
H1J 1C3
13008
1734
80805
60528
98124
01307
87110
05442-030
70563
82520
31000
8010
1675
5020
05033
CO7 6JX
70563
3508
31000
OX15 4NB
67000
01307
13008
52066
WX3 6FW
05023
8022
8200
8010
82520
3012
31000
05487-020

01-012
97827
H1J 1C3
OX15 4NB
S-844 67
02389-673

3508
8010
CO7 6JX
S-958 22
82520
05442-030
4110
OX15 4NB
T2F 8M4
8010
52066
5020
83720
97827
5022
80805
1756
83720
8200
WX3 6FW
87110
8010
8010
24100
4980
05487-020
50739
59000
1010
T2F 8M4
T2F 8M4
90110
31000
05442-030
97827
90110
1734
01307
1204
08737-363
02389-673
10100
04876-786
H1J 1C3
31000
8022
5020
42100

8010
T2F 8M4
82520
1756
S-844 67
WX1 6LT
67000
90110
44087
H1J 1C3
83720
99508
8010
42100
S-958 22
S-958 22
44087
02389-890
1010
67000
69004
01307
83720
CO7 6JX
31000
90110
14776
14776
B-6000
69004
S-844 67
3508
WX1 6LT
B-6000
1675
8200
05432-043
24100
14776
98124
13008
EC2 5NT
OX15 4NB
PO31 7PJ
05033
B-6000
5022
1756
69004
87110
59000
02389-890
99362
98124
EC2 5NT
4980
5022
05487-020
80805
5020
5022
1675
T2F 8M4
31000
05432-043
V3F 2K1
05634-030
60528
5022
3508
31000
68306
05033

98124
H1J 1C3
14776
05023
50739
68306
83720
13008
05442-030
70563
8010
01307

SW7 1RZ
05033
3012
4110
1010
60528
OX15 4NB
S-958 22
13008
90110
01307
97403
B-1180
5020
1010
WX3 6FW
S-844 67
60528
05023
60528
1204
EC2 5NT
EC2 5NT
01307
05454-876
14776
3508
97219
99362
69004
OX15 4NB
44087
01307
41101
1675
5022
90110
50739
83720
1734
60528
CO7 6JX
67000
80805
S-844 67
42100
02389-890
87110
H1J 1C3
67000

8022
87110
H1J 1C3
8010
S-958 22
05023
98034
04179
05033
98034
EC2 5NT
94117
50739
05442-030
68306
90110
67000
08737-363
42100
02389-673
01307
97403
H1J 1C3
8200
60528
60528
99508
8010
98124
5020
87110
EC2 5NT
97827
5022
8200
83720
1675
H1J 1C3
05634-030
83720
44087
44000
31000
01-012
83720
5022
68306
21240
97403
97403
H1J 1C3
H1J 1C3
V3F 2K1
PO31 7PJ
02389-890
80805
59801
05021
S-958 22
83720
67000
41101
14776
31000
70563
8010
59000
24100
90110
05487-020
4980
4110
70563
5022
1734
12209
08737-363
05454-876

02389-673
02389-890
B-1180
05442-030
70563
04876-786
80805
S-958 22
42100
97403
83720
01307
05487-020
97827

97219
13008
1675
97219
1204
8010
70563
1734
80805
44000
S-958 22
21240
PO31 7PJ
80805
05033
05023
83720
67000
99508
97403
05023
44000
50739
04876-786
5020

8200
S-958 22
05454-876
01307
12209
98124
01307
21240
98124
4980
8010
04179
83720

12209
S-844 67
05487-020
5022
99508
CO7 6JX
97201
04876-786
10100
83720

83720
83720
13008
1010
80805
14776
94117
02389-673
01307
83720
98124
H1J 1C3
05442-030
WX3 6FW
42100
05487-020
4980
13008
3012
13008
S-958 22
04876-786
94117

51100
75016
51100
98124
CO7 6JX
T2F 8M4
CO7 6JX
8200
01307
3012
5020
83720
PO31 7PJ
90110
1204
SW7 1RZ
10100
24100
13008
82520
83720
1204
05021
B-1180
87110
S-844 67
59000
8010
01307
50739
B-6000
CO7 6JX
8200
05454-876
8010
60528
8010
S-844 67
59801
8010
04876-786
S-958 22
04179
3508
90110
1010
05454-876
24100
1081
05487-020
31000
01307
59000
04876-786
80805
01-012
CO7 6JX
02389-673
8010
5022
52066
PO31 7PJ
14776
OX15 4NB
28023
1734
08737-363
OX15 4NB
97201
69004
10100
99508
08737-363
V3F 2K1
4980
42100
02389-890
69004
83720
97403
14776
24100
1010
87110
82520
98034
3508
S-844 67
52066
67000
13008
1010
PO31 7PJ
05634-030
4110
31000
50739
05634-030
12209
8010
S-958 22
4980
05634-030
4980
B-6000
05033
69004
5020
01307
B-6000
83720
WX1 6LT
14776
69004
02389-890
87110
68306
8010
99508
05023
S-958 22
78000
80805
44000
98124
60528
5022
CO7 6JX
01307
S-958 22
97219
05487-020
OX15 4NB
01-012
13008
41101
21240
41101
S-958 22
13008
02389-890
01307
21240
S-844 67
1010
83720
97219
94117
B-6000
05454-876
8022
41101
87110
44000
60528
B-1180
14776
83720
8010
B-1180

1010
3508
08737-363
5022
S-844 67
05454-876
98124
08737-363
01-012
75016
42100
4110
21240
41101

05487-020
05487-020
05033
1010
28001
T2F 8M4
4980
CO7 6JX
8200
05454-876
31000
S-958 22
05454-876
05021
78000
8022
80805
B-6000
1204
13008
PO31 7PJ
60528
08737-363
97403
1010
01307
24100
13008
83720
42100
EC2 5NT
T2F 8M4
04179
8200
EC2 5NT
41101
T2F 8M4
24100
1204
12209
CO7 6JX
4980
S-844 67
68306
5022
1010
04876-786
5022
05487-020
01307
1675
75016
99508
3012
44087
8010
05432-043
28023
44000
78000
78000
82520
T2F 8M4
5022
S-844 67
B-1180
8010
S-844 67
05454-876
T2F 8M4
83720
83720

1010
WX3 6FW
87110
02389-673
8010
01307
97201
S-844 67
8200
05033
01307
3508
01-012
50739
87110
S-844 67
83720
59801
B-1180
21240
97403
1756
8010
41101
42100
12209
80805
28001
4980
4110
CO7 6JX
8010
97219
1010
50739
01307
05454-876
EC2 5NT
WX3 6FW
90110
10100
T2F 8M4
14776
3012
83720
83720
98124
1204
99508
B-6000
52066
41101
B-6000
4980
97403
3012
05432-043
75016
01-012
T2F 8M4
70563
WX3 6FW
T2F 8M4
04876-786
S-844 67
31000
05454-876
5020
1010
5022
WX3 6FW
SW7 1RZ
68306
02389-890
10100
97403
42100

83720
3508
98124
52066
05487-020
05033
60528
3508
8010
05033
1734
1204
13008
87110
Chai
Chang
Chef Anton's Cajun Seasoning
Chef Anton's Gumbo Mix
Uncle Bob's Organic Dried Pears
Guaraná Fantástica
Gumbär Gummibärchen
Rössle Sauerkraut
Thüringer Rostbratwurst
Nord-Ost Matjeshering
Sasquatch Ale
Steeleye Stout
Boston Crab Meat
Jack's New England Clam Chowder
Tarte au sucre
Wimmers gute Semmelknödel
Louisiana Fiery Hot Pepper Sauce
Röd Kaviar
Rhönbräu Klosterbier
Original Frankfurter grüne Soße
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Tests/tkt-00f86f9739.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
###############################################################################
#
# tkt-00f86f9739.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Setup the variables that refer to the various files required by the
#       tests in this file.
#
set testLinqExeFile [getBuildFileName testlinq.exe]
set northwindEfDbFile [file nativename [file join [file dirname $path] \
    testlinq northwindEF.db]]

#
# NOTE: Setup the test constraints specific to the tests in this file.
#
if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then {
  checkForFile $test_channel $testLinqExeFile
}

if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then {
  checkForFile $test_channel $northwindEfDbFile
}

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

runTest {test tkt-00f86f9739-1.1 {LINQ with StartsWith} -body {
  set result [list]

  foreach value [list "" a b z 1+1 don notthere] {
    set output ""

    set code [catch {
      testClrExec $testLinqExeFile [list -eventflags Wait -directory \
          [file dirname $testLinqExeFile] -nocarriagereturns -stdout output \
          -success 0] -startsWith $value
    } error]

    tlog "---- BEGIN STDOUT OUTPUT\n"
    tlog $output
    tlog "\n---- END STDOUT OUTPUT\n"

    lappend result $code

    if {$code == 0} then {
      lappend result [string trim $output]
    } else {
      lappend result [string trim $error]
    }
  }

  set result
} -cleanup {
  unset -nocomplain code output error result value
} -constraints {eagle monoToDo 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 {}}}

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

unset -nocomplain testLinqExeFile northwindEfDbFile

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted Tests/tkt-0d5b1ef362.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
###############################################################################
#
# tkt-0d5b1ef362.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# HACK: This test reads the private "_domainUnload" field of the AppDomain
#       class.  This is non-portable and will not work on Mono.  Also, this
#       may not work on versions of the .NET Framework after 4.0.
#
runTest {test tkt-0d5b1ef362-1.1 {SQLiteLog.DomainUnload event} -setup \
    [getAppDomainPreamble] -body {
  #
  # NOTE: Grab the number of DomainUnload handlers prior to doing anything
  #       else.
  #
  set x [object invoke -flags +NonPublic \
      AppDomain.CurrentDomain._domainUnload.GetInvocationList Length]

  package require EagleLibrary
  package require EagleTest
  package require System.Data.SQLite.Test

  object load -loadtype File [file join [getBinaryDirectory] \
      System.Data.SQLite.dll]

  for {set i 1} {$i < 3} {incr i} {
    set connection($i) [object create System.Data.SQLite.SQLiteConnection ""]
  }

  #
  # NOTE: Now, grab the number of DomainUnload handlers after creating the
  #       connections.
  #
  set y [object invoke -flags +NonPublic \
      AppDomain.CurrentDomain._domainUnload.GetInvocationList Length]

  #
  # NOTE: Make sure that no DomainUnload handlers were actually added while we
  #       created the two connections (i.e. because we are not in the default
  #       application domain).
  #
  expr {$x == $y}
} -cleanup {
  unset -nocomplain connection i x y
} -constraints {eagle dotNet monoBug28 compile.ISOLATED_INTERPRETERS SQLite\
System.Data.SQLite} -isolationLevel AppDomain -result {True}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































Deleted Tests/tkt-201128cc88.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
###############################################################################
#
# tkt-201128cc88.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-201128cc88-1.1 {custom function with byte[] arg} -setup {
  set fileName tkt-201128cc88-1.1.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      \[SQLiteFunction(Name = "Base64", FuncType = FunctionType.Scalar)\]
      public class Test${id} : SQLiteFunction
      {
        public override object Invoke(object\[\] args)
        {
          if (args == null)
            return null;

          if (args.Length != 1)
            return new ArgumentException(String.Format(
              "need exactly one argument, got {0}", args.Length));

          object arg = args\[0\];

          if (arg == null)
            return String.Empty;

          Type type = arg.GetType();

          if (type == typeof(DBNull))
            return String.Empty;

          if (type != typeof(byte\[\]))
            return new ArgumentException(String.Format(
              "argument must be byte array, got {0}", type));

          return Convert.ToBase64String((byte\[\]) arg);
        }

        public static void Main()
        {
          SQLiteFunction.RegisterFunction(typeof(Test${id}));
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  #
  # NOTE: Compile the C# code (above) to register the custom SQLite function
  #       and then open the database for this test case and attempt to execute
  #       the function.  Normally, we would open the database in the test setup
  #       phase; however, that will not work correctly because newly registered
  #       functions are only picked up and used by databases opened after they
  #       have been registered.
  #
  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result [setupDb $fileName] \
      [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 \{\}\
System#Data#SQLite#SQLiteConnection#\d+ \{\} \{\} Zm9v$}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































Deleted Tests/tkt-2c630bffa7.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
###############################################################################
#
# tkt-2c630bffa7.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

set y [list -1.79769e308 -3.40282e038 -1 0 1 3.40282e038 1.79769e308]

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

runTest {test tkt-2c630bffa7-1.1 {range of REAL type} -setup {
  setupDb [set fileName tkt-2c630bffa7-1.1.db]
} -body {
  sql execute $db "CREATE TABLE t1(x INTEGER, y REAL);"

  for {set x 0} {$x < [llength $y]} {incr x} {
    sql execute $db \
        "INSERT INTO t1 (x, y) VALUES($x, [lindex $y $x]);"
  }

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

  unset -nocomplain x result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{0 -1.79769E+308 1 -3.40282E+38 2 -1 3 0 4 1 5 3.40282E+38 6 1.79769E+308}}

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

runTest {test tkt-2c630bffa7-1.2 {range of FLOAT type} -setup {
  setupDb [set fileName tkt-2c630bffa7-1.2.db]
} -body {
  sql execute $db "CREATE TABLE t2(x INTEGER, y FLOAT);"

  for {set x 0} {$x < [llength $y]} {incr x} {
    sql execute $db \
        "INSERT INTO t2 (x, y) VALUES($x, [lindex $y $x]);"
  }

  set result [sql execute -execute reader -format list $db \
      "SELECT x, y FROM t2 ORDER BY x;"]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain x result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{0 -1.79769E+308 1 -3.40282E+38 2 -1 3 0 4 1 5 3.40282E+38 6 1.79769E+308}}

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

runTest {test tkt-2c630bffa7-1.3 {range of DOUBLE type} -setup {
  setupDb [set fileName tkt-2c630bffa7-1.3.db]
} -body {
  sql execute $db "CREATE TABLE t3(x INTEGER, y DOUBLE);"

  for {set x 0} {$x < [llength $y]} {incr x} {
    sql execute $db \
        "INSERT INTO t3 (x, y) VALUES($x, [lindex $y $x]);"
  }

  set result [sql execute -execute reader -format list $db \
      "SELECT x, y FROM t3 ORDER BY x;"]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain x result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{0 -1.79769E+308 1 -3.40282E+38 2 -1 3 0 4 1 5 3.40282E+38 6 1.79769E+308}}

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

unset -nocomplain y

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted Tests/tkt-2ce0870fad.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
###############################################################################
#
# tkt-2ce0870fad.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Make sure that SQLite core library is completely shutdown prior to
#       starting any of the tests in this file.
#
if {[haveConstraint SQLite]} then {
  object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \
      sqlite3_shutdown
}

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

for {set i 1} {$i < 3} {incr i} {
  runTest {test [appendArgs tkt-2ce0870fad-1. $i] {logging setup} -setup \
      [getAppDomainPreamble {
    set i {$i}
    set appDomainId($i) {[object invoke AppDomain.CurrentDomain Id]}
    set fileName {[appendArgs tkt-2ce0870fad-1. $i .db]}

    #
    # NOTE: Keep track of whether or not the global test year and configuration
    #       variables already exist in the primary application domain before the
    #       test.  If not, we will need to unset them after the test.
    #
    set hadTestYear {[info exists ::test_year]}
    set hadTestConfiguration {[info exists ::test_configuration]}
  }] -body {
    set appDomainId(3) [object invoke AppDomain.CurrentDomain Id]

    package require EagleLibrary
    package require EagleTest
    package require System.Data.SQLite.Test

    set assembly [object load -loadtype File [file join [getBinaryDirectory] \
        System.Data.SQLite.dll]]

    object invoke System.Data.SQLite.SQLiteLog Initialize

    list $appDomainId($i) $appDomainId(3) [expr {$i == 1 ? \
        $appDomainId($i) != $appDomainId(3) : \
        $appDomainId($i) == $appDomainId(3)}] [setupDb $fileName]
  } -cleanup {
    cleanupDb $fileName

    if {!$hadTestConfiguration} then {
      unset -nocomplain ::test_configuration
    }

    if {!$hadTestYear} then {
      unset -nocomplain ::test_year
    }

    #
    # NOTE: If this is the primary application domain, skip unsetting the
    #       loop variable because the surrounding [for] command still needs
    #       it.
    #
    if {$i <= 1} then {
      unset -nocomplain i
    }

    unset -nocomplain assembly appDomainId db fileName hadTestConfiguration \
        hadTestYear
  } -constraints {eagle monoBug28 command.sql compile.DATA\
compile.ISOLATED_INTERPRETERS SQLite System.Data.SQLite} -isolationLevel \
[expr {$i == 1 ? "AppDomain" : "Default"}] -match regexp -result \
{^\d+ \d+ True System#Data#SQLite#SQLiteConnection#\d+$}}
}

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

unset -nocomplain i

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted Tests/tkt-343d392b51.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
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
###############################################################################
#
# tkt-343d392b51.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

set dateTimeFormats [list "" Ticks ISO8601 JulianDay UnixEpoch]

for {set i 1} {$i < 5} {incr i} {
  set dateTimeFormat [lindex $dateTimeFormats $i]

  runTest {test [appendArgs tkt-343d392b51-1. $i] [subst {DateTime\
      binding $dateTimeFormat format}] -setup {
    setupDb [set fileName [appendArgs tkt-343d392b51-1. $i .db]] "" \
        $dateTimeFormat Utc

    set dateTime "4 October, 2011 3:27:50 PM GMT"
  } -body {
    sql execute $db "CREATE TABLE t1(x DATETIME);"

    set paramDateTime1 [clock format [clock scan $dateTime] -format \
        [getDateTimeFormat] -gmt true]

    switch -exact -- $dateTimeFormat {
      Ticks {
        set paramDateTime1 [object invoke -alias DateTime Parse $paramDateTime1]
        set paramDateTime1 [$paramDateTime1 ToUniversalTime.Ticks]
        set paramDateTime2 $paramDateTime1
      }
      ISO8601 {
        set paramDateTime2 [appendArgs ' $paramDateTime1 ']
      }
      JulianDay {
        set paramDateTime1 [object invoke -alias DateTime Parse $paramDateTime1]
        set paramDateTime1 [$paramDateTime1 -alias ToUniversalTime]

        set paramDateTime1 [expr {[$paramDateTime1 ToOADate] + \
            [object invoke -flags +NonPublic System.Data.SQLite.SQLiteConvert \
            OleAutomationEpochAsJulianDay]}]

        set paramDateTime2 $paramDateTime1
      }
      UnixEpoch {
        set paramDateTime1 [clock scan $dateTime]
        set paramDateTime2 $paramDateTime1
      }
    }

    sql execute $db [appendArgs "INSERT INTO t1 (x) VALUES(" $paramDateTime2 \
        ");"]

    list [sql execute -verbatim -execute reader -format list -datetimeformat \
        [getDateTimeFormat] $db "SELECT x FROM t1 WHERE x = ?;" \
        [list param1 String $paramDateTime1]] \
        [sql execute -verbatim -execute reader -format list -datetimeformat \
        [getDateTimeFormat] $db "SELECT x FROM t1 WHERE x = ?;" \
        [list param1 DateTime $paramDateTime1]]
  } -cleanup {
    cleanupDb $fileName

    unset -nocomplain paramDateTime2 paramDateTime1 dateTime db fileName
  } -constraints \
{eagle threadCulture.en_US monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -result {{{2011-10-04 15:27:50Z}} {{2011-10-04 15:27:50Z}}}}
}

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

unset -nocomplain dateTimeFormat i dateTimeFormats

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

runTest {test tkt-343d392b51-2.1 {SQLiteDataAdapter update fail} -setup {
  setupDb [set fileName tkt-343d392b51-2.1.db]
  set otherFileName tkt-343d392b51-2.1-otherDb.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]
  set otherDataSource [file join [getDatabaseDirectory] $otherFileName]
  set otherDbName otherDb
  set otherTable [appendArgs $otherDbName .t1]

  set sql(inserts) ""
  set sql(1) [subst { \
    ATTACH DATABASE '${otherDataSource}' AS ${otherDbName}; \
    CREATE TABLE ${otherTable}(x INTEGER PRIMARY KEY, y DATETIME); \
    [for {set i 1} {$i < 3} {incr i} {
      append sql(inserts) [appendArgs \
          "INSERT INTO " ${otherTable} " (x, y) VALUES(" $i ", '" \
          [clock format $i -format [getDateTimeFormat]] "'); "]
    }; return [expr {[info exists sql(inserts)] ? $sql(inserts) : ""}]] \
  }]

  set sql(2) [subst { \
    SELECT x, y FROM ${otherTable} ORDER BY x; \
  }]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = connection.CreateCommand())
            {
              command.CommandText = "${sql(1)}";
              command.ExecuteNonQuery();
            }

            using (SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(
                "${sql(2)}", connection))
            {
              using (DataSet dataSet = new DataSet())
              {
                dataAdapter.Fill(dataSet, "${otherTable}");

                DataTable dataTable = dataSet.Tables\["${otherTable}"\];

                dataTable.Columns\["x"\].Unique = true;
                dataTable.PrimaryKey = new DataColumn\[\] {
                  dataTable.Columns\["x"\]
                };

                [expr {[isMono] ? "#pragma warning disable 219" : ""}]
                SQLiteCommandBuilder commandBuilder =
                    new SQLiteCommandBuilder(dataAdapter);
                [expr {[isMono] ? "#pragma warning restore 219" : ""}]

                foreach (DataRow dataRow in dataTable.Rows)
                {
                  //
                  // NOTE: Update even rows and delete odd rows.
                  //
                  if ((long)dataRow\["x"\] % 2 == 0)
                    dataRow\["y"\] =
                        DateTime.UtcNow.ToString("[getDateTimeFormat]");
                  else
                    dataRow.Delete();
                }

                dataAdapter.Update(dataTable); // DBConcurrencyException (?)
              }
            }
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $otherFileName
  cleanupDb $fileName

  unset -nocomplain result code results errors i sql otherTable otherDbName \
      otherDataSource dataSource id db otherFileName fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -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 {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]
  set otherDataSource [file join [getDatabaseDirectory] $otherFileName]
  set otherDbName otherDb
  set otherTable [appendArgs $otherDbName .t1]

  set sql(inserts) ""
  set sql(1) [subst { \
    ATTACH DATABASE '${otherDataSource}' AS ${otherDbName}; \
    CREATE TABLE ${otherTable}(x INTEGER PRIMARY KEY, y DATETIME); \
    [for {set i 1} {$i < 3} {incr i} {
      append sql(inserts) [appendArgs \
          "INSERT INTO " ${otherTable} " (x, y) VALUES(" $i ", JULIANDAY('" \
          [clock format $i -format [getDateTimeFormat]] "')); "]
    }; return [expr {[info exists sql(inserts)] ? $sql(inserts) : ""}]] \
  }]

  set sql(2) [subst { \
    SELECT x, y FROM ${otherTable} ORDER BY x; \
  }]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};DateTimeFormat=JulianDay;"))
          {
            connection.Open();

            using (SQLiteCommand command = connection.CreateCommand())
            {
              command.CommandText = "${sql(1)}";
              command.ExecuteNonQuery();
            }

            using (SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(
                "${sql(2)}", connection))
            {
              using (DataSet dataSet = new DataSet())
              {
                dataAdapter.Fill(dataSet, "${otherTable}");

                DataTable dataTable = dataSet.Tables\["${otherTable}"\];

                dataTable.Columns\["x"\].Unique = true;
                dataTable.PrimaryKey = new DataColumn\[\] {
                  dataTable.Columns\["x"\]
                };

                [expr {[isMono] ? "#pragma warning disable 219" : ""}]
                SQLiteCommandBuilder commandBuilder =
                    new SQLiteCommandBuilder(dataAdapter);
                [expr {[isMono] ? "#pragma warning restore 219" : ""}]

                foreach (DataRow dataRow in dataTable.Rows)
                {
                  //
                  // NOTE: Update even rows and delete odd rows.
                  //
                  if ((long)dataRow\["x"\] % 2 == 0)
                    dataRow\["y"\] =
                        DateTime.UtcNow.ToString("[getDateTimeFormat]");
                  else
                    dataRow.Delete();
                }

                dataAdapter.Update(dataTable); // DBConcurrencyException (?)
              }
            }
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $otherFileName
  cleanupDb $fileName

  unset -nocomplain result code results errors i sql otherTable otherDbName \
      otherDataSource dataSource id db otherFileName fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -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 {
  set otherDataSource [file join [getDatabaseDirectory] $otherFileName]
  set otherDbName otherDb
  set otherTable [appendArgs $otherDbName .t1]

  set sql(inserts) ""
  set sql(1) [subst { \
    CREATE TABLE t1(x INTEGER PRIMARY KEY); \
    ATTACH DATABASE '${otherDataSource}' AS ${otherDbName}; \
    CREATE TABLE ${otherTable}(x INTEGER PRIMARY KEY); \
    [for {set i 1} {$i < 3} {incr i} {
      append sql(inserts) [appendArgs \
          "INSERT INTO t1 (x) VALUES(" $i "); "]

      append sql(inserts) [appendArgs \
          "INSERT INTO " ${otherTable} " (x) VALUES(" [expr {$i * 2}] "); "]
    }; return [expr {[info exists sql(inserts)] ? $sql(inserts) : ""}]] \
  }]

  sql execute $db $sql(1)

  list [sql execute -execute reader -format list $db "SELECT x FROM t1;"] \
      [sql execute -execute reader -format list $db [appendArgs \
      "SELECT x FROM " ${otherTable} ";"]]
} -cleanup {
  cleanupDb $otherFileName
  cleanupDb $fileName

  unset -nocomplain i sql otherTable otherDbName otherDataSource db \
      otherFileName fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{{1 2} {2 4}}}

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

runTest {test tkt-343d392b51-3.2 {adapter, attached db, table names} -setup {
  setupDb [set fileName tkt-343d392b51-3.2.db]
  set otherFileName tkt-343d392b51-3.2-otherDb.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]
  set otherDataSource [file join [getDatabaseDirectory] $otherFileName]
  set otherDbName otherDb
  set otherTable [appendArgs $otherDbName .t1]

  set sql(inserts) ""
  set sql(1) [subst { \
    CREATE TABLE t1(x INTEGER PRIMARY KEY); \
    ATTACH DATABASE '${otherDataSource}' AS ${otherDbName}; \
    CREATE TABLE ${otherTable}(x INTEGER PRIMARY KEY); \
    [for {set i 1} {$i < 3} {incr i} {
      append sql(inserts) [appendArgs \
          "INSERT INTO t1 (x) VALUES(" $i ");"]
      append sql(inserts) [appendArgs \
          "INSERT INTO " ${otherTable} " (x) VALUES(" [expr {$i * 2}] "); "]
    }; return [expr {[info exists sql(inserts)] ? $sql(inserts) : ""}]] \
  }]

  set sql(2) [subst { \
    SELECT x FROM ${otherTable} ORDER BY x; \
  }]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = connection.CreateCommand())
            {
              command.CommandText = "${sql(1)}";
              command.ExecuteNonQuery();
            }

            using (SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(
                "${sql(2)}", connection))
            {
              using (DataSet dataSet = new DataSet())
              {
                dataAdapter.Fill(dataSet, "${otherTable}");

                DataTable dataTable = dataSet.Tables\["${otherTable}"\];

                dataTable.Columns\["x"\].Unique = true;
                dataTable.PrimaryKey = new DataColumn\[\] {
                  dataTable.Columns\["x"\]
                };

                [expr {[isMono] ? "#pragma warning disable 219" : ""}]
                SQLiteCommandBuilder commandBuilder =
                    new SQLiteCommandBuilder(dataAdapter);
                [expr {[isMono] ? "#pragma warning restore 219" : ""}]

                foreach (DataRow dataRow in dataTable.Rows)
                  dataRow.Delete();

                dataAdapter.Update(dataTable); // DBConcurrencyException (?)
              }
            }
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $otherFileName
  cleanupDb $fileName

  unset -nocomplain result code results errors i sql otherTable otherDbName \
      otherDataSource dataSource id db otherFileName fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted Tests/tkt-448d663d11.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
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
###############################################################################
#
# tkt-448d663d11.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-448d663d11-1.1 {missing journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.1.db]
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.2 {missing journal mode, WAL db} -body {
  set fileName tkt-448d663d11-1.2.db
  file copy -force [file join $path wal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName "" "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{wal}}

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

runTest {test tkt-448d663d11-1.3 {missing journal mode, non-WAL db} -body {
  set fileName tkt-448d663d11-1.3.db
  file copy -force [file join $path nonWal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName "" "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.4 {'Default' journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.4.db] Default
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.5 {'Default' journal mode, WAL db} -body {
  set fileName tkt-448d663d11-1.5.db
  file copy -force [file join $path wal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName Default "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{wal}}

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

runTest {test tkt-448d663d11-1.6 {'Default' journal mode, non-WAL db} -body {
  set fileName tkt-448d663d11-1.6.db
  file copy -force [file join $path nonWal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName Default "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.7 {'Delete' journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.7.db] Delete
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.8 {'Delete' journal mode, WAL db} -body {
  set fileName tkt-448d663d11-1.8.db
  file copy -force [file join $path wal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName Delete "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.9 {'Delete' journal mode, non-WAL db} -body {
  set fileName tkt-448d663d11-1.9.db
  file copy -force [file join $path nonWal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName Delete "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.10 {'Persist' journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.10.db] Persist
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{persist}}

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

runTest {test tkt-448d663d11-1.11 {'Off' journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.11.db] Off
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{off}}

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

runTest {test tkt-448d663d11-1.12 {'Truncate' journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.12.db] Truncate
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{truncate}}

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

runTest {test tkt-448d663d11-1.13 {'Memory' journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.13.db] Memory
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{memory}}

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

runTest {test tkt-448d663d11-1.14 {'Wal' journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.14.db] Wal
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{wal}}

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

runTest {test tkt-448d663d11-1.15 {'Wal' journal mode, non-WAL db} -body {
  set fileName tkt-448d663d11-1.15.db
  file copy -force [file join $path nonWal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName Wal "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{wal}}

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

runTest {test tkt-448d663d11-1.16 {'Wal' journal mode, WAL db} -body {
  set fileName tkt-448d663d11-1.16.db
  file copy -force [file join $path wal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName Wal "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{wal}}

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

runTest {test tkt-448d663d11-1.17 {'Bad' journal mode, new db} -body {
  setupDb [set fileName tkt-448d663d11-1.17.db] Bad
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.18 {'Bad' journal mode, non-WAL db} -body {
  set fileName tkt-448d663d11-1.18.db
  file copy -force [file join $path nonWal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName Bad "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{delete}}

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

runTest {test tkt-448d663d11-1.19 {'Bad' journal mode, WAL db} -body {
  set fileName tkt-448d663d11-1.19.db
  file copy -force [file join $path wal.db] \
      [file join [getDatabaseDirectory] $fileName]
  setupDb $fileName Bad "" "" "" false
  sql execute -execute scalar $db "PRAGMA journal_mode;"
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{wal}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































Deleted Tests/tkt-544dba0a2f.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
###############################################################################
#
# tkt-544dba0a2f.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-544dba0a2f-1.1 {BOOL versus BOOLEAN} -setup {
  setupDb [set fileName tkt-544dba0a2f-1.1.db]
} -body {
  sql execute $db "CREATE TABLE t1(x BOOL, y BOOLEAN);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(0, 0);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(0, 1);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(1, 0);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(1, 1);"

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

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

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































Deleted Tests/tkt-59edc1018b.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
###############################################################################
#
# tkt-59edc1018b.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Setup the variables that refer to the various files required by the
#       tests in this file.
#
set testLinqExeFile [getBuildFileName testlinq.exe]
set northwindEfDbFile [file nativename [file join [file dirname $path] \
    testlinq northwindEF.db]]

#
# NOTE: Setup the test constraints specific to the tests in this file.
#
if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then {
  checkForFile $test_channel $testLinqExeFile
}

if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then {
  checkForFile $test_channel $northwindEfDbFile
}

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

runTest {test tkt-59edc1018b-1.1 {LINQ with EndsWith} -body {
  set result [list]

  foreach value [list "" a b z 1+1 don notthere] {
    set output ""

    set code [catch {
      testClrExec $testLinqExeFile [list -eventflags Wait -directory \
          [file dirname $testLinqExeFile] -nocarriagereturns -stdout output \
          -success 0] -endsWith $value
    } error]

    tlog "---- BEGIN STDOUT OUTPUT\n"
    tlog $output
    tlog "\n---- END STDOUT OUTPUT\n"

    lappend result $code

    if {$code == 0} then {
      lappend result [string trim $output]
    } else {
      lappend result [string trim $error]
    }
  }

  set result
} -cleanup {
  unset -nocomplain code output error result value
} -constraints {eagle monoToDo 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 testLinqExeFile northwindEfDbFile

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted Tests/tkt-7e3fa93744.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
###############################################################################
#
# tkt-7e3fa93744.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-7e3fa93744-1.1 {composite primary key, baseline} -setup {
  setupDb [set fileName tkt-7e3fa93744-1.1.db]
} -body {
  set sql {
    CREATE TABLE t1 (
      id1 INTEGER PRIMARY KEY
    );

    CREATE TABLE t2 (
      id1 INTEGER NOT NULL,
      id2 INTEGER NOT NULL,
      PRIMARY KEY (id1, id2)
    );

    INSERT INTO t1 (id1) VALUES (1);
    INSERT INTO t1 (id1) VALUES (2);

    INSERT INTO t2 (id1, id2) VALUES (1, 1);
    INSERT INTO t2 (id1, id2) VALUES (1, 2);
    INSERT INTO t2 (id1, id2) VALUES (2, 1);
    INSERT INTO t2 (id1, id2) VALUES (2, 2);

    SELECT t1.id1, t2.id1, t2.id2
    FROM t1, t2
    ORDER BY t1.id1, t2.id1, t2.id2;
  }

  sql execute -execute reader -format list $db $sql
} -cleanup {
  cleanupDb $fileName

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

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

runTest {test tkt-7e3fa93744-1.2 {composite primary key, DataTable} -setup {
  setupDb [set fileName tkt-7e3fa93744-1.2.db]
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  set sql { \
    CREATE TABLE t1 ( \
      id1 INTEGER PRIMARY KEY NOT NULL \
    ); \
    CREATE TABLE t2 ( \
      id1 INTEGER NOT NULL, \
      id2 INTEGER NOT NULL, \
      PRIMARY KEY (id1, id2) \
    ); \
    INSERT INTO t1 (id1) VALUES (1); \
    INSERT INTO t1 (id1) VALUES (2); \
    INSERT INTO t2 (id1, id2) VALUES (1, 1); \
    INSERT INTO t2 (id1, id2) VALUES (1, 2); \
    INSERT INTO t2 (id1, id2) VALUES (2, 1); \
    INSERT INTO t2 (id1, id2) VALUES (2, 2); \
    SELECT t1.id1, t2.id1, t2.id2 \
    FROM t1, t2 \
    ORDER BY t1.id1, t2.id1, t2.id2; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static int Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = connection.CreateCommand())
            {
              command.CommandText = "${sql}";

              using (SQLiteDataReader dataReader = command.ExecuteReader())
              {
                DataTable dataTable = new DataTable();
                dataTable.Load(dataReader);

                return dataTable.Rows.Count;
              }
            }
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [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$}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































Deleted Tests/tkt-84718e79fa.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
###############################################################################
#
# tkt-84718e79fa.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

set c 10

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

runTest {test tkt-84718e79fa-1.1 {SQLiteConvert thread safety} -setup {
  proc threadStart { args } {
    lappend ::results [sql execute -execute reader -format list $::db \
        "SELECT x FROM t1;"]
  }

  object import System.Threading

  setupDb [set fileName tkt-84718e79fa-1.1.db]
} -body {
  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  for {set i 0} {$i < $c} {incr i} {
    set t($i) [object create -alias Thread threadStart]
  }

  set ::results [list]

  for {set i 0} {$i < $c} {incr i} {
    $t($i) Start
  }

  after 4000; # wait for other threads to do something...

  for {set i 0} {$i < $c} {incr i} {
    $t($i) Join
  }

  set ::results
} -cleanup {
  cleanupDb $fileName

  object unimport -importpattern System.Threading

  for {set i 0} {$i < $c} {incr i} {
    if {[info exists t($i)] && [cleanupThread $t($i)]} then {
      unset t($i)
    }
  }

  catch {object removecallback threadStart}

  unset -nocomplain results t i c db fileName

  rename threadStart ""
} -constraints \
{eagle shell monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result [lrepeat $c 1]}

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

unset -nocomplain c

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































Deleted Tests/tkt-8554170e09.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
###############################################################################
#
# tkt-8554170e09.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-8554170e09-1.1 {default DATETIME value, NULL} -setup {
  setupDb [set fileName tkt-8554170e09-1.1.db]
} -body {
  sql execute $db "CREATE TABLE t1(x INTEGER, y DATETIME);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(1, NULL);"

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

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

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

runTest {test tkt-8554170e09-1.2 {default DATETIME value, empty} -setup {
  setupDb [set fileName tkt-8554170e09-1.2.db]
} -body {
  sql execute $db "CREATE TABLE t1(x INTEGER, y DATETIME);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(1, '');"

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

  unset -nocomplain result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-returnCodes 1 -match glob -result {*.SQLiteConvert.ToDateTime*}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































Deleted Tests/tkt-8b7d179c3c.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
###############################################################################
#
# tkt-8b7d179c3c.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Setup the variables that refer to the various files required by the
#       tests in this file.
#
set testLinqExeFile [getBuildFileName testlinq.exe]
set northwindEfDbFile [file nativename [file join [file dirname $path] \
    testlinq northwindEF.db]]

#
# NOTE: Setup the test constraints specific to the tests in this file.
#
if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then {
  checkForFile $test_channel $testLinqExeFile
}

if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then {
  checkForFile $test_channel $northwindEfDbFile
}

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

runTest {test tkt-8b7d179c3c-1.1 {LINQ with Skip and Take} -body {
  set result [list]

  for {set pageSize 0} {$pageSize <= 2} {incr pageSize} {
    set output ""

    set code [catch {
      testClrExec $testLinqExeFile [list -eventflags Wait -directory \
          [file dirname $testLinqExeFile] -nocarriagereturns -stdout output \
          -success 0] -skip $pageSize
    } error]

    tlog "---- BEGIN STDOUT OUTPUT\n"
    tlog $output
    tlog "\n---- END STDOUT OUTPUT\n"

    lappend result $code

    if {$code == 0} then {
      lappend result [string trim $output]
    } else {
      lappend result [string trim $error]
    }
  }

  set result
} -cleanup {
  unset -nocomplain code output error result pageSize
} -constraints {eagle monoToDo 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 FAMIA\
QUEEN TRADH WHITC GODOS SANTG BLONP WANDK FRANS LAMAI BOTTM LAUGB LACOR LAZYK\
WOLZA VAFFE} 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\
FAMIA QUEEN TRADH WHITC GODOS SANTG BLONP WANDK FRANS LAMAI BOTTM LAUGB LACOR\
LAZYK WOLZA VAFFE}}}

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

unset -nocomplain testLinqExeFile northwindEfDbFile

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































Deleted Tests/tkt-ac47dd230a.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
###############################################################################
#
# tkt-ac47dd230a.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-ac47dd230a-1.1 {multiple AppDomains} -setup {
  for {set i 1} {$i < 3} {incr i} {
    set appDomain($i) [object invoke AppDomain CreateDomain \
        tkt-ac47dd230a-1.1.$i]

    set result null
    set interpreterHelper($i) [object invoke -alias InterpreterHelper \
        Create $appDomain($i) null Default null null null result]

    if {[string length $interpreterHelper($i)] == 0} then {
      error [object invoke $result ToString]
    }

    set interpreter($i) [$interpreterHelper($i) -alias Interpreter]

    set result null
    set code [$interpreter($i) EvaluateScript [getAppDomainPreamble] result]

    if {$code ne "Ok"} then {
      error [object invoke $result ToString]
    }
  }
} -body {
  set results [list]

  for {set i 1} {$i < 3} {incr i} {
    set result null
    set code [$interpreter($i) EvaluateScript {
      package require EagleLibrary
      package require EagleTest
      package require System.Data.SQLite.Test

      object load -loadtype File [file join [getBinaryDirectory] \
          System.Data.SQLite.dll]

      setupDb tkt-ac47dd230a-1.1; cleanupDb tkt-ac47dd230a-1.1
    } result]

    lappend results $code [expr {[string length $result] > 0 ? \
        [object invoke $result ToString] : ""}]
  }

  set results
} -cleanup {
  unset -nocomplain results code result interpreter interpreterHelper

  for {set i 1} {$i < 3} {incr i} {
    object invoke AppDomain Unload $appDomain($i)
  }

  unset -nocomplain appDomain i
} -constraints {eagle monoBug28 command.sql compile.DATA\
compile.ISOLATED_INTERPRETERS SQLite System.Data.SQLite} -result {Ok 0 Ok 0}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































Deleted Tests/tkt-b4a7ddc83f.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
###############################################################################
#
# tkt-b4a7ddc83f.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Make sure that SQLite core library is completely shutdown prior to
#       starting any of the tests in this file.
#
if {[haveConstraint SQLite]} then {
  object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \
      sqlite3_shutdown
}

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

for {set i 1} {$i < 3} {incr i} {
  runTest {test [appendArgs tkt-b4a7ddc83f-1. $i] {logging shutdown} -setup \
      [getAppDomainPreamble {
    set appDomainId(1) {[object invoke AppDomain.CurrentDomain Id]}
    set fileName {[appendArgs tkt-b4a7ddc83f-1. $i .db]}
  }] -body {
    set appDomainId(2) [object invoke AppDomain.CurrentDomain Id]

    package require EagleLibrary
    package require EagleTest
    package require System.Data.SQLite.Test

    object load -loadtype File [file join [getBinaryDirectory] \
        System.Data.SQLite.dll]

    object invoke System.Data.SQLite.SQLiteLog Initialize

    list $appDomainId(1) $appDomainId(2) \
        [expr {$appDomainId(1) != $appDomainId(2)}] [setupDb $fileName]
  } -cleanup {
    cleanupDb $fileName
    unset -nocomplain appDomainId db fileName
  } -constraints {eagle monoBug28 command.sql compile.DATA\
compile.ISOLATED_INTERPRETERS SQLite System.Data.SQLite} -isolationLevel \
AppDomain -match regexp -result {^\d+ \d+ True\
System#Data#SQLite#SQLiteConnection#\d+$}}
}

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

unset -nocomplain i

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































Deleted Tests/tkt-bb4b04d457.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
###############################################################################
#
# tkt-bb4b04d457.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-bb4b04d457-1.1 {} -setup {
  setupDb [set fileName tkt-bb4b04d457-1.1.db] "" Ticks Utc
} -body {
  set dateTime [object invoke -alias DateTime Parse 2011-11-29T12:34:56Z]
  set dateTime [$dateTime -alias ToUniversalTime]

  sql execute $db "CREATE TABLE t1(x TIMESTAMP NOT NULL);"

  sql execute $db "INSERT INTO t1 (x) VALUES(?);" \
      [list param1 Int64 [$dateTime Ticks]]

  sql execute -execute reader -format list -datetimeformat \
      [getDateTimeFormat] $db "SELECT x FROM t1 ORDER BY rowid;"
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain dateTime db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{{2011-11-29 12:34:56Z}}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































Deleted Tests/tkt-ccfa69fc32.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
###############################################################################
#
# tkt-ccfa69fc32.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Setup the variables that refer to the various files required by the
#       tests in this file.
#
set testLinqExeFile [getBuildFileName testlinq.exe]
set northwindEfDbFile [file nativename [file join [file dirname $path] \
    testlinq northwindEF.db]]

#
# NOTE: Setup the test constraints specific to the tests in this file.
#
if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then {
  checkForFile $test_channel $testLinqExeFile
}

if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then {
  checkForFile $test_channel $northwindEfDbFile
}

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

runTest {test tkt-ccfa69fc32-1.1 {Entity Framework / Transaction Scope} -body {
  set result [list]

  foreach add [list false true false] {
    set output ""

    set code [catch {
      testClrExec $testLinqExeFile [list -eventflags Wait -directory \
          [file dirname $testLinqExeFile] -nocarriagereturns -stdout output \
          -success 0] -efTransaction $add
    } error]

    tlog "---- BEGIN STDOUT OUTPUT\n"
    tlog $output
    tlog "\n---- END STDOUT OUTPUT\n"

    lappend result $code

    if {$code == 0} then {
      lappend result [string trim $output]
    } else {
      lappend result [string trim $error]
    }
  }

  set result
} -cleanup {
  unset -nocomplain code output error result add
} -constraints {eagle monoToDo file_testlinq.exe file_northwindEF.db} -match \
glob -result {0 {1581 1730 1833 2116 2139} 0 {System.Data.UpdateException: *\
---> System.Data.SQLite.SQLiteException: Abort due to constraint violation
PRIMARY KEY must be unique
*} 0 {1 2 3 4 5 6 7 8 9 10 1576 1577 1578 1579 1580 1581 1730 1833 2116 2139}}}

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

unset -nocomplain testLinqExeFile northwindEfDbFile

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































Deleted Tests/tkt-e1b2e0f769.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
###############################################################################
#
# tkt-e1b2e0f769.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-e1b2e0f769-1.1 {data reader cleanup} -setup {
  setupDb [set fileName tkt-e1b2e0f769-1.1.db]
} -body {
  sql execute $db "CREATE TABLE t1(x INTEGER);"
  sql execute $db "CREATE TABLE t2(x INTEGER);"

  foreach x [list 1 2 3] {
    sql execute $db "INSERT INTO t1 (x) VALUES($x);"
  }

  set result1 [list]
  set dataSource [file join [getDatabaseDirectory] tkt-e1b2e0f769-1.1.db]

  foreach table [list t1 t2] {
    set id [object invoke Interpreter.GetActive NextId]
    set sql "SELECT x FROM $table ORDER BY x;"

    unset -nocomplain results errors

    set code [compileCSharpWith [subst {
      using System.Collections.Generic;
      using System.Data.SQLite;

      namespace _Dynamic${id}
      {
        public class Test${id}
        {
          public static List<long?> Tkt_e1b2e0f769(SQLiteConnection connection)
          {
            List<long?> result = new List<long?>();

            using (SQLiteTransaction transaction = connection.BeginTransaction())
            {
              using (SQLiteCommand command = connection.CreateCommand())
              {
                command.CommandText = "${sql}";

                using (SQLiteDataReader dataReader = command.ExecuteReader())
                {
                  //
                  // NOTE: If there are no rows, close the connection and
                  //       return the empty list.  In this case,  an exception
                  //       will be raised when exiting the using block for the
                  //       data reader because we are closing the connection out
                  //       from underneath it.
                  //
                  if (!dataReader.HasRows)
                  {
                    //
                    // NOTE: Closing the connection here caused an exception to
                    //       be raised when exiting the using block for the data
                    //       reader (below) because the Dispose method for the
                    //       data reader calls the Close method, which always
                    //       assumed the underlying connection was still open.
                    //
                    connection.Close();
                    return result;
                  }

                  while (dataReader.Read())
                  {
                    result.Add((long?) dataReader\[0\]);
                  }
                } // NOTE: Exception here when no data rows (see comment above).
              }
            }

            connection.Close();
            return result;
          }

          public static int Main()
          {
            using (SQLiteConnection connection = new SQLiteConnection(
                "Data Source=${dataSource};"))
            {
              connection.Open();

              return Tkt_e1b2e0f769(connection).Count;
            }
          }
        }
      }
    }] true true true results errors System.Data.SQLite.dll]

    lappend result1 $code $results \
        [expr {[info exists errors] ? $errors : ""}] \
        [expr {$code eq "Ok" ? [catch {
          object invoke _Dynamic${id}.Test${id} Main
        } result2] : [set result2 ""]}] $result2
  }

  set result1
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result2 result1 code results errors sql table dataSource \
      id x db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 3 Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 0$}}

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































Deleted Tests/tkt-e30b820248.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
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
###############################################################################
#
# tkt-e30b820248.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

set memory_used [reportSQLiteResources $test_channel true]

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

runTest {test tkt-e30b820248-1.1 {disposal ordering} -setup {
  set fileName tkt-e30b820248-1.1.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]
  set name [file rootname [file tail $fileName]]

  set sql { \
    CREATE TABLE t1 (id1 INTEGER); \
    INSERT INTO t1 (id1) VALUES (1); \
    INSERT INTO t1 (id1) VALUES (2); \
    INSERT INTO t1 (id1) VALUES (?); \
    INSERT INTO t1 (id1) VALUES (?); \
    INSERT INTO t1 (id1) VALUES (?); \
    SELECT * FROM t1 ORDER BY id1; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data.SQLite;
    using System.Diagnostics;
    using System.IO;

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (TraceListener listener = new TextWriterTraceListener(
              new FileStream("${test_log}", FileMode.Append,
                  FileAccess.Write, FileShare.ReadWrite), "${name}"))
          {
            Trace.Listeners.Add(listener);
            Trace.WriteLine("---- START TRACE \\"${name}\\"");

            using (SQLiteConnection connection = new SQLiteConnection(
                "Data Source=${dataSource};"))
            {
              connection.Open();
              connection.LogMessage(0, "Connection opened.");

              using (SQLiteTransaction transaction =
                  connection.BeginTransaction())
              {
                connection.LogMessage(0, "Transaction started.");

                using (SQLiteCommand command = connection.CreateCommand())
                {
                  command.Transaction = transaction;
                  command.CommandText = "${sql}";

                  command.Parameters.AddWithValue("x", 3);
                  command.Parameters.AddWithValue("y", 4);
                  command.Parameters.AddWithValue("z", 5);

                  command.ExecuteNonQuery();
                  connection.LogMessage(0, "Command executed.");
                }

                transaction.Commit();
                connection.LogMessage(0, "Transaction committed.");
              }
            }

            Trace.WriteLine("---- END TRACE \\"${name}\\"");
            Trace.Listeners.Remove(listener);
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        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 dataSource id db fileName
} -constraints \
{eagle logFile monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-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]

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

  runTest {test [appendArgs tkt-e30b820248-1. $i] {disposal ordering} -setup {
    set fileName [appendArgs tkt-e30b820248-1. $i .db]
  } -body {
    set id [object invoke Interpreter.GetActive NextId]
    set dataSource [file join [getDatabaseDirectory] $fileName]
    set name [file rootname [file tail $fileName]]

    set sql { \
      CREATE TABLE t1 (id1 INTEGER); \
      INSERT INTO t1 (id1) VALUES (1); \
      INSERT INTO t1 (id1) VALUES (2); \
      INSERT INTO t1 (id1) VALUES (3); \
      INSERT INTO t1 (id1) VALUES (4); \
      INSERT INTO t1 (id1) VALUES (5); \
      SELECT * FROM t1 ORDER BY id1; \
    }

    unset -nocomplain results errors

    set code [compileCSharpWith [subst {
      using System;
      using System.Data.SQLite;
      using System.Diagnostics;
      using System.IO;

      namespace _Dynamic${id}
      {
        public class Test${id}
        {
          #region Private Static Data
          private static SQLiteConnection connection;
          #endregion

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

          #region Public Static Methods
          public static void OpenConnection()
          {
            connection = new SQLiteConnection("Data Source=${dataSource};");
            connection.Open();
            connection.LogMessage(0, "Connection opened.");
          }

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

          public static SQLiteCommand CreateCommand(string sql)
          {
            SQLiteCommand command = connection.CreateCommand();
            command.CommandText = sql;
            connection.LogMessage(0, "Command created.");
            return command;
          }

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

          public static SQLiteDataReader ExecuteReader(SQLiteCommand command)
          {
            SQLiteDataReader dataReader = command.ExecuteReader();
            connection.LogMessage(0, "Command executed.");
            return dataReader;
          }

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

          public static SQLiteDataReader ExecuteReader(string sql)
          {
            SQLiteCommand command = CreateCommand(sql);
            SQLiteDataReader dataReader = command.ExecuteReader();
            connection.LogMessage(0, "Command executed.");
            return dataReader;
          }

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

          public static void CloseConnection()
          {
            connection.LogMessage(0, "Closing connection...");
            connection.Close();
          }
          #endregion

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

          public static void Main()
          {
            using (TraceListener listener = new TextWriterTraceListener(
                new FileStream("${test_log}", FileMode.Append,
                    FileAccess.Write, FileShare.ReadWrite), "${name}"))
            {
              Trace.Listeners.Add(listener);
              Trace.WriteLine("---- START TRACE \\"${name}\\"");

              OpenConnection();
              SQLiteDataReader dataReader = ExecuteReader("${sql}");

              [expr {$i <= 2 ? {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
              } : ""}]

              dataReader.Close();

              [expr {$i <= 3 ? {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
              } : ""}]

              CloseConnection();

              [expr {$i <= 4 ? {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
              } : ""}]

              Trace.WriteLine("---- END TRACE \\"${name}\\"");
              Trace.Listeners.Remove(listener);
            }
          }
        }
      }
    }] true true true results errors System.Data.SQLite.dll]

    list $code $results \
        [expr {[info exists errors] ? $errors : ""}] \
        [expr {$code eq "Ok" ? [catch {
          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 db \
        fileName
  } -constraints {eagle logFile monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\} " $memory_used \$]}
}

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

unset -nocomplain i

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

unset -nocomplain memory_used

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































Deleted Tests/version.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
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
###############################################################################
#
# version.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################
# ******************** BEGIN VOLATILE VERSION INFORMATION *********************
###############################################################################

#
# 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)            77; # NOTE: Incremented with each release.
set version(revision)          0

###############################################################################
# ********************* END VOLATILE VERSION INFORMATION **********************
###############################################################################

#
# NOTE: Build the full version number using the components setup above.  This
#       should not have to be changed.
#
set version(full) [appendArgs $version(major) . $version(minor) . \
                              $version(build) . $version(revision)]

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

#
# NOTE: Setup the variables that refer to the various files required by the
#       tests in this file.
#
set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll]
set systemDataSQLiteLinqDllFile [getBuildFileName System.Data.SQLite.Linq.dll]
set testExeFile [getBuildFileName test.exe]
set testLinqExeFile [getBuildFileName testlinq.exe]

#
# NOTE: Setup the test constraints specific to the tests in this file.
#
if {![haveConstraint [appendArgs file_ \
    [file tail $systemDataSQLiteDllFile]]]} then {
  checkForFile $test_channel $systemDataSQLiteDllFile
}

if {![haveConstraint [appendArgs file_ \
    [file tail $systemDataSQLiteLinqDllFile]]]} then {
  checkForFile $test_channel $systemDataSQLiteLinqDllFile
}

if {![haveConstraint [appendArgs file_ [file tail $testExeFile]]]} then {
  checkForFile $test_channel $testExeFile
}

if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then {
  checkForFile $test_channel $testLinqExeFile
}

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

runTest {test version-1.1 {'System.Data.SQLite' binary version} -body {
  file version $systemDataSQLiteDllFile
} -constraints {eagle file_System.Data.SQLite.dll} -result $version(full)}

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

runTest {test version-1.2 {'System.Data.SQLite' assembly version} -body {
  set assembly [object load System.Data.SQLite]

  foreach assembly [object assemblies] {
    if {[string match System.Data.SQLite,* $assembly]} then {
      return [regexp -- [appendArgs Version= [string map [list . \\.] \
          $version(full)] ,] $assembly]
    }
  }

  return false
} -cleanup {
  unset -nocomplain assembly
} -constraints {eagle SQLite System.Data.SQLite} -result {1}}

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

runTest {test version-1.3 {'System.Data.SQLite.Linq' binary version} -body {
  file version $systemDataSQLiteLinqDllFile
} -constraints {eagle file_System.Data.SQLite.Linq.dll} -result $version(full)}

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

runTest {test version-1.4 {'System.Data.SQLite.Linq' assembly version} -body {
  set assembly [object load System.Data.SQLite.Linq]

  foreach assembly [object assemblies] {
    if {[string match System.Data.SQLite.Linq,* $assembly]} then {
      return [regexp -- [appendArgs Version= [string map [list . \\.] \
          $version(full)] ,] $assembly]
    }
  }

  return false
} -cleanup {
  unset -nocomplain assembly
} -constraints {eagle SQLite System.Data.SQLite System.Data.SQLite.Linq} \
-result {1}}

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

runTest {test version-1.5 {'test' binary version} -body {
  file version $testExeFile
} -constraints {eagle file_test.exe} -result $version(full)}

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

runTest {test version-1.6 {'testlinq' binary version} -body {
  file version $testLinqExeFile
} -constraints {eagle file_testlinq.exe} -result $version(full)}

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

set patterns [list \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs Version= [string map [list . \\.] $version(full)] ,] \
    [appendArgs &quot\; [format %03d $version(build)] &quot\;] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs Value=\" [format %03d $version(build)] \"] \
    [appendArgs Value=\" [string map [list . \\.] $version(full)] \"] \
    [appendArgs Value=\" [string map [list . ,] $version(full)] \"] \
    [appendArgs <INTEROP_BUILD_NUMBER> [format %03d $version(build)] \
        </INTEROP_BUILD_NUMBER>] \
    [appendArgs <INTEROP_MANIFEST_VERSION> [string map [list . \\.] \
        $version(full)] </INTEROP_MANIFEST_VERSION>] \
    [appendArgs <INTEROP_RC_VERSION> [string map [list . ,] \
        $version(full)] </INTEROP_RC_VERSION>] \
    [appendArgs \" [string map [list . \\.] $version(full)] \"] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs \" [string map [list . \\.] $version(full)] \"] \
    [appendArgs \"SQLite.Interop. [format %03d $version(build)] .dll\"] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs Version= [string map [list . \\.] $version(full)] ,] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs Version= [string map [list . \\.] $version(full)] ,] \
    [appendArgs Version= [string map [list . \\.] $version(full)] ,] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)]]

set fileNames [list \
    SQLite.nuspec \
    SQLite.MSIL.nuspec \
    SQLite.x64.nuspec \
    SQLite.x86.nuspec \
    [file join Doc Extra dbfactorysupport.html] \
    [file join Doc Extra welcome.html] \
    [file join Membership Properties AssemblyInfo.cs] \
    [file join Membership Properties AssemblyInfo.cs] \
    [file join SQLite.Designer AssemblyInfo.cs] \
    [file join SQLite.Designer AssemblyInfo.cs] \
    [file join SQLite.Interop props SQLite.Interop.vsprops] \
    [file join SQLite.Interop props SQLite.Interop.vsprops] \
    [file join SQLite.Interop props SQLite.Interop.vsprops] \
    [file join SQLite.Interop props SQLite.Interop.props] \
    [file join SQLite.Interop props SQLite.Interop.props] \
    [file join SQLite.Interop props SQLite.Interop.props] \
    [file join SQLite.Interop src win interop.h] \
    [file join System.Data.SQLite AssemblyInfo.cs] \
    [file join System.Data.SQLite AssemblyInfo.cs] \
    [file join System.Data.SQLite SQLite3.cs] \
    [file join System.Data.SQLite UnsafeNativeMethods.cs] \
    [file join System.Data.SQLite.Linq AssemblyInfo.cs] \
    [file join System.Data.SQLite.Linq AssemblyInfo.cs] \
    [file join test AssemblyInfo.cs] \
    [file join test AssemblyInfo.cs] \
    [file join test app.config] \
    [file join testce AssemblyInfo.cs] \
    [file join testce AssemblyInfo.cs] \
    [file join testlinq 2008 App.config] \
    [file join testlinq 2010 App.config] \
    [file join testlinq Properties AssemblyInfo.cs] \
    [file join testlinq Properties AssemblyInfo.cs] \
    [file join tools install Properties AssemblyInfo.cs] \
    [file join tools install Properties AssemblyInfo.cs]]

for {set i 1} {$i <= [llength $fileNames]} {incr i} {
  set pattern [lindex $patterns [expr {$i - 1}]]
  set fileName [lindex $fileNames [expr {$i - 1}]]
  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.7. $i] \
      [appendArgs "pattern {" $pattern "} in file \"" $fileName \"] -body {
    regexp -- $pattern [readFile $fileName]
  } -constraints [list eagle [appendArgs file_ $constraint]] -result {1}}
}

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

unset -nocomplain constraint fileName pattern fileNames patterns i version

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

unset -nocomplain testLinqExeFile testExeFile systemDataSQLiteLinqDllFile \
    systemDataSQLiteDllFile

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

runSQLiteTestEpilogue
runTestEpilogue
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































Deleted Tests/wal.db.

cannot compute difference between binary files

Added bin/test.exe.config.














>
>
>
>
>
>
>
1
2
3
4
5
6
7
<configuration>
  <system.data>
    <DbProviderFactories>
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" support="3F" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>
</configuration>
Deleted exclude_bin.txt.
1
2
3
4
5
6
*.exp
*.lib
*.map
*Installer.*
*EnvDTE.*
*Microsoft.*
<
<
<
<
<
<












Deleted exclude_src.txt.
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
*.cache
*.chw
*.docstates
*.fossil
*.ncb
*.nupkg
*.suo
*.user
*.zip
_FOSSIL_
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/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/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/*
Externals/NDoc3/*
Membership/*
Membership/obj/*
Membership/Profile/*
Membership/SiteMap/*
obj/*
Setup/Output/*
SQLite.Designer/obj/*
SQLite.Designer/Properties/*
SQLite.Designer/VSDesign/*
System.Data.SQLite.Linq/obj/*
System.Data.SQLite/obj/*
System.Data.SQLite/Properties/*
test/obj/*
testce/obj/*
testlinq/obj/*
tools/install/obj/*
www/*
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































Changes to readme.htm.
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
<!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.77.0 November 28, 2011<br />
Using SQLite 3.7.9 <a href="http://www.sqlite.org/src/info/c7c6050ef0">[c7c6050ef0]</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?n=20&y=ci">
http://system.data.sqlite.org/index.html/timeline?n=20&y=ci</a>

<br />
<br />

<h2><b>Features</b></h2>

<ul>
  <li>
    Written from scratch on Visual Studio 2008 specifically for ADO.NET,
    implementing all the base classes and features recently introduced in the
    framework, including automatic transaction enlistment.
  </li>

  <li>
    Supports the Full and Compact .NET Framework, and native C/C++ development.
    100% binary compatible with the original sqlite3.dll.
  </li>

  <li>
    Full support for Mono via a &quot;managed only&quot; provider that runs
    against the official SQLite 3.6.1 or higher library.
  </li>

  <li>Full Entity Framework support (ADO.NET 3.5 SP1).</li>

  <li>
    On the Compact Framework, it is faster than SQL Server Mobile.  SQLite's
    installed size is a fraction of SQL Mobile's.  It uses less memory at
    runtime, runs queries faster, and has a smaller database file size as well.
  </li>

  <li>
    Encrypted database support.  Encrypted databases are fully encrypted and
    support both binary and cleartext password types.
  </li>

  <li>
    Visual Studio design-time Support, works with all versions of Visual Studio
    2005/2008/2010.  You can add a SQLite database to the Servers list, design
    queries with the Query Designer, drag-and-drop tables onto a Typed DataSet,
    etc.
    <br />
    <font color="red">
      Currently not included.  We are still updating the design-time support
      installer.  Due to Visual Studio licensing restrictions, the Express
      Editions can no longer be supported.
    </font>
  </li>

  <li>
    Full SQLite schema editing inside Visual Studio.  You can create/edit tables,
    views, triggers, indexes, check constraints and foreign keys.
  </li>

  <li>
    Single file redistributable (except on Compact Framework).  The core SQLite
    native code and the ADO.NET managed wrapper are combined into one mixed-mode
    assembly.
  </li>

  <li>
    Binaries included for x86, x64, Itanium, and ARM processors.
    <br />
    <font color="red">
      Itanium processor support not currently included.
    </font>
  </li>



  <li>DbProviderFactory support.</li>

  <li>
    Full support for ATTACH'ed databases.  Exposed as <i>Catalogs</i> in the
    schema.  When cloning a connection, all attached databases are automatically
    re-attached to the new connection.
  </li>

  <li>
    DbConnection.GetSchema(...) support includes <i>ReservedWords</i>,
    <i>MetaDataCollections</i>, <i>DataSourceInformation</i>, <i>DataTypes</i>,
    <i>Columns</i>, <i>Tables</i>, <i>Views</i>, <i>ViewColumns</i>,
    <i>Catalogs</i>, <i>Indexes</i>, <i>IndexColumns</i>, <i>ForeignKeys</i> and
    <i>Triggers</i>.
  </li>

  <li>
    Enhanced DbDataReader.GetSchemaTable() functionality returns catalog,
    namespace and detailed schema information even for complex queries.
  </li>

  <li>Named and unnamed parameters.</li>

  <li>
    Full UTF-8 and UTF-16 support, each with optimized pipelines into the native
    database core.
  </li>

  <li>
    Multiple simultaneous DataReaders (one DataReader per Command however).
  </li>

  <li>
    Full support for user-defined scalar and aggregate functions, encapsulated

    into an easy-to-use base class in which only a couple of overrides are
    necessary to implement new SQL functions.
  </li>

  <li>
    Full support for user-defined collating sequences, every bit as simple to
    implement as user-defined functions and uses the same base class.
  </li>

  <li>
    Full source for the entire engine and wrapper.  No copyrights.  Public
    Domain.  100% free for commercial and non-commercial use.
  </li>
</ul>

<h2><strong>Design-Time Support</strong></h2>
<font color="red">Currently not included.  We are still updating the Design-Time
support installer.</font>
<p>
In Windows Explorer, navigate to the <strong>SQLite.NET\bin\Designer</strong> folder
and execute the <strong>INSTALL.EXE</strong> file.&nbsp; The program will automatically
detect what version(s) of Visual Studio 2005/2008 are installed and allow you to
selectively install and uninstall the designer for each edition.</p>
<h2>
<strong>DbFactory Support (Non-Compact Framework)</strong></h2>
In order to use the SQLiteFactory and have the SQLite data provider enumerated in
the DbProviderFactories methods, you must add the following segment into your application's


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" /&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.
</p>

<h2>Compiling for the Compact Framework</h2>

<p>
Just change the target platform from Win32 to Compact Framework and recompile.&nbsp;
<strong>The Compact Framework has no support for enumerating attributes in an assembly,
therefore all user-defined collating sequences and functions must be explicitly
registered.</strong>&nbsp; See the <strong>testce</strong> sample application for
an example of how to explicitly register user-defined collating sequences and functions.</p>

<h2><b><a name="redist"></a>Distributing The SQLite Engine and ADO.NET Assembly</b></h2>

<p>
On the desktop, only the <strong>System.Data.SQLite.DLL</strong> file needs to be
distributed with your application(s).&nbsp; This DLL contains both the managed wrapper
and the native SQLite3 codebase.&nbsp; For the Compact Framework, you will have
to distribute both the CF version of System.Data.SQLite.DLL, as well as the SQLite.Interop.XXX.DLL.&nbsp;
This is a breaking change as of 1.0.59.0.&nbsp; Recent Windows Mobile frameworks
are not supporting the mixed CF assembly I was building prior to this version.</p>

<h2><b>Development Notes Regarding the SQLite 3 Source Code</b></h2>

<p>
The core SQLite engine is compiled directly from the unmodified source code available
at the sqlite.org website.&nbsp; Several additional pieces are compiled on top of
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.77.0 - November 28, 2011</b>
</p>
<ul>
    <li>Updated to SQLite 3.7.9 <a href="http://www.sqlite.org/src/info/a499ae3835">[a499ae3835]</a>.</li>
    <li>More enhancements to the build and test automation.</li>
    <li>Plug native memory leak when closing a database connection containing a statement that cannot be finalized for some reason.</li>
    <li>The SQLite3 class should always attempt to dispose the contained SQLiteConnectionHandle, even when called via the finalizer.</li>
    <li>When compiled with DEBUG defined, emit diagnostic information related to resource cleanup to any TraceListener objects that may be registered.</li>
    <li>Stop characterizing all log messages as errors. From now on, if the errorCode is zero, the message will not be considered an error.</li>
    <li>Never attempt to configure the native logging interface if the SQLite core library has already been initialized for the process. Fix for [2ce0870fad].</li>
    <li>Allow the SQLiteLog class to be used for logging messages without having an open connection.</li>
    <li>Support building the core System.Data.SQLite assemblies using the .NET Framework 4.0 Client Profile. Fix for [566f1ad1e4].</li>
    <li>When generating the schema based on the contents of a SQLiteDataReader, skip flagging columns as unique if the data reader is holding the result of some kind of multi-table construct (e.g. a cross join) because we must allow duplicate values in that case. Fix for [7e3fa93744].</li>
    <li>When returning schema information that may be used by the .NET Framework to construct dynamic SQL, use a fake schema name (instead of null) so that the table names will be properly qualified with the catalog name (i.e. the attached database name). Partial fix for [343d392b51].</li>
    <li>Add SQLiteSourceId property to the SQLiteConnection class to return the SQLite source identifier.</li>
    <li>Add MemoryUsed and MemoryHighwater properties to the SQLiteConnection class to help determine the memory usage of SQLite.</li>
    <li>Add DateTimeKind connection string property to control the DateTimeKind of parsed DateTime values. Partial fix for [343d392b51].</li>
    <li>Improve the robustness of the SQLiteLog class when it will be initialized and unloaded multiple times.</li>
    <li>Fix the name of the interop assembly for Windows CE. Add unit tests to prevent this type of issue from happening again. Fix for [737ca4ff74].</li>
    <li>Formally support the SQL type name BOOLEAN in addition to BOOL. Fix for [544dba0a2f].</li>
    <li>Make sure the SQLiteConvert.TypeNameToDbType method is thread-safe. Fix for [84718e79fa].</li>
</ul>
<p>
    <b>1.0.76.0 - October 4, 2011</b>
</p>
<ul>
    <li>Prevent the domain unload event handler in SQLiteLog from being registered multiple times. Fix for [0d5b1ef362].</li>
    <li>Stop allowing non-default application domains to initialize the SQLiteLog class. Fix for [ac47dd230a].</li>
</ul>
<p>
    <b>1.0.75.0 - October 3, 2011</b>
</p>
<ul>
    <li>Updated to SQLite 3.7.8 <a href="http://www.sqlite.org/src/info/3e0da808d2">[3e0da808d2]</a>.</li>
    <li>More enhancements to the build system.</li>
    <li>Add official <a href="http://www.nuget.org/">NuGet</a> packages for x86 and x64.</li>
    <li>Add Changes and LastInsertRowId properties to the connection class.</li>
    <li>Support more formats when converting data from/to the DateTime type.</li>
    <li>Make all the assembly versioning attributes consistent.</li>
    <li>Add unit testing infrastructure using <a href="http://eagle.to/">Eagle</a>.</li>
    <li>Integrate all legacy unit tests, including the &quot;testlinq&quot; project, into the new test suite.</li>
    <li>Add projects to build the interop assembly statically linked to the Visual C++ runtime. Fix for [53f0c5cbf6].</li>
    <li>Add SQLITE_ENABLE_STAT2 compile-time option to the interop assembly.  Fix for [74807fbf27].</li>
    <li>Fix mutex issues exposed when running the test suite with the debug version of SQLite.</li>
    <li>Fix transaction enlistment when repeated attempts are made to enlist in the same transaction. Fix for [ccfa69fc32].</li>
    <li>Support the SQLITE_FCNTL_WIN32_AV_RETRY file control to mitigate the impact of file sharing violations caused by external processes.</li>
    <li>Refactor the logging interface to be thread-safe and self-initializing.</li>
    <li>Shutdown the SQLite native interface when the AppDomain is being unloaded. Fix for [b4a7ddc83f].</li>
    <li>Support Skip operation for LINQ using OFFSET. Fix for [8b7d179c3c].</li>
    <li>Support EndsWith operation for LINQ using SUBSTR. Fix for [59edc1018b].</li>
    <li>Support all SQLite journal modes. Fix for [448d663d11].</li>
    <li>Do not throw exceptions when disposing SQLiteDataReader. Fix for [e1b2e0f769].</li>
    <li>The REAL type should be mapped to System.Double. Fix for [2c630bffa7] and [b0a5990f48].</li>
    <li>Minor optimization to GetParamValueBytes(). Fix for [201128cc88].</li>
    <li>Support the ON UPDATE, ON DELETE, and MATCH clause information when generating schema metadata for foreign keys. Partial fix for [b226147b37]. VS designer changes are not yet tested.</li>
    <li>Fix incorrect resource name for SR.resx in the mixed-mode assembly.</li>
    <li>Reduce the number of String.Compare() calls in the hot path for SQLiteCommand.ExecuteReader().</li>
</ul>
<p>
    <b>1.0.74.0 - July 4, 2011</b>
</p>
<ul>
    <li>Updated to SQLite 3.7.7.1 <a href="http://www.sqlite.org/src/info/af0d91adf4">[af0d91adf4]</a>.</li>
    <li>Fix incorrect hard-coded .NET Framework version information SQLiteFactory_Linq.cs that was causing IServiceProvider.GetService to fail when running against the .NET Framework 3.5.</li>
    <li>Fix all XML documentation warnings.</li>
    <li>Restore support for the mixed-mode assembly (i.e. the one that can be registered in the Global Assembly Cache).</li>
    <li>Restore support for the Compact Framework.</li>
    <li>Remove unused &quot;using&quot; statements from the System.Data.SQLite and System.Data.SQLite.Linq projects.</li>
    <li>Remove hard-coded System.Data.SQLite.Linq version from SQLiteFactory_Linq.cs</li>
    <li>Modify the setup to support bundled packages (i.e. with the mixed-mode assembly) and standard packages (i.e. with the managed assembly separate from the native interop library).</li>
    <li>Disable the ability to register with the Global Assembly Cache in the standard setup package (i.e. it is available in the bundled setup only).</li>
    <li>Remove PATH modification from the setup.</li>
    <li>Modify the naming scheme for the source, setup, and binary packages to allow for the necessary variants.</li>
    <li>In the build automation, attempt to automatically detect if Visual Studio 2008 and/or 2010 are installed and support building binaries for both at once, when available.</li>
    <li>Add release automation to build the source, setup, and binary packages in all supported build variants.</li>
    <li>Add the testlinq project to the new build system and make it work properly with Visual Studio 2008 and 2010.</li>
</ul>
<p>
  <b>1.0.73.0 - June 2, 2011</b>
</p>
<ul>
  <li>Updated to SQLite 3.7.6.3 <a href="http://www.sqlite.org/src/info/ed1da510a2">[ed1da510a2]</a>
  <li>Minor optimization to GetBytes(). Fix for [8c1650482e].</li>
  <li>Update various assembly information settings.</li>
  <li>Correct System.Data.SQLite.Linq version and resource information. Fix for [6489c5a396] and [133daf50d6].</li>
  <li>Moved log handler from SQLiteConnection object to SQLiteFactory object to prevent if from being prematurely GCed.</li>
  <li>We should block x64 installs on x86 and we should install native only if the setup package itself is native. Fix for [e058ce156e].</li>
</ul>
<p>
  <b>1.0.72.0 - May 1, 2011</b>
</p>
<ul>
  <li>Add the correct directory to the path. Fix for [50515a0c8e].</li>
</ul>
<p>
  <b>1.0.71.0 - April 27, 2011</b>
</p>
<ul>
  <li>Updated to SQLite 3.7.6+ <a href="http://www.sqlite.org/src/info/1bd1484cd7">[1bd1484cd7]</a>

   to get additional Windows error logging.</li>
  <li>Updated setup to optionally add install directory to PATH if GAC option selected.</li>
</ul>
<p>
  <b>1.0.70.0 - April 22, 2011</b>
</p>
<ul>
  <li>Added support for sqlite3_extended_result_codes(), sqlite3_errcode(), and sqlite3_extended_errcode()
        via SetExtendedResultCodes(), ResultCode(), and ExtendedResultCode().</li>
  <li>Added support for SQLITE_CONFIG_LOG via SQLiteLogEventHandler().</li>
</ul>
<p>
  <b>1.0.69.0 - April 12, 2011</b>
</p>
<ul>
  <li>Code merge with SQLite 3.7.6</li>
  <li>New VS2008 and VS2010 solution files</li>
  <li>Build and packaging automation</li>
  <li>New Inno Setup files</li>
  <li>Designer support currently not ready for release</li>
</ul>
<p>
  <b>1.0.68.0 - February 2011</b>
</p>
<ul>
  <li>Code merge with SQLite 3.7.5</li>

  <li>Continuing work on supporting Visual Studio 2010</li>
</ul>

<p>
<b>1.0.67.0 - January 3, 2011</b></p>
<ul>
<li>Code merge with SQLite 3.7.4</li>
<li>Continuing work on supporting Visual Studio 2010</li>
</ul>
<p>
<b>1.0.66.1 - August 1, 2010</b></p>
<ul>
<li>Code merge with SQLite 3.7.0.1</li>
<li>Re-enabled VS2005 designer support, broken in previous versions during the 2008
transition</li>
<li>Implemented new forms of Take/Skip in the EF framework courtesy jlsantiago</li>
<li>Added "Foreign Keys" to the connection string parameters</li>
<li>Added the Truncate option to the Journal Modes enumeration</li>
</ul>
<p>
<b>1.0.66.0 - April 18, 2010</b></p>
<ul>
<li>Code merge with SQLite 3.6.23.1</li>
<li>Fixed a bug in the installer that accidentally modified the machine.config on
.NET versions prior to 2.0, invaliding the config file.</li>
<li>Fixed INTERSECT and EXCEPT union query generation in EF</li>
<li>Fixed an out of memory error in the trigger designer in cases where a WHEN clause
is used in the trigger</li>
</ul>
<p>
<b>1.0.65.0 - July 26, 2009</b></p>
<ul>
<li>Fixed a bug in the encryption module to prevent a double free() when rekeying
a database.</li>
<li>Fixed a bug in the encryption module when ATTACHing an encrypted database.</li>
<li>Incorporated the WinCE locking fix from ticket <a href="http://www.sqlite.org/cvstrac/tktview?tn=3991">
#3991</a></li>
<li>Added &quot;bigint&quot; to the dropdown in the table designer, plus other minor
table designer bugfixes.</li>
</ul>
<p>
<b>1.0.64.0 - July 9, 2009</b></p>
<ul>
<li>Fixed the missing resources problem from the 63 release.</li>
<li>Added preliminary support for the Visual Studio 2010 beta.</li>
<li>Fixed a bug in SQLiteCommand that threw a null reference exception when setting
the Transaction object to null.</li>
<li>If SQLiteConnection.EnlistTransaction is called multiple times for the same
transaction scope, just return without throwing an error.</li>
</ul>
<p>
<b>1.0.63.0 - June 29, 2009</b></p>
<ul>
<li>Code merge with SQLite 3.6.16</li>
<li>Check the autocommit mode of the connection to which a transaction is bound
during the disposal of the transaction.&nbsp; If autocommit is enabled, then the
database has already rolled back the transaction and we don&#39;t need to do it
during dispose, and can quietly ignore the step without throwing an error.</li>
<li>Eliminated the mergebin step altogether.&nbsp; It was developed primarily to
merge the Compact Framework binaries together, but since we&#39;re not doing that
anymore, its use is limited.&nbsp; Its non-standard method of merging a binary on
the desktop framework is redundant as well.&nbsp; The desktop binary now hard-links
to MSCOREE, but as of Windows XP, this was redundant as well since XP and beyond
automatically attempt to load MSCOREE on startup when a DLL has a .NET header.</li>
<li>More improvements to the test.exe program for running the tests against Sql
Server for comparison purposes.</li>
</ul>
<p>
<b>1.0.62.0 - June 19, 2009</b></p>
<ul>
<li>Code merge with SQLite 3.6.15</li>
<li>Fixed the decimal reading bug in the SQLiteDataReader</li>
<li>Changed Join()&#39;s to Sleep()&#39;s in the statement retry code to prevent
message pumping</li>
<li>Fixed a bad pointer conversion when retrieving blobs using GetBytes() in 64-bit
land</li>
<li>Several changes to the Test program that comes with the provider.&nbsp; Tests
can now be individually disabled, and the test program can run against several provider
back-ends</li>
</ul>
<p>
<b>1.0.61.0 - April 28, 2009</b></p>
<ul>
<li>Code merge with SQLite 3.6.13. The new backup features are as yet unimplemented
in the provider, but will be forthcoming in a subsequent release</li>
<li>Fixed the default-value lookups in SQLiteConnectionStringBuilder when accessing
properties</li>
<li>Lock the SQLiteTransaction object during dispose to avoid potential race condition
during cleanup</li>
<li>Fixed SQLiteDataReader.GetDecimal() processing and parsing of decimal values
for cases when SQLite returns things like "1.0e-05" instead of "0.0001"</li>
</ul>
<p>
<b>1.0.60.0 - October 3, 2008</b></p>
<ul>
<li>Throw a NotSupported exception in the EF Sql Gen code instead of parsing illegal
SQL during an update/insert/delete where no primary key is defined.</li>
<li>Fixed the Compact Framework interop library.&nbsp; Since the linker flag /subsystem
had no version specified, it was causing a problem for many CE-based platforms.</li>
<li>Incorporated SQLite patch for ticket <a href="http://www.sqlite.org/cvstrac/tktview?tn=3387">
#3387</a> and reverted out the vfs override code I added in build 59 to work around
this problem.</li>
<li>Fixed a designer issue when creating a new table from the Server Explorer.&nbsp;
After initially saving it, if you then continued to edit it and tried to save it
again, it would generate the change SQL using the old temporary table name rather
than the new name.</li>
</ul>
<p>
<b>1.0.59.0 - September 22, 2008</b></p>
<ul>
<li>Code merge with SQLite 3.6.3.&nbsp; Solves a couple different EF issues that
were either giving inconsistent results or crashing the engine.</li>
<li>Fixed the parsing of literal binaries in the EF SqlGen code.&nbsp; SQLite now
passes nearly all the testcases in <a href="http://sqlite.phxsoftware.com/forums/p/1377/5921.aspx#5921">
Microsoft's EF Query Samples</a> application -- the exception being the <i>datetimeoffset
</i>and<i> time</i> constants tests, and tests that use the <i>APPLY </i>keyword
which are unsupported for now.</li>
<li>Revamped the Compact Framework mixed-mode assembly.&nbsp; Tired of playing cat
and mouse with the Compact Framework&#39;s support for mixed-mode assemblies.&nbsp;
The CF build now requires that you distribute both the System.Data.SQLite library
and the paired SQLite.Interop.XXX library.&nbsp;&nbsp; The XXX denotes the build
number of the library.</li>
<li>Implemented a workaround for Vista&#39;s overzealous caching by turning off
FILE_FLAG_RANDOM_ACCESS for OS versions above XP.&nbsp; This is implemented as a
custom (default override) VFS in the interop.c file, so no changes are made to the
SQLite source code.</li>
<li>Fixed some registry issues in the designer install.exe, which prevented some
design-time stuff from working on the Compact Framework when .NET 3.5 was installed.</li>
</ul>
<p>
<b>1.0.58.0 - August 30, 2008</b></p>
<ul>
<li>Code merge with SQLite 3.6.2.&nbsp; If only I&#39;d waited one more day to release
57!&nbsp; Several LINQ issues have been resolved with this engine release relating
to deeply-nested subqueries that the EF SqlGen creates.</li>
<li>The Rollback SQLiteConnection event no longer requires an open connection in
order to subscribe to it.&nbsp; Missed this one in the 57 release.</li>
</ul>
<p>
<b>1.0.57.0 - August 29, 2008</b></p>
<ul>
<li>Compiled against 3.6.1 with checkin <a href="http://www.sqlite.org/cvstrac/tktview?tn=3300">
#3300</a> resolved, which fixes an Entity Framework bug I was seeing.&nbsp; I currently
have 3 other tickets out on the engine, which are not yet resolved and relate to
EF.</li>
<li>Fixed decimal types to store and fetch using InvariantCulture.&nbsp; If you&#39;re
using decimal datatypes in your database and were affected by the 56 release, please
issue an UPDATE &lt;table&gt; SET &lt;column&gt; = REPLACE(&lt;column&gt;, &#39;,&#39;,
&#39;.&#39;);&nbsp; to fix the decimal separators.&nbsp; Apologies for not testing
that more thoroughly before releasing 56.</li>
<li>Too many LINQ fixes to list.&nbsp; Fixed views so they generate, fixed the LIMIT
clause, implemented additional functionality and removed unnecessary code.</li>
<li>Fixed foreign key names in the designer so viewing the SQL script on a new unsaved
table after renaming it in the properties toolwindow will reflect in the script
properly.</li>
<li>Fixed the Update and Commit events on SQLiteConnection so they don&#39;t require
the connection to be opened first.</li>
<li>Fixed userdef aggregate functions so they play nice with each other when appearing
multiple times in the same statement.</li>
<li>Fixed the editing and saving of default values in the table designer.</li>
<li>Fixed ForeignKeys schema to support multi-column foreign keys.&nbsp; Also hacked
support for them in the table designer, provided two foreign keys in the designer
have the same name and reference the same foreign table and different columns.&nbsp;
Will implement first-class support for this in the next release.</li>
</ul>
<p>
<b>1.0.56.0 - August 11, 2008</b></p>
<ul>
<li>Fixed a bug in the table designer when designing new tables, wherein you had
to save the table first before being able to create indexes and foreign keys.</li>
<li>Tweaks to decimal type handling.&nbsp; The &#39;decimal&#39; type can&#39;t
be represented by Int64 or Double (without loss of precision) in SQLite, so we have
to fudge it by treating it like a string and converting it back and forth in the
provider.&nbsp; Unfortunately backing it to the db as a string causes sorting problems.&nbsp;
See <a href="http://sqlite.phxsoftware.com/forums/p/1296/5595.aspx#5595">this post</a>
for details on using a custom collation sequence to overcome the sorting issue arising
from this patch.</li>
<li>Minor tweaks and bugfixes to the test program and the provider.</li>
<li>More adjustments to make the managed-only version of the provider run and pass
all tests on Mono.</li>
<li>LINQ to Entities bits heavily updated and compiled against VS2008 SP1 RTM.&nbsp;
SQLite LINQ support is still considered beta.</li>
</ul>
<p>
<b>1.0.55.0 - August 6, 2008</b></p>
<ul>
<li>Code merge with SQLite 3.6.1</li>
<li>Added support for the user-contributed extension-functions at <a href="http://www.sqlite.org/contrib">
http://www.sqlite.org/contrib</a>.&nbsp; Feel free to override any of them with
your own implementation.&nbsp; The new functions are: <i>acos, asin, atan, atn2,
atan2, acosh, asinh, atanh, difference, degrees, radians, cos, sin, tan, cot, cosh,
sinh, tanh, coth, exp, log, log10, power, sign, sqrt, square, ceil, floor, pi, replicate,
charindex, leftstr, rightstr, reverse, proper, padl, padr, padc, strfilter,</i>
and aggregates <i>stdev, variance, mode, median, lower_quartile, upper_quartile.</i></li>
<li>Moved the last_rows_affected() function to the C extension library.</li>
<li>Added a new class, SQLiteFunctionEx which extends SQLiteFunction and adds the
ability for a user-defined function to get the collating sequence during the Invoke/Step
methods.&nbsp; User-defined functions can use the collating sequence as a helper
to compare values.</li>
<li>When registering user-defined collation sequences and functions, the provider
will now register both a UTF8 and a UTF16 version instead of just UTF8.</li>
<li>Revamped connection pooling and added static ClearPool() and ClearAllPools()
functions to SQLiteConnection.&nbsp; Behavior of the pool and its clearing mechanics
match SqlClient.</li>
<li>Fixed connections going to the pool so that any unfinalized lingering commands
from un-collected datareaders are automatically reset and any lurking transactions
made on the connection are rolled back.</li>
<li>Transaction isolation levels are now partially supported.&nbsp; Serializable
is the default, which obtains read/write locks immediately -- this is compatible
with previous releases of the provider.&nbsp; Unspecified will default to whatever
the default isolation mode is set to, and ReadCommitted will cause a deferred lock
to be obtained.&nbsp; No other values are legal.</li>
<li>Revamped the test.exe program.&nbsp; It&#39;s now an interactive GUI application.&nbsp;
Easier for me to add tests now.</li>
<li>Tweaks to the VS designer package and installer.</li>
<li>More adjustments to the internal SQLite3.Prepare() method to account for both
kinds of lock errors when retrying.</li>
<li>Stripped a lot of unnecessary interop() calls and replaced with base sqlite
calls.&nbsp; Revamped most of UnsafeNativeMethods to make it easier to port the
code.</li>
<li>Rerigged internal callbacks for userdef functions and other native to managed
callbacks.&nbsp; More portable this way.</li>
<li>Source can now can be compiled with the SQLITE_STANDARD preprocessor symbol
to force the wrapper to use the stock sqlite3 library.&nbsp; Some functionality
is missing, but its minimal.&nbsp; None of the precompiled binaries are compiled
using this setting, but its useful for testing portability.</li>
<li>Added &quot;boolean&quot; and a couple other missing datatypes to the &quot;DataTypes&quot;
schema xml file.&nbsp; Used by the VS designer when displaying tables and querying.</li>
<li>Added a new connection string option &quot;Read Only&quot;.&nbsp; When set to
True, the database will be opened in read-only mode.</li>
<li>Added a new connection string option &quot;Max Pool Size&quot; to set the maximum
size of the connection pool for a given db file connection.</li>
<li>Added a new connection string option &quot;Default IsolationLevel&quot; to set
the default isolation level of transactions.&nbsp; Possible values are Serializable
and ReadCommitted.</li>
<li>Added a new connection string option &quot;URI&quot; as an optional parameter
for compatibility with other ports of the provider.</li>
</ul>
<p>
<b>1.0.54.0 - July 25, 2008</b></p>
<ul>
<li>Fixed the setup project, which somehow &quot;forgot&quot; to include all the
binaries in the 53 release.</li>
<li>Fixed a crash in the table designer when creating a new table and tabbing past
the &quot;Allow Nulls&quot; cell in the grid while creating a new column.</li>
<li>Fixed a mostly-benign bug in SQLiteDataReader&#39;s GetEnumerator, which failed
to pass along a flag to the underyling DbEnumerator it creates.&nbsp; This one&#39;s
been around since day 1 and nobody&#39;s noticed it in all these years.</li>
<li>Added a new connection string parameter &quot;Journal Mode&quot; that allows
you to set the SQLite journal mode to Delete, Persist or Off.</li>
</ul>
<p>
<b>1.0.53.0 - July 24, 2008</b></p>
<ul>
<li>Enabled sqlite_load_extension</li>
<li>Added retry/timeout code to SQLite3.Prepare() when preparing statements for
execution and a SQLITE_BUSY error occurs.</li>
<li>Added a new schema to SQLiteConnection.GetSchema() called <i>Triggers</i>.&nbsp;
Used to retrieve the trigger(s) associated with a database and/or table/view.</li>
<li>Extensive updates to table/view editing capabilities inside Visual Studio&#39;s
Server Explorer.&nbsp; The program now parses and lets you edit CHECK constraints
and triggers on a table, as well as define triggers on views.&nbsp; Experimental
still, so e-mail me if you have issues.</li>
<li>Minor bugfix to the ViewColumns schema to return the proper base column name
for a view that aliases a column.</li>
<li>Fixed the insert/update/delete DML support in the Linq module.</li>
<li>Changed the behavior of SQLiteCommand to allow a transaction to be set even
if the command hasn&#39;t been associated with a connection yet.</li>
</ul>
<p>
<b>1.0.52.0 - July 16, 2008</b></p>
<ul>
<li>Code merge with SQLite 3.6.0</li>
<li>Added a lot of previously-missing exports to the DEF file for the native library.</li>
<li>Fixed SQLiteDataReader to check for an invalid connection before operating on
an open cursor.</li>
<li>Implemented the Cancel() function of SQLiteCommand to cancel an active reader.</li>
<li>Added beta table and view designers to the Visual Studio Server Explorer.&nbsp;
You can now edit/create tables and views, manage indexes and foreign keys from Visual
Studio.&nbsp; This feature is still undergoing testing so use at your own risk!</li>
<li>Fixed the Server Explorer so VS2005 users can once again right-click tables
and views and open the table data.</li>
<li>Added some new interop code to assist in returning more metadata not normally
available through the SQLite API.&nbsp; Specifically, index column sort modes and
collating sequences.&nbsp; Also added code to detect (but not parse) CHECK constraints,
so the table designer can pop up a warning when editing a table with these constraints.&nbsp;
Since I can&#39;t currently parse them.</li>
<li>Lots of LINQ SQL generation improvements and fixes.</li>
<li>Made some progress cleaning up and fixing up the schema definitions and manifests
for EdmGen.</li>
<li>Added a built-in SQLiteFunction called last_rows_affected() which can be called
from SQL to get the number of rows affected by the last update/insert operation
on the connection.&nbsp; This is roughly equivalent to Sql Server&#39;s @@ROWCOUNT
variable.</li>
</ul>
<p>
<b>1.0.51.0 - July 1, 2008</b></p>
<ul>
<li><b>VS2008 SP1 Beta1 LINQ Support</b></li>
<li>Added experimental Entity Framework support in a new library, System.Data.SQLite.Linq.&nbsp;
Some things work, some don&#39;t.&nbsp; I haven&#39;t finished rigging everything
up yet.&nbsp; The core library remains stable.&nbsp; All LINQ-specific code is completely
separate from the core.</li>
<li>Added some columns to several existing schemas to support some of the EDM framework
stuff.</li>
<li>Minor tweaks to the factory to better support dynamic loading of the Linq extension
library for SQLite.</li>
<li>SQLite&#39;s busy handler was interfering with the provider&#39;s busy handling
mechanism, so its been disabled.</li>
</ul>
<p>
<b>1.0.50.0 - June 27, 2008</b></p>
<ul>
<li>Fixed some lingering dispose issues and race conditions when some objects were
finalized.</li>
<li>Fixed the SQLiteConvert.Split() routine to be a little smarter when splitting
strings, which solves the quoted data source filename problem.</li>
<li>Enhanced the mergebin utility to work around the strong name validation bug
on the Compact Framework.&nbsp; The old workaround kludged the DLL and caused WM6.1
to fail to load it.&nbsp; This new solution is permanent and no longer kludges the
DLL.</li>
</ul>
<p>
<b>1.0.49.0 - May 28, 2008</b></p>
<ul>
<li>Code merge with SQLite 3.5.9</li>
<li>Fixed schema problems when querying the TEMP catalog.</li>
<li>Changed BLOB datatype schema to return IsLong = False instead of True.&nbsp;
This was preventing DbCommandBuilder from using GUID's and BLOB's as primary keys.</li>
<li>Fix rollover issue with SQLite3.Reset() using TickCount.</li>
<li>Fixed SQLiteDataReader to dispose of its command (if called for) before closing
the connection (when flagged to do so) instead of the other way around.</li>
<li>Fixed a DbNull error when retrieving items not backed by a table schema.</li>
<li>Fixed foreign key constraint parsing bug.</li>
<li>Added FailIfMissing property to the SQLiteConnectionStringBuilder.</li>
<li>Converted the source projects to Visual Studio 2008.</li>
</ul>
<p>
<b>1.0.48.0 - December 28, 2007</b></p>
<ul>
<li>Code merge with SQLite 3.5.4</li>
<li>Calling SQLiteDataReader.GetFieldType() on a column with no schema information
and whos first row is initially NULL now returns type Object instead of type DbNull.</li>
<li>Added support for a new DateTime type, JulianDay.&nbsp; SQLite uses Julian dates
internally.</li>
<li>Added a new connection string parameter "Default Timeout" and a corresponding
method on the SQLiteConnection object to change the default command timeout.&nbsp;
This is especially useful for changing the timeout on transactions, which use SQLiteCommand
objects internally and have no ADO.NET-friendly way to adjust the command timeout
on those commands.</li>
<li>FTS1 and FTS2 modules were removed from the codebase.&nbsp; Please upgrade all
full-text indexes to use the FTS3 module.&nbsp;</li>
</ul>
<p>
<b>1.0.47.2 - December 10, 2007</b></p>
<ul>
<li>Fixed yet one more bug when closing a database with unfinalized command objects</li>
<li>Fixed the DataReader's GetFieldType function when dealing with untyped SQLite
affinities</li>
</ul>
<p>
<b>1.0.47.1 - December 5, 2007</b></p>
<ul>
<li>Fixed a leftover bug from the codemerge with SQLite 3.5.3 that failed to close
a database.</li>
<li>Fixed the broken Compact Framework distribution binary.</li>
<li>SQLite 3.5.x changed some internal infrastructure pieces in the encryption interface
which I didn't catch initially.&nbsp; Fixed.&nbsp;</li>
</ul>
<p>
<b>1.0.47.0 - December 4, 2007</b></p>
<ul>
<li>Code merge with SQLite 3.5.3</li>
<li>Added installer support for Visual Studio 2008.&nbsp; Code is still using the
VS2005 SDK so one or two bells and whistles are missing, but nothing significant.</li>
<li>This is the last version that the FTS1 and FTS2 extensions will appear.&nbsp;
Everyone should rebuild their fulltext indexes using the new FTS3 module.&nbsp;
FTS1 and FTS2 suffer from a design flaw that could cause database corruption with
certain vacuum operations.</li>
<li>Fixed pooled connections so they rollback any outstanding transactions before
going to the pool.&nbsp; </li>
<li>Fixed the unintended breaking of the TYPES keyword, and mis-typing of untyped
or indeterminate column types. </li>
<li>Assert a FileIOPermission() requirement in the static SQLiteFunction constructor.
</li>
<li>The CE-only SQLiteFunction.RegisterFunction() is now available on the desktop
platform for dynamic registration of functions.&nbsp; You must still close and re-open
a connection in order for the new function to be seen by a connection.</li>
<li>Fixed the "database is locked" errors by implementing behavioral changes in
the interop.c file for SQLite.&nbsp; Closing a database force-finalizes any prepared
statements on the database to ensure the connection is fully closed.&nbsp; This
was rather tricky because the GC thread could still be finalizing statements itself.
&nbsp;</li>
<li>Modifed the mergebin utility to help circumvent a long-standing strong name
verification bug in the Compact Framework.</li>
</ul>
<p>
<b>1.0.46.0 - September 30, 2007</b></p>
<ul>
<li>Fixed faulty logic in type discovery code when using SQLiteDataReader.GetValue().</li>
<li>Fixed Connection.Open() bug when dealing with :memory: databases.</li>
<li>Fixed SQLiteCommand.ExecuteScalar() to return a properly-typed value.</li>
<li>Added support for SQLiteParameter.ResetDbType().</li>
<li>Added test cases for rigid and flexible type testing.</li>
</ul>
<p>
<b>1.0.45.0 - September 25, 2007</b></p>
<ul>
<li><strong>Breaking change in GetSchema("Indexes") </strong>-- MetaDataCollections
restrictions and identifier parts counts were wrong for this schema and I was using
the wrong final parameter as the final restriction.&nbsp; Meaning, if you use the
Indexes schema and are querying for a specific index the array should now be {catalog,
null, table, index } instead of {catalog, null, table, null, index}</li>
<li>Code merge with SQLite 3.4.2</li>
<li>Fixed some errors in the encryption module, most notably when a non-default
page size is specified in the connection string. </li>
<li>Fixed SQLiteDataReader to better handle type-less usage scenarios, which also
fixes problems with null values and datetimes.</li>
<li>Fixed the leftover temp files problem on WinCE </li>
<li>Added connection pooling.&nbsp; The default is disabled for now, but may change
in the future.&nbsp; Set "Pooling=True" in the connection string to enable it. </li>
<li>Sped up SQLiteConnection.Open() considerably.</li>
<li>Added some more robust cleanup code regarding SQLiteFunctions.</li>
<li>Minor additions to the code to allow for future LINQ integration into the main
codebase.</li>
<li>Fixed a long-standing bug in the Open() command of SQLiteConnection which failed
to honor the documented default behavior of the SQLite.NET provider to open the
database in "Synchronous=Normal" mode.&nbsp; The default was "Full". </li>
<li>If Open() fails, it no longer sets the connection state to Broken.&nbsp; It
instead reverts back to Closed, and cleans up after itself.</li>
<li>Added several new parameters to the ConnectionString for setting max page count,
legacy file format, and another called FailIfMissing to raise an error rather than
create the database file automatically if it does not already exist.</li>
<li>Fixed some designer toolbox references to the wrong version of the SQLite.Designer</li>
<li>Fixed a bug in the mergebin utility with regards to COR20 metadata rowsize computations.&nbsp;
</li>
<li>Minor documentation corrections &nbsp;&nbsp;</li>
</ul>
<p>
<b>1.0.44.0 - July 21, 2007</b></p>
<ul>
<li>Code merge with SQLite 3.4.1</li>
<li>Fixed a bug in SQLiteConnection.Open() which threw the wrong kind of error in
the wrong kind of way when a database file could not be opened or created.&nbsp;</li>
<li>Small enhancements to the TYPES keyword, and added documentation for it in the

help file.</li>
<li>Hopefully fixed the occasional SQLITE_BUSY errors that cropped up when starting
a transaction.&nbsp; Usually occurred in high-contention scenarios, and the underlying
SQLite engine bypasses the busy handler in this scenario to return immediately.</li>
</ul>
<p>
<b>1.0.43.0 - June 21, 2007</b></p>
<ul>
<li>Code merge with SQLite 3.4.0</li>
<li>Fixed a reuse bug in the SQLiteDataAdapter in conjunction with the SQLiteCommandBuilder.&nbsp;
It's been there unnoticed for more than a year, so it looks like most folks never
encountered it. </li>
<li>Fixed an event handler bug in SQLiteCommandBuilder in which it could fail to
unlatch from the DataAdapter when reused.&nbsp; Relates to the previous bugfix.</li>
<li>Fixed a double-dispose bug in SQLiteStatement that triggered a SQLiteException.&nbsp;</li>
</ul>
<p>
<b>1.0.42.0 - June 1, 2007</b></p>
<ul>
<li>Code merge with SQLite 3.3.17</li>
<li>Changed the SQLiteFunction static constructor so it only enumerates loaded modules
that have referenced the SQLite assembly, which hopefully should cut down dramatically
the time it takes for that function to execute.&nbsp;</li>
<li>Added the FTS2 full-text search extension to the project.&nbsp; Look for FTS1
to disappear within the next couple of revisions.&nbsp;</li>
<li>Fixed a bug introduced with the finalizers that triggered an error when statements
ended with a semi-colon or had other non-parsable comments at the end of a statement&nbsp;</li>
<li>Fixed an intermittent multi-threaded race condition between the garbage collector
thread and the main application thread which lead to an occasional SQLITE_MISUSE
error.</li>
<li>Fixed another issue relating to SQLite's inherent typelessness when dealing
with aggregate functions which could return Int64 or Double or even String for a
given row depending on what was aggregated.</li>
<li>Remembered to recompile the DDEX portion of the engine this time, so Compact
Framework users can once again use the design-time functionality</li>
</ul>
<p>
<b>1.0.41.0 - April 23, 2007</b></p>
<ul>
<li>Code merge with SQLite 3.3.16</li>




<li>Second go at implementing proper finalizers to cleanup after folks who've forgotten
to Dispose() of the SQLite objects</li>
<li>Enhanced GetSchema(IndexColumns) to provide numeric scale and precision values</li>
<li>Fixed the column ordinals in GetSchema(IndexColumns) to report the ordinal of
the column in the index, not the table</li>
<li>Fixed a bug whereby parameters named with an empty string (such as String.Empty)
were treated like a named parameter instead of an unnamed parameter</li>
</ul>
<p>
<b>1.0.40.0 - January 31, 2007</b></p>
<ul>
<li>Code merge with SQLite 3.3.12</li>
<li>Lots of new code to handle misuse of the library.&nbsp; Implemented finalizers
where it made sense, fixed numerous garbage collector issues when objects are not
disposed properly, &nbsp;fixed some object lifetime issues, etc.</li>
<li>A failed Commit() on a transaction no longer leaves the transaction in an unusable
state.</li>
</ul>
<p>
<b>1.0.39.1 - January 11, 2007</b></p>
<ul>
<li>Fixed a really dumb mistake that for some reason didn't trigger any errors in
the testcases, whereby commands when associated with a connection were not adding
or removing themselves from an internal list of commands for that connection --
causing a "database is locked" error when trying to close the connection.</li>
</ul>
<p>
<b>1.0.39.0 - January 10, 2007</b></p>
<ul>
<li>Code merge with SQLite 3.3.10</li>
<li>Fixed a multi-threaded race condition bug in the garbage collector when commands
and/or connections are not properly disposed by the user. </li>
<li>Switched the encryption's internal deallocation code to use sqlite's built-in
aux functions instead of modifying the pager.c source to free the crypt block.&nbsp;
This eliminates the last of the code changes the provider makes to the original
SQLite engine sources.&nbsp; Props to Ralf Junker for pointing that out.</li>
</ul>
<p>
<b>1.0.38.0 - November 22, 2006</b></p>
<ul>
<li>Fixed a bug when using CommandBehavior.KeyInfo whereby integer primary key columns
may be duplicated in the results. </li>
<li>Enhanced the CommandBuilder so that update/delete statements are optimized when
the affected table contains unique constraints and a primary key is present.</li>
<li>Fixed a bug in the DataReader when used in conjunction with CommandBehavior.CloseConnection.</li></ul>
<p>
<b>1.0.37.0 - November 19, 2006</b></p>
<ul>
<li>Added support for CommandBehavior.KeyInfo.&nbsp; When specified in a query,
additional column(s) will be returned describing the key(s) defined for the table(s)
selected in the query.&nbsp; This is optimized when INTEGER PRIMARY KEY is set for
the given tables, but does additional work for other kinds of primary keys.</li>
<li>Removed the default values from SQLiteDataReader.GetTableSchema(), to better
follow Sql Server's pattern and suppress schema errors when loading the records
into a dataset/datatable.</li>
<li>Allow integers to implicitly convert to double/decimal/single.</li></ul>
<p>
<b>1.0.36.1 - October 25, 2006</b></p>
<ul>
<li>Added support for LONGVARCHAR, SMALLDATE and SMALLDATETIME. These were actually
added in 1.0.36.0 but were undocumented.</li>
<li>Fixed the embedded helpfile which was accidentally built from old sources. </li>
<li>Fixed an unfortunate re-entry of a bug in the .36 codebase that caused the provider
to "forget" about commands on a connection under certain circumstances.</li>
</ul>
<p>
<b>1.0.36.0 - October 23, 2006</b></p>
<ul>
<li>Code merge with SQLite 3.3.8, including support for full-text search via the
FTS1 extension.&nbsp;</li><li>Fixed a bug retrieving data types when UseUtf16Encoding
is true. Side-effect of further merging the common code between the two base classes.</li>
<li>Fixed a bug with System.Transactions whereby a connection closed/disposed within
a transaction scope is rolled back and cannot be committed.</li>
<li>Added more error checking and reporting to transactions to help user's isolate
the source of transaction failures.</li>
<li>Implemented a workaround for a Compact Framework issue regarding strong-named
assemblies containing a PE section with a raw size less than the virtual size.&nbsp;</li>
</ul>
<p>
<b>1.0.35.1 - September 12, 2006</b></p>
<ul>
<li>Fixed the TYPES keyword to work when UseUTF16Encoding is true.</li>
<li>Fix another bug revealed in 1.0.35.0 regarding infinite loops when the 2nd or
subsequent statements of a semi-colon separated command cannot be parsed.</li>
<li>Updated the help documentation.&nbsp;</li>
</ul>
<p>
<b>1.0.35.0 - September 10, 2006</b></p>
<ul>
<li>Fixed an infinite loop bug in SQLiteCommand caused when multiple semi-colon
separated statements in a single command are executed via datareader and one of
the statements contains a syntax error preventing it from being prepared.&nbsp;</li><li>
Added the TYPES preparser keyword to be placed before a SELECT statement to aid
the wrapper in converting expressions in a subsequent select clause into more robust
types.&nbsp; Documentation yet to be integrated, but available on the forums.</li>
<li>Added a new connectionstring parameter "BinaryGUID=true/false" (default is "true").&nbsp;
When true, guid types are stored in the database as binary blobs to save space.&nbsp;
Binary has been the default format since 1.0.32.0 but this parameter eases backward
compatibility.</li>
</ul>
<p>
<b>1.0.34.0 - September 4, 2006</b></p>
<ul>
<li>Fixed a bug in SQLiteParameterCollection.RemoveAt(namedparam)</li>
<li>Fixed a bug in SQLiteDataReader introduced in 1.0.30 that broke DateTimes using
the Ticks option in the connection string.</li>
<li>Fixed a bug in the recent changes to guid behavior wherein using a datareader's
indexer to fetch a guid from a column containing both binary and text guids would
sometimes return a byte array instead of a guid.</li>
<li>Enacted a workaround involving typed datasets in Compact Framework projects
in which it took an excessive amount of time to open a form and generated a lot
of temporary files in the user's Local Settings\Application Data\Microsoft\VisualStudio\8.0\Assembly
References folder.</li>
</ul>
<p>
<b>1.0.33.0 - August 21, 2006</b></p>
<ul>
<li>Code merge with SQLite 3.3.7</li>
<li>Fixed a bug in SQLiteConnection that caused it to "forget" about commands bound
to it and occasionally throw an error when a database is closed and opened repeatedly.&nbsp;
</li>
</ul>
<p>
<b>1.0.32.0 - August 6, 2006</b></p>
<ul>
<li>Added AllowPartiallyTrustedCallers attribute to the assembly</li><li>Added the
missing "nchar" type</li>
<li>Added support for binary Guid's.&nbsp; Guids are now stored as binary by default
when using parameterized queries.&nbsp; Text guids are still fully supported.</li>
<li>Fixed a TransactionScope() error that caused the transaction not to be completed.</li>
<li>Enhanced parameter names so that if they are added to the Parameters collection
without their prefix character (@ : or $) they are still properly mapped.&nbsp;</li>
</ul>
<p>
<b>1.0.31.0 - July 16, 2006</b></p>
<ul>
<li>Re-applied the view parsing bugfix in 1.0.29.0 that was accidentally reverted
out of the 30 build.</li><li>Fixed SQLiteCommand.ExecuteScalar() to return null
instead of DbNull.Value when no rows were returned.</li>
<li>Design-time installer now installs the package-based designer on full Visual
Studio versions.&nbsp; Express editions continue to use the packageless designer.</li>
<li>In Visual Studio (not Express), you can now right-click a SQLite connection
in the Server Explorer and vacuum the database and change the encryption password.</li>
</ul>
<p>
<b>1.0.30.1 - July 2, 2006</b></p>
<ul>
<li>Code merge with SQLite 3.3.6</li>
<li>Added support for the |DataDirectory| keyword in the Data Source filename string.&nbsp;
</li>
<li>Added hook notification support to SQLiteConnection.&nbsp; Specifically, there
are three new events on the SQLiteConnection object which are raised when an update/insert/delete
occurs and when transactions are committed and rolled back.</li><li>Changed SQLiteTransaction
to default to BEGIN IMMEDIATE instead of just BEGIN, which solves a multithreaded
race condition.&nbsp;</li>
<li>Changed SQLiteDataReader to better support SQLite's typelessness.&nbsp; The
data reader no longer caches column affinity, but re-evaluates it for each column/row.</li>
<li>Fixed a bug in Prepare() which caused an intermittant fault due to the code
accessing the memory of an unpinned variable.&nbsp;</li>
<li>Fixed a multithreaded lock-retry bug in in SQLiteConnection.Open() and in SQLiteTransaction,
which failed to use a command timeout before giving up.</li>
</ul>
<p>
<b>1.0.29.0 - May 16, 2006</b></p>
<ul>
<li>Fixed a bug in the Views schema information which caused multi-line view definition
statements not to be parsed</li>
<li>Fixed a parsing bug in SQLiteDataReader.GetSchemaTable() to account for numeric(x,y)
datatypes with specified precision and scale</li>
<li>Fixed a bug in SQLiteConnection.Open() which tried to automatically enlist in
an ambient transaction but had not yet set the state of the database to Opened,
thereby causing a transaction fault</li>
<li>Changed SQLiteException to inherit from DbException on the full framework</li>
</ul>
<p>
<b>1.0.28.0 - April 14, 2006</b></p>
<ul>
<li>Code merge with SQLite 3.3.5</li>
<li>You can now specify a relative path in the Compact Framework's "Data Source"
by prefixing the file with ".\".&nbsp; i.e. "Data Source=.\\mydb.db3"</li>
<li>Several more changes and enhancements to schemas for better compatibility.</li>
<li>Fixed several bugs with the 64-bit builds of the provider.&nbsp; The x64 binary
is now optimized.</li>
<li>Design-time installer now tries to install the 64-bit builds into the GAC along
with the 32-bit build.</li>
<li>Fixed a bug in the SQLiteDataReader.GetSchemaTable() function when used with
tables containing apostrophes.</li>
<li>Fixed an XSD-related bug whereby the XSD utility was unable to locate the provider
and could not generate typed datasets.</li>
<li>Added NTEXT and STRING datatypes to the list of recognized keywords (used for
schema retrieval).</li>
<li>Due to the XSD bug and other potential problems related to external build utilities,
changes to the installation of the designer have had to be made.&nbsp; The installer
used to write the DbProviderFactories XML into the devenv.exe.config file and its
express cousins, but now has to write instead to the machine.config.</li>
<li>Installer writes to both the 32-bit machine.config and the 64-bit machine.config
if it exists.&nbsp;</li>
</ul>
<p>
<b>1.0.27.1 - February 28, 2006</b></p>
<ul>
<li>Fixed a bug when doing data binding in Compact Framework projects that prevented
you from assigning a typed dataset to a bindingsource.&nbsp; It turns out, the CF
version of the SQLite provider needs to be flagged as retargetable so it'll work
in the design-time desktop environment.&nbsp; No changes were made to the desktop
build, but the revision was bumped on all libraries anyway in order to keep them
sync'd.&nbsp;</li></ul>
<p>
<b>1.0.27.0 - February 27, 2006</b></p>
<ul>
<li>Many optimizations and a few more minor adjustments to schemas and schema retrieval
performance.</li>
<li>Lots of design-time attributes added to the code.&nbsp; The DbDataAdapter, DbCommand,
and DbConnection objects now have greatly enhanced design-time capabilities when
added to the toolbox and dropped on a form.</li>
<li>Lots of Server Explorer enhancements.</li>
<li>Binaries are now distributed in a setup program for easier administration and
configuration of the provider.</li>
</ul>
<p>
<b>1.0.26.2 - February 15, 2006</b></p>
<ul>
<li>Yet another bugfix to index schemas, which was incorrectly marking most indexes
as primary key indexes.</li><li>Fixed GetSchema() to accept a null string array.</li><li>
Fixed a misspelled export in the core C library that prevented databases opened
with UTF16Encoding from getting schema information and would likely cause an error
if attempted.</li></ul>
<p>
<b>1.0.26.1 - February 14, 2006</b></p>
<ul>
<li>Fixed even more minor schema bugs having to do with indexes.</li><li>Added two
missing pieces in the SQLite designer which were preventing it from being used from
within VS Express editions.&nbsp;</li><li>Several bugfixes to the design-time installer
program, including supporting 64-bit environments.</li></ul>
<p>
<b>1.0.26.0 - February 11, 2006</b></p>
<ul>
<li>Code merge with SQLite 3.3.4</li><li>Fixed an encryption bug when changing the
password of databases over 1gb in size.&nbsp;</li><li>Fixed various designer issues
related to construction of named parameters.</li>
<li>Retooled the GetSchema() method of SQLiteDataReader to use the new 3.3.4 API
functions, and made several enhancements and fixes to schemas.&nbsp;</li>
<li>Implemented the SourceColumnNullMapping property of SQLiteParameter to fix a
DbCommandBuilder code generation bug.&nbsp;</li><li>Removed the runtime dependency
on MSVCR80.DLL.&nbsp; File size is somewhat larger for the varying desktop versions.</li><li>
Created an install program to manage installation and uninstallation of the SQLite
design-time support.</li>
<li>Designer support now works for all Visual Studio editions, including all Express
Editions.</li>
<li>Design-time installer will now remove (if present) the machine.config SQLite

entries in favor of installing the xml code into the devenv.exe.config file (or
any of the variations for express editions).&nbsp; The officially-accepted behavior
of using DbProviderFactories is to add the code to your app.config file, and the
machine.config file should not be touched.</li>
</ul>
<p>
<b>1.0.25.0 - January 31, 2006</b></p>
<ul>
<li>Code merge with SQLite 3.3.3</li><li>Added automatic distributed transaction
enlistment and implemented the DbConnection.EnlistTransaction method for manual
enlistment.</li>
<li>Nested transactions are now supported.</li>
<li>Rearranged the timing of SetPassword(), which now must be called before the
database is opened instead of afterwards.&nbsp; Optionally, the password can be
supplied in the ConnectionString.</li>
<li>Fixed a bug in SQLiteFunction that caused a failure when an empty resultset
was returned and a custom user aggregate function was used in the query.</li>
<li>The designer has had another round of cleanup applied, in preparation for moving
to a VS package.</li>
<li>Added SQLiteMetaDataCollectionNames class.</li>
</ul>
<p>
<b>1.0.24.6 beta - January 23, 2006</b></p>
<ul>
<li>This beta is built from sqlite.org's 3.3.2 beta.</li><li>Eliminated the static
linking of mscoree from all binaries.&nbsp; Native projects can now use the library
without any dependencies on the .NET framework, while managed projects continue
to be able to use the library normally.</li></ul>
<p>
<b>1.0.24.5 beta - January 20, 2006</b></p>
<ul>
<li>This beta is built from sqlite.org's 3.3.1 alpha and contains development-in-progress
code.&nbsp; Therefore no guarantees can be made regarding its suitability for production
use.</li>
<li><strong>You no longer need to distribute 2 files on the CompactFramework.&nbsp;
You can delete SQLite.Interop.DLL entirely.&nbsp; </strong>I wrote a custom tool
called "mergebin" (available in the source zip file) which combines the two libraries
and gets around a glaring defect in the VS2005 linker for ARM processors which doesn't
allow you to link netmodules.</li>
<li><strong>x64 and ia64 builds now use the same strong name as the x86 build.</strong>&nbsp;
This means breaking backward compatibility, but it was necessary in order to allow
you to drop any of those 3 builds onto a PC and have your .NET program run properly.&nbsp;
Prior to this, you'd get an error if you built your program using the x86 build,
and then installed the x64 version on a target machine and tried to run your program
against it.</li>
<li>The entire source project has been gone over top to bottom.&nbsp; A debug build
no longer combines the binaries into a single module, which was preventing proper
debugging.</li></ul>
<p>
<b>1.0.24.4 beta - January 16, 2006</b></p>
<ul>
<li>This beta is built from sqlite.org's 3.3.1 alpha and contains development-in-progress
code.&nbsp; Therefore no guarantees can be made regarding its suitability for production
use.</li>
<li>Fixed a bug in the UTF-16 handling code for preparing statements due to a behavioral
change in SQLite 3.3.0.</li>
<li>Added pager.c code necessary to cleanup after an encrypted file is closed.</li>
<li>Fixed an encryption bug that caused a fault when an encrypted file was rolled
back.</li>
<li>Modified the testcase code to take advantage of optimizations regarding the
use of a DbCommandBuilder.&nbsp; DataAdapter insert speed increased dramatically
as a result.</li>
</ul>
<p>
<b>1.0.24.3 beta - January 10, 2006</b></p>
<ul>
<li>This beta is built from sqlite.org's 3.3.0 alpha and contains development-in-progress
code.&nbsp; Therefore no guarantees can be made regarding its suitability for production
use.</li><li>Added support for database encryption at the pager level.&nbsp; Databases
are encrypted using a 128-bit RC4 stream algorithm.&nbsp; To open an existing encrypted
database, you may now specify a "Password={password}" text in the ConnectionString,
or you may call the SQLiteConnection.SetPassword() function to set the password
on an open connection. &nbsp;To encrypt existing non-encrypted databases or to change
the password on an encrypted database, you must use the SQLiteConnection.ChangePassword()
function.&nbsp; If you use SetPassword() instead of specifying a password in the
connection string, or call ChangePassword() you may use a binary byte array or a
text string as the password.</li>
<li>Rewrote the locking implementation for the Compact Framework.&nbsp; It is now
more robust and incorporates into the SQLite codebase more efficiently than the
previous CE adaptation.</li>
<li>Moved some of the embedded schema XML data into a resource file to ease code
readability.</li>
<li>Automated the fixup of the original SQLite codebase's source prior to compiling,
to ease merging with sqlite.org's source.</li>
<li>Fixed a memory leak in SQLiteCommand due to it not removing an internal reference
to itself in SQLiteConnection.&nbsp; </li>
</ul>
<p>
<b>1.0.24.2 - December 30, 2005</b></p>
<ul>
<li>Fixed the SQLiteDataReader.HasRows property to return the proper value.</li>
<li>Implemented the inadvertently neglected RecordsAffected property on SQLiteDataReader.
</li>
<li>SQLiteFunction static constructor was changed to pre-filter classes with only
the SQLiteFunctionAttribute.&nbsp; The code was throwing an exception when certain
assemblies were referenced in a project. </li>
<li>Fixed the SQLiteDataAdapter OnRowUpdated event, which was using the wrong variable
to find the attached event handler and subsequently not raising the event.</li>
<li>Small optimizations and fixes to SQLiteDataReader.NextResult().&nbsp;</li>
</ul>
<p>
<b>1.0.24.1 - December 19, 2005</b></p>
<ul>
<li>Update core SQLite engine to 3.2.8&nbsp;</li></ul>
<p>
<b>1.0.24 - December 9, 2005</b></p>
<ul>
<li>Fixed the<em> Catalogs</em> schema bug that caused attached databases not to
be re-attached to a cloned connection </li>
<li>Enhanced transactions to allow for a deferred or immediate writelock. &nbsp;SQLiteConnection.BeginTransaction()
now has an additional overload to support it&nbsp;</li><li>Commands are now prepared
as they are executed instead of beforehand.&nbsp; This fixes a bug whereby a multi-statement
command that alters the database and subsequently references the altered data would
fail during Prepare().</li><li>Tightened up the SQLiteDataReader to prevent reading
columns before calling the first Read() and to prevent reading columns after the
last Read().</li>
<li>A more descriptive error is thrown if there aren't enough parameters in the
command to satisfy the parameters required by the statement(s).&nbsp;</li>
</ul>
<p>
<b>1.0.23 - November 21, 2005</b></p>
<ul>
<li>Named parameters may now begin with <strong>@</strong> to ease portability of
the provider. SQLite's named parameters are ordinarily prefixed with a <strong>:
</strong>or<strong> $</strong>.&nbsp; The designer will still use the <strong>$</strong>
prefix however, since its more compatible with the default SQLite engine.</li><li>
Added several alternate ISO8601 date/time formats to SQLiteConvert.cs to increase
compatibility.</li>
<li>Relaxed coersion restrictions to work better with SQLite's inherent typelessness.&nbsp;</li>
</ul>
<p>
<b>1.0.22 - November 11, 2005</b></p>
<ul>
<li>Fixed some globalization issues which resulted in incorrect case-insensitive
comparisons</li>
<li>Fixed a bug in the routine that finds all user-defined functions in a loaded
assembly.&nbsp; It would throw an exception if any of the types in the assembly
could not be loaded.&nbsp; The exception is now caught and handled appropriately.</li>
</ul>
<p>
<b>1.0.21 - November 4, 2005</b></p>
<ul>
<li>Fixed a designer bug when creating typed datasets with parameterized queries.</li>
<li>The above fix then exposed another bug in the datareader's ability to query
schema information on parameterized commands, which was also fixed.</li>
<li>Compiled against the RTM version of VS2005.</li>
<li>Rewrote the design-time install script to use the XML DOM objects when writing
to the machine.config and to automatically register the DLL in the GAC.</li><li>
Made changes to the app.config descriptions and help file to improve version-independent

factory support.</li></ul>
<p>
<b>1.0.20 - October 19, 2005</b></p>
<ul>
<li>Fixed a shortcut in SQLiteBase.GetValue which was insufficient for international
environments.&nbsp; The shortcut was removed and the "proper" procedure put in.</li></ul>
<p>
<b>1.0.19 - October 5, 2005</b></p>
<ul>
<li>Code merge with SQLite 3.2.7
<li>Fixed bugs in the CE port code (os_wince.c)&nbsp;which were brought to light&nbsp;by&nbsp;recent
changes in the SQLite engine.
<li>Recompiled and modified to be compatible with the September VS2005 Release Candidate.<br />
Beta 2 users should continue to use 1.0.18.1</li></ul>
<p>
<b>1.0.18.1 - September 19, 2005</b></p>
<ul>
<li>Code merge with SQLite 3.2.6</li></ul>
<p>
<b>1.0.18 - September 1, 2005</b></p>
<ul>
<li>Added type-specific method calls when using the various SQLite classes that
would've normally returned a a generic Db base class, which aligns the code better
with the Microsoft-supplied data providers.</li></ul>
<p>
<b>1.0.17 - August 26, 2005</b></p>
<ul>
<li>Code merge with SQLite 3.2.5
<li>Added Itanium and x64 build settings to the project (needs testing)
<li>Bugfixes and enhancements to several schema types
<li>Additional design-time support to include index and foreign key enumerations.&nbsp;
Requires re-registering the designer using INSTALL.CMD.&nbsp; The new designer code
now allows the VS query designer and typed datasets to automatically link up foreign
keys, use indexes, and automatically generate relationships from the schema.<li>
Additional static methods on SQLiteConnection to create a database file, encrypt
a file using the Encrypted File System (EFS) on NTFS (requires NT 2K or above) and

NTFS file compression</li>
</ul>
<p>
<b>1.0.16 - August 24, 2005</b></p>
<ul>
<li>Code merge with SQLite 3.2.4 with the large delete bugfix in CVS (which will
become 3.2.5 soon)
<li>Added new GetSchema() types: IndexColumns, ViewColumns, ForeignKeys</li>
</ul>
<p>
<b>1.0.15 - August 22, 2005</b><br />
</p>
<ul>
<li>Code merge with SQLite 3.2.3
<li>Minor updates for better design-time experience. More design-time code to follow
in subsequent releases.</li>
</ul>
<p>
<b>1.0.14 - August 16, 2005</b><br />
</p>
<ul>
<li>Fixed a bug in the SQLiteDataAdapter due to insufficient implementation of the
class.&nbsp; The RowUpdating and RowUpdated events are now properly implemented,
but unfortunately inserting and updating data in a DataTable or DataSet is now much
slower.&nbsp; This is the proper design however, so the changes are here to stay.
<li>Lots of schema changes to support Visual Studio's Data Designer architecture.<li>
Added Designer support for the provider.&nbsp; It's not 100%, but you can design
queries, add typed datasets and perform quite a number of tasks all within Visual
Studio now.</li></ul>
<p>
<b>1.0.13 - August 8, 2005</b><br />
</p>
<div>
<ul>
<li>Fixed a named parameter bug in the base SQLite_UTF16 class, which of course
only showed up when a database connection was opened using the UseUTF16Encoding=True
parameter.
<li>Fixed a performance issue in SQLite_UTF16 involving string marshaling.</li></ul>
</div>
<p>
<b>1.0.12 - August 5, 2005</b><br />
</p>
<div>
<ul>
<li>Full support for the Compact Framework.&nbsp; Each build (Debug/Release) now
has a&nbsp;platform, either Win32 or Compact Framework.&nbsp; The correct projects
are built accordingly.&nbsp; See the&nbsp;<a href="#redist">Distributing SQLite</a>
section for information on what files need to be distributed for each platform.&nbsp;
<li>Modified SQLite3.Reset() and Step() functions to transparently handle timeouts
while waiting on the database to become available (typically when a writer is waiting
on a reader to finish, or a reader is waiting on a writer to finish).
<li>Lots of code cleanup&nbsp;as suggested&nbsp;by the Code Analyzer (FxCop).
<li>Lots of updates to the helpfile (as you can see).
<li>Statements&nbsp;were already prepared lazily&nbsp;in a SQLiteCommand, but now
its even more lazy.&nbsp; Statements are now only prepared if the statements haven't
been previously prepared and a Prepare() function is called (and the command is
associated with a connection) or just prior to the command being executed.&nbsp;</li></ul>
</div>
<p>
<b>1.0.11 - August 1, 2005</b><br />
</p>
<ul>
<li><strong>For everything except the Compact Framework, System.Data.SQLite.DLL
is now the <em>only</em> DLL required to use this provider!</strong>&nbsp; The assembly
is now a multi-module assembly, containing both the native SQLite3 codebase and
the C# classes built on top of it.&nbsp; The Compact Framework version (when completed)
will not be able to support this feature, so backwards compatibility with the Compact
Framework has been preserved for the future.
<li>Fixed a bug in SQLiteCommand.ExecuteScalar() that caused it to stop executing
commands once it obtained the first column of the first row-returning resultset.&nbsp;
Any remaining statements after the row-returning statement was ignored. </li>
</ul>
<p>
<b>1.0.10 - June 10, 2005</b><br />
</p>
<ul>
<li>Fixed a bug in the SQLite3.cs Prepare() function that created a statement even
when the SQLite engine returned a NULL pointer. Typically this occurs when multiple
statements are processed and there are trailing comments at the end of the statement.
<li>Fixed a bug in SQLiteStatement.cs that retrieved parameter names for a parameterized
query.&nbsp; SQLite's parameters are 1-based, and the function was starting at 0.&nbsp;
This was fine when all parameters were unnamed, but for named parameters it caused
the parameters to be out of whack. </li>
</ul>
<p>
<b>1.0.09a - May 25, 2005</b><br />
</p>
<ul>
<li>Fixed a broken helpfile and corrected some obsolete help remarks in SQLiteFunction.cs
<li>Added a version resource to the SQLite.Interop.DLL.&nbsp;</li></ul>
<p>
<b>1.0.09 - May 24, 2005</b><br />
</p>
<ul>
<li>Code merge with the latest 3.21 version of SQLite.
<li>Removed obsolete methods and properties for Whidbey Beta 2</li></ul>
<p>
<b>1.0.08 Refresh - Mar 24, 2005<br />
</b>
</p>
<ul>
<li>Code merge with the latest 3.20 version of SQLite.
<li>Recompiled the help file to fix a build error in it. </li>
</ul>
<p>
<b>1.0.08 - Mar 11, 2005<br />
</b>
</p>
<ul>
<li>Added additional #if statements to support the old beta 1 edition of VS2005.
<li>Code merged the SQLite 3.14 source. </li>
</ul>
<p>
<b>1.0.07 - Mar 5, 2005</b><br />
</p>
<ul>
<li>Made more optimizations to frequently-called functions, resulting in significant
performance gains in all tests.
<li>Recompiled the binaries using the latest VS2005 February CTP, resulting in yet
more significant speed gains.&nbsp; The 100k insert test used to take 3.5 seconds
and the insertwithidentity took almost 8 seconds.&nbsp; With the above two changes,
those tests are now executing in 1.9 and 4.9 seconds respectively.</li></ul>
<p>
<b>1.0.06 - Mar 1, 2005<br />
</b>
</p>
<ul>
<li>Speed-ups to SQLiteDataReader.&nbsp; It was interop'ing unnecessarily every
time it tried to fetch a field due to a logic error.
<li>Changed/Added some code to SQLiteConvert's internal DbType, Type and TypeAffinity
functions.
<li>Fixed the SQLiteDataReader to obey the flags set in the optional CommandBehavior
flag from SQLiteCommand.ExecuteReader().
<li>Changed the default page size to 1024 to reflect the defaults of SQLite.&nbsp;
Ignores the "Page Size" connection string option for memory databases, as tests
revealed that changing it resulted in memory corruption errors.
<li>Performance enhancements to the SQLiteCommand and SQLiteStatement classes which
reduced the 100,000 row insert execution time as well as the various Function execution
times significantly. </li>
</ul>
<p>
<b>1.0.05 - Feb 25, 2005</b>
</p>
<ul>
<li>Fixed the SQLite3 C# class step/reset functions to accomodate schema changes
that invalidate a prepared statement.&nbsp; Statements are recompiled transparently.
<li>Moved all native DLL declarations to an UnsafeNativeMethods class.
<li>Split several classes into their own modules for readability.
<li>Renamed many internal variables, reviewed access to variables marked as internal
and altered their protection levels accordingly.
<li>Due to the presence of the altered sqlite3 codebase and so many added interop
functions, I decided to rename the sqlite3 C project and the DLL to SQLite.Interop.DLL.&nbsp;
This is the same core sqlite3 codebase but designed specifically for this ADO.NET
provider.&nbsp; This eliminates any possibility of someone dropping another build
of sqlite3.dll into the system and rendering the provider inoperable.&nbsp; In the
future if the folks at sqlite.org finally introduce a method of retrieving column
usage for an arbitrary prepared statement, I'll retool this library to be a lightweight
function call wrapper around the core binary distribution.
<li>Added [SuppressUnmanagedCodeSecurity] attribute to the UnsafeNativeMethods class
which brings VS2005 November CTP execution speeds inline with the December CTP.
<li>Added a <b>bin</b> directory to the project root where pre-compiled binaries
can be found.
<li>Added a <b>doc</b> directory where preliminary documentation on the class library
can be found.
<li>Documented a lot more of the classes internally. </li>
</ul>
<p>
<b>1.0.04 - Feb 24, 2005</b>
</p>
<ul>
<li>Removed the SQLiteContext class and revamped the way UserFunctions work to simplify
the imlementation.
<li>Fixed a counting bug in the TestCases class, specifically in the function tests
where I wasn't resetting the counter and it was consequently reporting intrinsic
and raw select calls as being much much faster than they actually were.&nbsp; The
numbers are now much closer to what I expected for performance, with .NET user-functions
still being the slowest, but only by a small margin.
<li>Small performance tweaks to SQLiteDataReader.
<li>Added PageSize to the SQLiteConnectionStringBuilder and subsequently to the
SQLiteConnection
<li>Added a PRAGMA encoding=XXX execution statement to the SQLiteConnection after
opening a connection. </li>
</ul>
<p>
<b>1.0.03 - Feb 23, 2005</b>
</p>
<ul>
<li>Fixed up SQLiteCommandBuilder to correct implementation errors, which resulted
in an enormous performance boost in the InsertMany test.&nbsp;&nbsp; 10,000 row
insert that executed in 1500ms now executes in 500ms.
<li>Fixed several errors in the SQLite3_UTF16 class.&nbsp; ToString() was working
incorrectly and the Open() method failed to register user defined functions and
collations.
<li>Fixed a bug in SQLiteCommand.ClearCommands() whereby only the first statement
was being properly cleaned up.
<li>Fixed a bug in SQLiteDataReader whereby calling NextResult() would not properly
reset the previously-executed command in the sequence.
<li>Added an InsertManyWithIdentityFetch test, which appends a select clause to
populate the ID of the last inserted row into the InsertCommand, demonstrating ADO.NET's
ability to auto-fetch identity columns on insert. </li>
</ul>
<p>
<b>1.0.02 - Feb 21, 2005</b></p>
<ul>
<li>Tweaks to the xxx_interop functions that return char *'s, so they also return
the length.&nbsp; Saves an interop call to get the UTF-8 string length during conversion
to a .NET string.
<li>Reworked the whole interop.c thing into interop.h and reduced the code required
to merge the main sqlite3 codebase.
<li>Added support for user-defined collations. </li>
</ul>
</body>
</html>


|
|
|
|
|
|
<
|
|
<
<
|
<
<
>
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<

>
>
|
<
<
|
|
|
<
<
<
|
<
|
<
<
<
|
<
|
|
<
<
|
<
<
|
<
<
<
<
|
<
<
<
|
>
|
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
>
>
|
|

|
|
<
|
<
|
|


<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
>
>
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
>
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|

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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title></title>
	</head>
	<body>
    ADO.NET 2.0 SQLite Data Provider<br />
    Version 1.0.6 - Feb 28, 2005<br />

    Written by Robert Simpson (<a href="mailto:robert@blackcastlesoft.com">robert@blackcastlesoft.com</a>)<br />
    Released to the public domain, use at your own risk!<br />


    <br />


    This provider was written and verified using the Visual Studio 2005 November and
    December CTP's.<br />
    <br />
    The latest version can be downloaded <a href="http://www.blackcastlesoft.com/files/system.data.sqlite.zip">here</a>





































    <br />




















    <br />





    <b>Features:</b><br />
    <ul>
      <li>DbProviderFactory support, just add the XML below at the machine.config and/or app.config level. </li>


      <li>Full support for ATTACH'ed databases.&nbsp; Exposed as <i>Catalogs</i> in the
        schema.&nbsp; When cloning a connection, all attached databases are automatically
        re-attached to the new connection.</li>



      <li>DbConnection.GetSchema(...) support includes the <i>MetaDataCollections</i>, <i>

        DataSourceInformation</i>, <i>Columns</i>, <i>Tables</i>, <i>Views</i>, <i>Catalogs</i>



        and <i>Indexes</i> keywords.</li>

      <li>Enhanced DbDataReader.GetSchemaTable() functionality returns catalog, namespace
        and detailed schema information even for complex queries.</li>


      <li>Named and unnamed parameters.</li>


      <li>Full UTF-8 and UTF-16 support.</li>




      <li>Multiple simultaneous DataReaders (one DataReader per Command however).</li>



      <li>Full support for user-defined scalar and aggregate functions, encapsulated into
        an
        easy-to-use base class in which only a couple of overrides are necessary to implement
        new SQL functions.</li>



      <li>Full support for user-defined collating sequences, every bit as simple to implement
        as user-defined functions and uses the same base class.</li></ul>


















    In order to use the SQLiteFactory and have the SQLite data provider enumerated in
    the DbProviderFactories methods, you must add the following segment into either
    your application's app.config or the system's machine.config located in the %SystemRoot%\Microsoft.Net\Framework\v2.xxxx\Config
    folder:<br />
    <br />
    <pre>
&lt;configuration&gt;
  &lt;system.data&gt;
    &lt;DbProviderFactories&gt;

      &lt;add name="SQLite Data Provider" invariant="System.Data.SQLite" support="3F" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /&gt;

    &lt;/DbProviderFactories&gt;
  &lt;/system.data&gt;
&lt;/configuration&gt;
</pre>




    <br />



















    <b>Development Notes Regarding the SQLite 3 Source Code<br />
    </b>*** At this time, the necessary changes to the DLL to support Windows CE have






    not been completed.&nbsp; All function calls that return or pass a 64-bit value

    have been wrapped, but the necessary OS changes have not been finished.<br />
    <br />

      <p></p>




















    <p>





































      Steps for merging the sqlite3 core codebase:</p>
















    <ol>



      <li>Download the latest sqlite3 source from <a href="http://www.sqlite.org/download.html">
















        http://www.sqlite.org/download.html</a></li>
      <li>Extract the source code to the <b>SQLite.Interop\src</b> directory of this project</li>
      <li>Open the <b>src\select.c</b> file.</li>

























      <li>Add <b>#include "../interop.h" </b>to the top of the file where the other include's

        are.</li>
      <li>Scroll down the <b>select.c</b> file to around line <b>748</b>.&nbsp; Change the name of the function <b>static void generateColumnNames </b>to






























    <b>static void _generateColumnNames</b> (<i>note the underscore in front of the name</i>).</li>




      <li>Compile it.</li>
    </ol>






      <b>Version History<br />


































        1.06 - Feb 28, 2005<br />









      </b>


    <ul>






























      <li>Speed-ups to SQLiteDataReader.&nbsp; It was interop'ing every time it tried to


















        fetch a field due to a logic error.</li>










      <li>Changed/Added some code to SQLiteConvert's internal DbType, Type and TypeAffinity










































        functions.</li>



      <li>Fixed the SQLiteDataReader to obey the flags set in the optional CommandBehavior
        flag from SQLiteCommand.ExecuteReader().</li>




		<li>Changed the default page size to 1024 to reflect the defaults of 



















		SQLite.&nbsp; Ignores the &quot;Page Size&quot; connection string option for 
		memory databases, as tests revealed that changing it resulted in memory 













































		corruption errors.</li>
      <li>Performance enhancements to the SQLiteCommand and SQLiteStatement classes which













        reduced the 100,000 row insert execution time as well as the various Function execution













        times significantly.</li>




    </ul>
    <b>











      <br />
        1.05 - Feb 25, 2005</b>



















































































    <ul>










      <li>Fixed the SQLite3 C# class step/reset functions to accomodate schema changes

        that invalidate a prepared statement.&nbsp; Statements are recompiled transparently.</li>



      <li>Moved all native DLL declarations to an UnsafeNativeMethods class.</li>










      <li>Split several classes into their own modules for readability.</li>









      <li>Renamed many internal variables, reviewed access to variables marked as internal
        and altered their protection levels accordingly.</li>












      <li>Due to the presence of the altered sqlite3 codebase and so many added interop








        functions, I decided to rename the sqlite3 C project and the DLL to SQLite.Interop.DLL.&nbsp;

















        This is the same core sqlite3 codebase but designed specifically for this
        ADO.NET provider.&nbsp; This eliminates any possibility of someone dropping another
        build of sqlite3.dll into the system and rendering the provider inoperable.&nbsp;
        In the future if the folks at sqlite.org finally introduce a method of retrieving




        column usage for an arbitrary prepared statement, I'll retool this library to be











        a lightweight function call wrapper around the core binary distribution.</li>































      <li>Added [SuppressUnmanagedCodeSecurity] attribute to the UnsafeNativeMethods class





        which brings VS2005 November CTP execution speeds inline with the December CTP.</li>




		<li>Added a <b>bin</b> directory to the project root where pre-compiled 




























































		binaries can be found.</li>




		<li>Added a <b>doc</b> directory where preliminary documentation on the 























		class library can be found.</li>










		<li>Documented a lot more of the classes internally.</li>
    </ul>
      <b>











        <br />
























        1.04 - Feb 24, 2005</b>
    <ul>


      <li>Removed the SQLiteContext class and revamped the way UserFunctions work to simplify












































        the imlementation.</li>

      <li>Fixed a counting bug in the TestCases class, specifically in the function tests
        where I wasn't resetting the counter and it was consequently reporting intrinsic
        and raw select calls as being much much faster than they actually were.&nbsp; The









        numbers are now much closer to what I expected for performance, with .NET user-functions





















        still being the slowest, but only by a small margin.</li>



















      <li>Small performance tweaks to SQLiteDataReader.</li>

















      <li>Added PageSize to the SQLiteConnectionStringBuilder and subsequently to the SQLiteConnection</li>

      <li>Added a PRAGMA encoding=XXX execution statement to the SQLiteConnection after





        opening a connection.</li>






    </ul>
      <b>

















        1.03 - Feb 23, 2005</b>
    <ul>


























      <li>Fixed up SQLiteCommandBuilder to correct implementation errors, which resulted















        in an enormous performance boost in the InsertMany test.&nbsp;&nbsp; 10,000 row
        insert that executed in 1500ms now executes in 500ms.</li>










      <li>Fixed several errors in the SQLite3_UTF16 class.&nbsp; ToString() was working
























        incorrectly and the Open() method failed to register user defined functions and
        collations.</li>












      <li>Fixed a bug in SQLiteCommand.ClearCommands() whereby only the first statement

        was being properly cleaned up.</li>





      <li>Fixed a bug in SQLiteDataReader whereby calling NextResult() would not properly






        reset the previously-executed command in the sequence.</li>





      <li>Added an InsertManyWithIdentityFetch test, which appends a select clause to populate


















        the ID of the last inserted row into the InsertCommand, demonstrating ADO.NET's












        ability to auto-fetch identity columns on insert.</li>




    </ul>
    <p>

      <b>
















        1.02 - Feb 21, 2005</b></p>

    <ul>














































































































      <li>Tweaks to the xxx_interop functions that return char *'s, so they also return
        the length.&nbsp; Saves an interop call to get the UTF-8 string length during conversion
        to a .NET string.</li>
      <li>Reworked the whole interop.c thing into interop.h and reduced the code required
        to merge the main sqlite3 codebase.</li>
      <li>Added support for user-defined collations.</li>
    </ul>
	</body>
</html>
Changes to test/AssemblyInfo.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 Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

using System.Reflection;

using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite Tester")]
[assembly: AssemblyDescription("ADO.NET Data Provider for SQLite")]

[assembly: AssemblyCompany("http://system.data.sqlite.org/")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

//  Setting ComVisible to false makes the types in this assembly not visible 
//  to COM componenets.  If you need to access a type in this assembly from 
//  COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a6adbb45-c95f-44fb-bd47-f073e79c1d4b")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.77.0")]
[assembly: AssemblyFileVersion("1.0.77.0")]
<
<
<
<
<
<
<

>





|
|
>
|
|
|
<
<
|
<
|
<

|
|
|

<
<
<








|
<







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








using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("test")]
[assembly: AssemblyCopyright("")]


[assembly: AssemblyTrademark("")]

[assembly: AssemblyCulture("")]


///  Setting ComVisible to false makes the types in this assembly not visible 
///  to COM componenets.  If you need to access a type in this assembly from 
///  COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]




// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.0.0")]

Changes to test/Program.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
/********************************************************
 * 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.Diagnostics;
using System.Windows.Forms;


namespace test
{
    class Program
    {
        [STAThread()]
        static void Main(string[] args)
        {
            if (Environment.GetEnvironmentVariable("BREAK") != null)
            {
                Console.WriteLine(
                    "Attach a debugger to process {0} and press any key to continue.",
                    Process.GetCurrentProcess().Id);

                try
                {
                    Console.ReadKey(true); /* throw */
                }
                catch (InvalidOperationException) // Console.ReadKey
                {
                    // do nothing.
                }

                Debugger.Break();
            }

            string fileName = "test.db"; // NOTE: New default, was "Test.db3".
            bool autoRun = false;

            if (args != null)
            {
                int length = args.Length;


                for (int index = 0; index < length; index++)
                {
                    string arg = args[index];

                    if (arg != null)
                    {
                        arg = arg.TrimStart(new char[] { '-', '/' });

                        if (String.Equals(arg, "fileName",
                                StringComparison.OrdinalIgnoreCase))
                        {
                            index++;

                            if (index < length)
                                fileName = args[index];
                        }
                        else if (String.Equals(arg, "autoRun",
                                StringComparison.OrdinalIgnoreCase))
                        {
                            autoRun = true;
                        }
                    }

                }
            }

            Application.Run(new TestCasesDialog(fileName, autoRun));
        }
    }
}
<
<
<
<
<
<
|
|
|
|
>



|
|
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
|
|
|
<
<
|
<
<
|
<
|
<
>

<
<
<
|
<
<
<
|
<
<
|
<
|
|
<
<
<
<
<
|
|
|
>
|
<
|
<
|
|







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






using System;
using System.Data;
using System.Text;
using System.Data.Common;
using System.Data.SQLite;

namespace test
{
  class Program
  {

    static void Main(string[] args)
    {





      DbProviderFactory fact; // = DbProviderFactories.GetFactory("System.Data.OleDb");






      DbConnection cnn; //  = fact.CreateConnection();

//      cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Temp\\db.mdb;Persist Security Info=False";


//      cnn.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DirectLink;Data Source=MASTER";


//      cnn.Open();



//      TestCases.Run(fact, cnn);




      fact = DbProviderFactories.GetFactory("System.Data.SQLite");



      using (cnn = fact.CreateConnection())


      {

        cnn.ConnectionString = "Data Source=test.db3";
        cnn.Open();





        TestCases.Run(fact, cnn);
      }

      System.IO.File.Delete("test.db3");


      Console.ReadKey();

    }
  }
}
Deleted test/Properties/Resources.Designer.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
/********************************************************
 * 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!
 ********************************************************/

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace test.Properties {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class Resources {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal Resources() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("test.Properties.Resources", typeof(Resources).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































Deleted test/Properties/Resources.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































Changes to test/TestCases.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
/********************************************************
 * 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.Data.Common;
using System.Data;
using System.Data.SQLite;
using System.Transactions;
using System.Collections.Generic;
using System.Text;

namespace test
{
  internal class TestCases : TestCaseBase
  {
    private const int NumThreads = 8;
    private const int ThreadTimeout = 60000;

    private List<string> droptables = new List<string>();
    private List<string> maydroptable = new List<string>();
    private long logevents = 0;
    

    internal TestCases()
    {
    }

    internal TestCases(DbProviderFactory factory, string connectionString)
      : base(factory, connectionString)
    {
    }

    /// <summary>
    /// Inserts binary data into the database using a named parameter
    /// </summary>
    internal void BinaryInsert()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field6) VALUES(@bin)";
        DbParameter Field6 = cmd.CreateParameter();

        byte[] b = new byte[4000];
        b[0] = 1;
        b[100] = 2;
        b[1000] = 3;
        b[2000] = 4;
        b[3000] = 5;

        Field6.ParameterName = "@bin";
        Field6.Value = b;

        cmd.Parameters.Add(Field6);

        cmd.ExecuteNonQuery();
      }
    }

    internal void CheckLocked()
    {
      // Lets make sure the database isn't locked.  If it is, we've failed.
      using (DbConnection newcnn = ((ICloneable)_cnn).Clone() as DbConnection)
      using (DbCommand cmd = newcnn.CreateCommand())
      {
        if (newcnn.State != ConnectionState.Open) newcnn.Open();

        cmd.CommandText = "INSERT INTO TestCase (Field1) SELECT 1 WHERE 1 = 2";
        cmd.ExecuteNonQuery();
      }
    }

    internal void CheckSQLite()
    {
      if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) == -1)
        throw new InconclusiveException("Not a SQLite database");
    }

    /// <summary>
    /// Tests changing password on an encrypted database.
    /// </summary>
    [Test]
    internal void ChangePasswordTest()
    {
        if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) > -1)
        {
            // Opens an unencrypted database
            SQLiteConnection cnn = new SQLiteConnection(_cnnstring.ConnectionString);

            cnn.Open();

            // Encrypts the database. The connection remains valid and usable afterwards.
            cnn.ChangePassword("mypassword");

            maydroptable.Add("ChangePasswordTest");
            if (cnn.State != ConnectionState.Open) cnn.Open();
            using (DbCommand cmd = cnn.CreateCommand())
            {
                cmd.CommandText = "CREATE TABLE ChangePasswordTest(ID int primary key)";
                cmd.ExecuteNonQuery();
            }

            cnn.Close();

            // Try re-opening with bad password
            cnn.SetPassword("!mypassword");
            cnn.Open();
            cnn.Close();

            // Try re-opening with good password
            cnn.SetPassword("mypassword");
            cnn.Open();

            // Decrpyt database
            cnn.ChangePassword("");

            cnn.Close();

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

            cnn.Open();

            // Re-Encrypts the database. The connection remains valid and usable afterwards.
            cnn.ChangePassword("mypassword");
            cnn.ChangePassword("mynewerpassword");

            maydroptable.Add("ChangePasswordTest2");
            if (cnn.State != ConnectionState.Open) cnn.Open();
            using (DbCommand cmd = cnn.CreateCommand())
            {
                cmd.CommandText = "CREATE TABLE ChangePasswordTest2(ID int primary key)";
                cmd.ExecuteNonQuery();
            }

            // Decrpyt database
            cnn.ChangePassword("");
            cnn.Close();

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

            // Try opening now without password
            cnn.Open();
            cnn.Close();

        }
    }

    [Test(Sequence=1)]
    internal string VersionTest()
    {
      CheckSQLite();
      string[] version = _cnn.ServerVersion.Split('.');
      if (Convert.ToInt32(version[0]) < 3
        || (Convert.ToInt32(version[0]) == 3 && Convert.ToInt32(version[1]) < 6)
        || (Convert.ToInt32(version[0]) == 3 && Convert.ToInt32(version[1]) == 6 && Convert.ToInt32(version[2]) < 1)
        ) throw new Exception(String.Format("SQLite Engine is {0}.  Minimum supported version is 3.6.1", _cnn.ServerVersion));

      return String.Format("SQLite Engine is {0}", _cnn.ServerVersion);
    }

    //[Test(Sequence = 1)]
    internal void ParseTest()
    {
      DataTable tbl = _cnn.GetSchema("ViewColumns");
      DataTable tbl2 = _cnn.GetSchema("Views");

      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.Parameters.Add(cmd.CreateParameter());
        cmd.Parameters[0].Value = 1;

        cmd.Parameters.Add(cmd.CreateParameter());
        cmd.Parameters[1].Value = 1;

        cmd.CommandText = "select * from sqlite_master limit ? offset ?";
        object obj = cmd.ExecuteScalar();

        cmd.CommandText = @"
CREATE TEMP TABLE A(ID INTEGER, BID INTEGER);CREATE TEMP TABLE B(ID INTEGER, MYVAL VARCHAR);
INSERT INTO A (ID, BID) VALUES(2, 1);
INSERT INTO B (ID, MYVAL) VALUES(1,'TEST');
";
        cmd.ExecuteNonQuery();
        
        cmd.CommandText = "select *, (select 1 as c from b where b.id = a.bid) from a;";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          reader.Read();
        }

        cmd.CommandText = "select a.id as aa from a where (select 1 from (select 1 where 1 = aa));";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          reader.Read();
        }
        
        cmd.CommandText = "select *, (select count(c) from (select 1 as c from b where b.id = a.bid)) from a;";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          reader.Read();
        }
      }
    }

    [Test(Sequence = 39)]
    internal void MultipleFunctions()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT MYCOUNT(Field1), MYCOUNT(Field2) FROM TestCase";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          reader.Read();
        }
      }
    }

    [Test(Sequence = 8)]
    internal void FunctionWithCollation()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT CHARINDEX('pat', 'thepat'), CHARINDEX('pat', 'THEPAT'), CHARINDEX('pat' COLLATE NOCASE, 'THEPAT' COLLATE NOCASE)";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          reader.Read();
          if (reader.GetInt64(0) != reader.GetInt64(2) || reader.GetInt64(1) != 0 || reader.GetInt64(0) != 4)
            throw new Exception("CharIndex returned wrong results!");
        }
      }
    }

    [Test(Sequence = 9)]
    internal void FunctionWithCollation2()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT CASETEST('pat', 'pat'), CASETEST('pat', 'PAT'), CASETEST('pat' COLLATE NOCASE, 'PAT' COLLATE NOCASE), CASETEST('pat' COLLATE MYSEQUENCE, 'PAT' COLLATE MYSEQUENCE), CASETEST('tap', 'TAP' COLLATE NOCASE)";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          reader.Read();
          if (reader.GetInt64(0) != reader.GetInt64(2) || reader.GetInt64(1) != 1 || reader.GetInt64(0) != 0)
            throw new Exception("CharIndex returned wrong results!");
        }
      }
    }

    [Test]
    internal void DataTypesSchema()
    {
      using (DataTable tbl = _cnn.GetSchema("DataTypes"))
      {
      }
    }

    /// <summary>
    /// Make sure our implementation of ClearPool() behaves exactly as the SqlClient version is documented to behave.
    /// </summary>
    [Test(Sequence=90)]
    internal void ClearPoolTest()
    {
      string table = "clearpool";
      string temp = "TEMP";

      if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) == -1)
      {
        temp = String.Empty;
        table = "#clearpool";
      }

      object value;
      if (_cnnstring.TryGetValue("Pooling", out value) == false) throw new Exception("Pooling not present in connection string");
      if ((bool)value == false) throw new InconclusiveException("Pooling not enabled in the connection string");

      string sql = String.Format("CREATE {0} TABLE {1}(id int primary key);", temp, table);
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        // Create a temp table in the main connection so we can confirm our new connections are using true new connections
        cmd.CommandText = sql;
        cmd.ExecuteNonQuery();
      }

      for (int n = 0; n < 10; n++)
      {
        using (DbConnection newcnn = ((ICloneable)_cnn).Clone() as DbConnection)
        {
          if (newcnn.State != ConnectionState.Open) newcnn.Open();
          using (DbCommand cmd = newcnn.CreateCommand())
          {
            // If the pool is properly implemented and the pooled connection properly destroyed, this command will succeed.
            // If the new connection was obtained from the pool even after we cleared it, then this table will already exist
            // and the test fails.
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
          }
          // Try and clear the pool associated with this file
          newcnn.GetType().InvokeMember("ClearPool", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, new object[] { newcnn });

          // At this point when the connection is destroyed, it should not be returned to the pool, but instead disposed.
        }
      }
    }

    /// <summary>
    /// This tests ClearAllPools() functionality.  Makes sure that the pool is working properly and clearing properly.
    /// </summary>
    [Test(Sequence = 100)]
    internal void ClearAllPoolsTest()
    {
      string table = "clearpool";
      string temp = "TEMP";
      string exists = " IF NOT EXISTS ";

      if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) == -1)
      {
        temp = String.Empty;
        exists = String.Empty;
        table = "#clearpool";
      }

      object value;
      if (_cnnstring.TryGetValue("Pooling", out value) == false) throw new Exception("Pooling not present in connection string");
      if ((bool)value == false) throw new InconclusiveException("Pooling not enabled in the connection string");

      string sql = String.Format("CREATE {0} TABLE {2}{1}(id int primary key);", temp, table, exists);

      _cnn.GetType().InvokeMember("ClearAllPools", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, null);

      DbConnection[] arr = new DbConnection[10];

      try
      {
        // Create 10 connections and create temporary tables on them
        for (int n = 0; n < 10; n++)
        {
          arr[n] = ((ICloneable)_cnn).Clone() as DbConnection;
          if (arr[n].State != ConnectionState.Open) arr[n].Open();

          using (DbCommand cmd = arr[n].CreateCommand())
          {
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
            cmd.CommandText = String.Format("INSERT INTO {1} (id) VALUES({0})", n, table);
            cmd.ExecuteNonQuery();
          }

          switch (n)
          {
            case 2: // Put this one back into the pool
              arr[n].Dispose();
              arr[n] = null;
              break;
            case 4:
              // Clear all the pools
              _cnn.GetType().InvokeMember("ClearAllPools", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, null);
              break;
          }
        }

        // Now close all the connections.  Only the last 5 should go into the pool
        for (int n = 0; n < 10; n++)
        {
          if (arr[n] != null)
          {
            arr[n].Dispose();
            arr[n] = null;
          }
        }

        // Open 10 connections.  They should either have a clearpool containing an id of 5 or greater,
        // or should have no clearpool table at all.
        for (int n = 0; n < 10; n++)
        {
          arr[n] = ((ICloneable)_cnn).Clone() as DbConnection;
          if (arr[n].State != ConnectionState.Open) arr[n].Open();

          using (DbCommand cmd = arr[n].CreateCommand())
          {
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
            cmd.CommandText = String.Format("SELECT [id] FROM {0}", table);
            object o = cmd.ExecuteScalar();

            if (o == null || o == DBNull.Value)
              continue; // No data in the table at all, which means we must've just created it -- connection wasn't part of the pool

            if (Convert.ToInt32(o) < 5)
              throw new Exception("Unexpected data returned from table!");
          }
        }

        // Clear all the pools
        _cnn.GetType().InvokeMember("ClearAllPools", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, null);

      }
      finally
      {
        // Close all the connections
        for (int n = 0; n < 10; n++)
        {
          if (arr[n] != null)
          {
            arr[n].Dispose();
            arr[n] = null;
          }
        }
        // Clear all the pools
        _cnn.GetType().InvokeMember("ClearAllPools", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, null);
      }
    }

    [Test(Sequence = 50)]
    internal void CoersionTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, [Fiëld3], [Fiæld4], Field5, 'A', 1, 1 + 1, 3.14159 FROM TestCase";
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read())
          {
            object Field1 = rd.GetInt32(0);
            object Field2 = rd.GetDouble(1);
            object Field3 = rd.GetString(2);
            object Field4 = rd.GetString(3).TrimEnd();
            object Field5 = rd.GetDateTime(4);

            // The next statement should cause an exception
            try
            {
              Field1 = rd.GetString(0);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }

            try
            {
              Field2 = rd.GetString(1);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }
            Field3 = rd.GetString(2);
            Field4 = rd.GetString(3);

            Field1 = rd.GetInt32(0);

            try
            {
              Field2 = rd.GetInt32(1);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }

            try
            {
              Field3 = rd.GetInt32(2);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }

            try
            {
              Field4 = rd.GetInt32(3);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }
            try
            {
              Field5 = rd.GetInt32(4);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }

            try
            {
              Field3 = rd.GetDecimal(2);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }
            catch (FormatException)
            {
            }
            try
            {
              Field4 = rd.GetDecimal(3);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }
            catch (FormatException)
            {
            }
            try
            {
              Field5 = rd.GetDecimal(4);
              throw new Exception("Should have failed type checking!");
            }
            catch (InvalidCastException)
            {
            }
            catch (FormatException)
            {
            }
          }
          else throw new Exception("No data in table");
        }
      }
    }

    [Test(Sequence = 10)]
    internal void CreateTable()
    {
      droptables.Add("TestCase");

      using (DbCommand cmd = _cnn.CreateCommand())
      {
        if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) == -1)
          cmd.CommandText = "CREATE TABLE TestCase (ID bigint primary key identity, Field1 integer, Field2 Float, [Fiëld3] VARCHAR(50), [Fiæld4] CHAR(10), Field5 DateTime, Field6 Image)";
        else
          cmd.CommandText = "CREATE TABLE TestCase (ID integer primary key autoincrement, Field1 int, Field2 Float, [Fiëld3] VARCHAR(50), [Fiæld4] CHAR(10), Field5 DateTime, Field6 Image)";

        cmd.ExecuteNonQuery();
      }
    }

    [Test(Sequence = 1100)]
    internal string DataAdapterTest()
    {
      return DataAdapter(false);
    }

    [Test(Sequence = 1200)]
    internal string DataAdapterWithIdentityFetch()
    {
      return DataAdapter(true);
    }

    /// <summary>
    /// Utilizes the SQLiteCommandBuilder, 
    /// which in turn utilizes SQLiteDataReader's GetSchemaTable() functionality
    /// This insert is slow because it must raise callbacks before and after every update.
    /// For a fast update, see the FastInsertMany function beneath this one
    /// </summary>
    internal string DataAdapter(bool bWithIdentity)
    {
      StringBuilder builder = new StringBuilder();

      using (DbTransaction dbTrans = _cnn.BeginTransaction())
      {
        using (DbDataAdapter adp = _fact.CreateDataAdapter())
        {
          using (DbCommand cmd = _cnn.CreateCommand())
          {
            cmd.Transaction = dbTrans;
            cmd.CommandText = "SELECT * FROM TestCase WHERE 1 = 2";
            adp.SelectCommand = cmd;

            using (DbCommandBuilder bld = _fact.CreateCommandBuilder())
            {
              bld.DataAdapter = adp;
              using (adp.InsertCommand = (DbCommand)((ICloneable)bld.GetInsertCommand()).Clone())
              {
                if (bWithIdentity)
                {
                  if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) == -1)
                    adp.InsertCommand.CommandText += ";SELECT SCOPE_IDENTITY() AS [ID]";
                  else
                    adp.InsertCommand.CommandText += ";SELECT last_insert_rowid() AS [ID]";
                  adp.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
                }
                bld.DataAdapter = null;

                using (DataTable tbl = new DataTable())
                {
                  adp.Fill(tbl);
                  for (int n = 0; n < 10000; n++)
                  {
                    DataRow row = tbl.NewRow();
                    row[1] = n + (50000 * ((bWithIdentity == true) ? 2 : 1));
                    tbl.Rows.Add(row);
                  }

                  //Console.WriteLine(String.Format("          Inserting using CommandBuilder and DataAdapter\r\n          ->{0} (10,000 rows) ...", (bWithIdentity == true) ? "(with identity fetch)" : ""));
                  int dtStart = Environment.TickCount;
                  adp.Update(tbl);
                  int dtEnd = Environment.TickCount;
                  dtEnd -= dtStart;
                  builder.AppendFormat("Insert Ends in {0} ms ... ", (dtEnd));

                  dtStart = Environment.TickCount;
                  dbTrans.Commit();
                  dtEnd = Environment.TickCount;
                  dtEnd -= dtStart;
                  builder.AppendFormat("Commits in {0} ms", (dtEnd));

                  if (bWithIdentity)
                  {
                    using (DataTable tbl2 = new DataTable())
                    {
                      adp.SelectCommand.CommandText = "SELECT * FROM TestCase WHERE Field1 BETWEEN 100000 AND 199999 ORDER BY Field1";
                      adp.Fill(tbl2);

                      if (tbl2.Rows.Count != tbl.Rows.Count) throw new Exception("Selected data doesn't match updated data!");

                      for (int n = 0; n < tbl.Rows.Count; n++)
                      {
                        if (tbl.Rows[n][0].Equals(tbl2.Rows[n][0]) == false)
                          throw new Exception("Fetched identity doesn't match selected identity!");
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
      return builder.ToString();
    }

    /// <summary>
    /// Make sure a datareader can run even if the parent command is disposed, and that the connection is closed
    /// by the datareader when it is finished.
    /// </summary>
    [Test]
    internal void DataReaderCleanup()
    {
      DbConnection newcnn = ((ICloneable)_cnn).Clone() as DbConnection;
      DbCommand cmd = newcnn.CreateCommand();

      try
      {
        if (newcnn.State != ConnectionState.Open)
          newcnn.Open();

        cmd.CommandText = "SELECT 1, 2, 3";
        using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
          cmd.Dispose(); // Dispose of the command while an open reader is active ... should still be able to read
          try
          {
            reader.Read();
          }
          catch
          {
            throw new Exception("Unable to read from a DataReader!");
          }

          if (reader.GetInt32(0) != 1 || reader.GetInt32(1) != 2 || reader.GetInt32(2) != 3)
            throw new Exception("Unexpected return values from reader!");

          reader.Close(); // Close the reader, and check if the connection is closed

          if (newcnn.State != ConnectionState.Closed)
            throw new Exception("DataReader failed to cleanup!");
        }
      }
      finally
      {
        cmd.Dispose();
        newcnn.Dispose();
      }
    }

    [Test]
    internal void DataTypeTest()
    {
      DateTime now = DateTime.Now;

      using (DbCommand cmd = _cnn.CreateCommand())
      {
        droptables.Add("datatypetest");

        if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) == -1)
          cmd.CommandText = "create table datatypetest(id bigint identity primary key, myvalue sql_variant, datetimevalue datetime, decimalvalue decimal(38,18))";
        else
          cmd.CommandText = "create table datatypetest(id integer primary key, myvalue sql_variant, datetimevalue datetime, decimalvalue decimal(38,18))";

        cmd.ExecuteNonQuery();

        System.Globalization.CultureInfo oldculture = System.Threading.Thread.CurrentThread.CurrentCulture;
        System.Globalization.CultureInfo olduiculture = System.Threading.Thread.CurrentThread.CurrentUICulture;

        // Insert using a different current culture
        System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("es-ES");
        System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture;

        try
        {
          cmd.CommandText = "insert into datatypetest(myvalue, datetimevalue, decimalvalue) values(@p1,@p2,@p3)";
          DbParameter p1 = cmd.CreateParameter();
          DbParameter p2 = cmd.CreateParameter();
          DbParameter p3 = cmd.CreateParameter();

          cmd.Parameters.Add(p1);
          cmd.Parameters.Add(p2);
          cmd.Parameters.Add(p3);

          p1.ParameterName = "@p1";
          p2.ParameterName = "@p2";
          p3.ParameterName = "@p3";

          p1.Value = (long)1;
          p2.Value = new DateTime(1753, 1, 1);
          p3.Value = (Decimal)1.05;
          cmd.ExecuteNonQuery();

          p1.ResetDbType();
          p2.ResetDbType();
          p3.ResetDbType();

          p1.Value = "One";
          p2.Value = "2001-01-01";
          p3.Value = (Decimal)1.0;
          cmd.ExecuteNonQuery();

          p1.ResetDbType();
          p2.ResetDbType();
          p3.ResetDbType();

          p1.Value = 1.01;
          p2.Value = now;
          p3.Value = (Decimal)9.91;
          cmd.ExecuteNonQuery();

          // Read using a different current culture
          System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
          System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture;

          cmd.CommandText = "select myvalue, datetimevalue, decimalvalue from datatypetest";
          cmd.Parameters.Clear();
          using (DbDataReader reader = cmd.ExecuteReader())
          {
            for (int n = 0; n < 3; n++)
            {
              reader.Read();
              if (reader.GetValue(1).GetType() != reader.GetDateTime(1).GetType()) throw new Exception("DateTime type non-match");
              if (reader.GetValue(2).GetType() != reader.GetDecimal(2).GetType()) throw new Exception("Decimal type non-match");

              switch (n)
              {
                case 0:
                  if (reader.GetValue(0).GetType() != typeof(long)) throw new Exception("long type non-match");

                  if (reader.GetValue(0).Equals((long)1) == false) throw new Exception("long value non-match");
                  if (reader.GetValue(1).Equals(new DateTime(1753, 1, 1)) == false) throw new Exception(String.Format("DateTime value non-match expected {0} got {1}", new DateTime(1753, 1, 1), reader.GetValue(1)));
                  if (reader.GetValue(2).Equals((Decimal)1.05) == false) throw new Exception("Decimal value non-match");

                  if (reader.GetValue(0).Equals(reader.GetInt64(0)) == false) throw new Exception(String.Format("long value failed to match itself, {0} and {1}", reader.GetValue(0), reader.GetInt64(0)));
                  if (reader.GetValue(1).Equals(reader.GetDateTime(1)) == false) throw new Exception(String.Format("DateTime failed to match itself {0} and {1}", reader.GetValue(1), reader.GetDateTime(1)));
                  if (reader.GetValue(2).Equals(reader.GetDecimal(2)) == false) throw new Exception(String.Format("Decimal failed to match itself {0} and {1}", reader.GetValue(2), reader.GetDecimal(2)));
                  break;
                case 1:
                  if (reader.GetValue(0).GetType() != typeof(string)) throw new Exception("String type non-match");
                  if (reader.GetValue(0).Equals("One") == false) throw new Exception("String value non-match");
                  if (reader.GetValue(1).Equals(new DateTime(2001, 1, 1)) == false) throw new Exception(String.Format("DateTime value non-match expected {0} got {1}", new DateTime(2001, 1, 1), reader.GetValue(1)));
                  if (reader.GetValue(2).Equals((Decimal)1.0) == false) throw new Exception("Decimal value non-match");

                  if (reader.GetString(0) != "One") throw new Exception("String value non-match");
                  if (reader.GetValue(1).Equals(reader.GetDateTime(1)) == false) throw new Exception(String.Format("DateTime failed to match itself {0} and {1}", reader.GetValue(1), reader.GetDateTime(1)));
                  if (reader.GetValue(2).Equals(reader.GetDecimal(2)) == false) throw new Exception(String.Format("Decimal failed to match itself {0} and {1}", reader.GetValue(2), reader.GetDecimal(2)));
                  break;
                case 2:
                  if (reader.GetValue(0).GetType() != typeof(double)) throw new Exception("Double type non-match");
                  if (reader.GetValue(0).Equals(1.01) == false) throw new Exception("Double value non-match");
                  if (reader.GetValue(1).ToString() != now.ToString()) throw new Exception(String.Format("DateTime value non-match, expected {0} got {1}", now, reader.GetValue(1)));
                  if (reader.GetValue(2).Equals((Decimal)9.91) == false) throw new Exception("Decimal value non-match");

                  if (reader.GetDouble(0) != 1.01) throw new Exception("Double value non-match");
                  if (reader.GetValue(1).Equals(reader.GetDateTime(1)) == false) throw new Exception(String.Format("DateTime failed to match itself {0} and {1}", reader.GetValue(1), reader.GetDateTime(1)));
                  if (reader.GetValue(2).Equals(reader.GetDecimal(2)) == false) throw new Exception(String.Format("Decimal failed to match itself {0} and {1}", reader.GetValue(2), reader.GetDecimal(2)));
                  break;
              }
            }
          }
        }
        finally
        {
          System.Threading.Thread.CurrentThread.CurrentCulture = oldculture;
          System.Threading.Thread.CurrentThread.CurrentUICulture = olduiculture;
        }
      }
    }

    /// <summary>
    /// This is an mean ugly test that leaves a lot of open datareaders out on many connections
    /// to see if the database can survive being cloned a lot and disposed while active readers are up.
    /// </summary>
    [Test(Sequence = 40)]
    internal void LeakyDataReaders()
    {
      try
      {
        {
          DbConnection newcnn = null;
          try
          {
            for (int x = 0; x < 10000; x++)
            {
              if (newcnn == null)
              {
                newcnn = ((ICloneable)_cnn).Clone() as DbConnection;
              }

              if (newcnn.State != ConnectionState.Open)
                newcnn.Open();

              DbCommand cmd = newcnn.CreateCommand();
              cmd.CommandText = "SELECT * FROM TestCase";
              DbDataReader reader = cmd.ExecuteReader();
              reader.Read();
              object obj = reader[0];

              if (x % 500 == 0)
              {
                newcnn.Close();
                newcnn = null;
              }
            }
          }
          finally
          {
            if (newcnn != null)
              newcnn.Close();

            newcnn = null;
          }
        }
        CheckLocked();
      }
      catch (Exception e)
      {
        System.Diagnostics.Debug.WriteLine(e.Message);
      }
    }

    [Test(Sequence = int.MaxValue)]
    internal void DropTable()
    {
      DropTables(true);
    }

    internal void DropTables(bool throwError)
    {
      //string[] arr = new string[] { "TestCase", "datatypetest", "MultiThreadedTest", "fulltext", "guidtest", "keyinfotest", "stepreader", "nonexistent" };
      string errors = String.Empty;

      using (DbCommand cmd = _cnn.CreateCommand())
      {
        foreach(string table in droptables)
        {
          try
          {
            cmd.CommandText = String.Format("DROP TABLE{1} [{0}]", table, (throwError == false) ? " IF EXISTS" : "");
            cmd.ExecuteNonQuery();
          }
          catch (Exception e)
          {
            if (throwError == true)
              errors += String.Format("{0}\r\n", e.Message);
          }
        }

        foreach (string table in maydroptable)
        {
          try
          {
            cmd.CommandText = String.Format("DROP TABLE{1} [{0}]", table, (throwError == false) ? " IF EXISTS" : "");
            cmd.ExecuteNonQuery();
          }
          catch (Exception)
          {
          }
        }
      }

      if (String.IsNullOrEmpty(errors) == false)
        throw new Exception(errors);

    }

    [Test(Sequence = 1000)]
    internal string FastInsertMany()
    {
      StringBuilder builder = new StringBuilder();
      using (DbTransaction dbTrans = _cnn.BeginTransaction())
      {
        int dtStart;
        int dtEnd;

        using (DbCommand cmd = _cnn.CreateCommand())
        {
          cmd.Transaction = dbTrans;
          cmd.CommandText = "INSERT INTO TestCase(Field1) VALUES(@p1)";
          DbParameter Field1 = cmd.CreateParameter();

          Field1.ParameterName = "@p1";
          cmd.Parameters.Add(Field1);

          //Console.WriteLine(String.Format("          Fast insert using parameters and prepared statement\r\n          -> (100,000 rows) Begins ... "));
          dtStart = Environment.TickCount;
          for (int n = 0; n < 100000; n++)
          {
            Field1.Value = n + 200000;
            cmd.ExecuteNonQuery();
          }

          dtEnd = Environment.TickCount;
          dtEnd -= dtStart;
          builder.AppendFormat("Ends in {0} ms ... ", (dtEnd));
        }

        dtStart = Environment.TickCount;
        dbTrans.Commit();
        dtEnd = Environment.TickCount;
        dtEnd -= dtStart;
        builder.AppendFormat("Commits in {0} ms", (dtEnd));
      }
      return builder.ToString();
    }

    [Test]
    internal void FullTextTest()
    {
      CheckSQLite();

      using (DbCommand cmd = _cnn.CreateCommand())
      {
        droptables.Add("FullText");
        cmd.CommandText = "CREATE VIRTUAL TABLE FullText USING FTS3(name, ingredients);";
        cmd.ExecuteNonQuery();

        string[] names = { "broccoli stew", "pumpkin stew", "broccoli pie", "pumpkin pie" };
        string[] ingredients = { "broccoli peppers cheese tomatoes", "pumpkin onions garlic celery", "broccoli cheese onions flour", "pumpkin sugar flour butter" };
        int n;

        cmd.CommandText = "insert into FullText (name, ingredients) values (@name, @ingredient);";
        DbParameter name = cmd.CreateParameter();
        DbParameter ingredient = cmd.CreateParameter();

        name.ParameterName = "@name";
        ingredient.ParameterName = "@ingredient";

        cmd.Parameters.Add(name);
        cmd.Parameters.Add(ingredient);

        for (n = 0; n < names.Length; n++)
        {
          name.Value = names[n];
          ingredient.Value = ingredients[n];

          cmd.ExecuteNonQuery();
        }

        cmd.CommandText = "select rowid, name, ingredients from FullText where name match 'pie';";
        cmd.Parameters.Clear();

        int[] rowids = { 3, 4 };
        n = 0;

        using (DbDataReader reader = cmd.ExecuteReader())
        {
          while (reader.Read())
          {
            if (reader.GetInt64(0) != rowids[n++])
              throw new Exception("Unexpected rowid returned");

            if (n > rowids.Length) throw new Exception("Too many rows returned");
          }
        }
      }
    }

    [Test]
    internal void GuidTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        Guid guid = Guid.NewGuid();

        droptables.Add("GuidTest");

        cmd.CommandText = "CREATE TABLE GuidTest(MyGuid uniqueidentifier)";
        cmd.ExecuteNonQuery();

        // Insert a guid as a default binary representation
        cmd.CommandText = "INSERT INTO GuidTest(MyGuid) VALUES(@b)";
        DbParameter parm = cmd.CreateParameter();
        parm.ParameterName = "@b";
        parm.Value = guid;
        cmd.Parameters.Add(parm);
        //((SQLiteParameterCollection)cmd.Parameters).AddWithValue("@b", guid);

        // Insert a guid as text
        cmd.ExecuteNonQuery();
        cmd.Parameters[0].Value = guid.ToString();
        cmd.Parameters[0].DbType = DbType.String;
        cmd.ExecuteNonQuery();

        cmd.CommandText = "SELECT MyGuid FROM GuidTest";
        cmd.Parameters.Clear();

        using (DbDataReader reader = cmd.ExecuteReader())
        {
          reader.Read();
          if (reader.GetFieldType(0) != typeof(Guid)) throw new Exception("Column is not a Guid");
          if (reader.GetGuid(0) != guid) throw new Exception(String.Format("Got guid {0}, expected {1}", reader.GetGuid(0), guid));

          reader.Read();
          if (reader.GetFieldType(0) != typeof(Guid)) throw new Exception("Column is not a Guid");
          if (reader.GetGuid(0) != guid) throw new Exception(String.Format("Got guid {0}, expected {1}", reader.GetGuid(0), guid));
        }
      }
    }

    [Test(Sequence = 20)]
    internal void InsertTable()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, [Fiëld3], [Fiæld4], Field5) VALUES(1, 3.14159, 'Fiëld3', 'Fiæld4', '2005-01-01 13:49:00')";
        cmd.ExecuteNonQuery();
      }
    }

    [Test]
    internal string IterationTest1()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int dtStart;
        int dtEnd;
        int nCount;
        long n;

        cmd.CommandText = "SELECT Foo(ID, ID) FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        return String.Format("User Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart));
      }
    }

    [Test]
    internal string IterationTest2()
    {
      StringBuilder builder = new StringBuilder();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int dtStart;
        int dtEnd;
        int nCount;
        long n;

        cmd.CommandText = "SELECT ID FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        return String.Format("Raw iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart));
      }
    }

    [Test]
    internal string IterationTest3()
    {
      StringBuilder builder = new StringBuilder();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int dtStart;
        int dtEnd;
        int nCount;
        long n;

        cmd.CommandText = "SELECT ABS(ID) FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        return String.Format("Intrinsic Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart));
      }
    }

    [Test(Sequence=21)]
    internal void KeyInfoTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        try
        {
          // First test against integer primary key (optimized) keyinfo fetch
          droptables.Add("keyinfotest");
          cmd.CommandText = "Create table keyinfotest (id integer primary key, myuniquevalue integer unique not null, myvalue varchar(50))";
          cmd.ExecuteNonQuery();

          cmd.CommandText = "Select * from keyinfotest";
          using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
          {
            using (DataTable tbl = reader.GetSchemaTable())
            {
              if (tbl.Rows.Count != 3) throw new Exception("Wrong number of columns returned");
            }
          }

          cmd.CommandText = "SELECT MyValue FROM keyinfotest";
          using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
          {
            using (DataTable tbl = reader.GetSchemaTable())
            {
              if (tbl.Rows.Count != 2) throw new Exception("Wrong number of columns returned");
            }
          }
        }
        finally
        {
        }

        cmd.CommandText = "DROP TABLE keyinfotest";
        cmd.ExecuteNonQuery();

        droptables.Remove("keyinfotest");

        try
        {
          // Now test against non-integer primary key (unoptimized) subquery keyinfo fetch
          droptables.Add("keyinfotest");
          cmd.CommandText = "Create table keyinfotest (id char primary key, myuniquevalue integer unique not null, myvalue varchar(50))";
          cmd.ExecuteNonQuery();

          cmd.CommandText = "SELECT MyValue FROM keyinfotest";
          using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
          {
            using (DataTable tbl = reader.GetSchemaTable())
            {
              if (tbl.Rows.Count != 2) throw new Exception("Wrong number of columns returned");
            }
          }

          cmd.CommandText = "Select * from keyinfotest";
          using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
          {
            using (DataTable tbl = reader.GetSchemaTable())
            {
              if (tbl.Rows.Count != 3) throw new Exception("Wrong number of columns returned");
            }
          }

          // Make sure commandbuilder can generate an update command with the correct parameter count
          using (DbDataAdapter adp = _fact.CreateDataAdapter())
          using (DbCommandBuilder builder = _fact.CreateCommandBuilder())
          {
            adp.SelectCommand = cmd;
            builder.DataAdapter = adp;
            builder.ConflictOption = ConflictOption.OverwriteChanges;

            using (DbCommand updatecmd = builder.GetUpdateCommand())
            {
              if (updatecmd.Parameters.Count != 4)
                throw new Exception("Wrong number of parameters in update command!");
            }
          }
        }
        finally
        {
        }
      }
    }

    [Test]
    internal void ConnectionStringBuilder()
    {
      DbConnectionStringBuilder builder = _fact.CreateConnectionStringBuilder();
      if (builder is SQLiteConnectionStringBuilder)
      {
        bool pool = ((SQLiteConnectionStringBuilder)builder).Pooling;
      }
    }

    [Test]
    internal void LeakyCommands()
    {
      for (int n = 0; n < 100000; n++)
      {
        DbCommand cmd = _cnn.CreateCommand();
        cmd.CommandText = "SELECT * FROM sqlite_master";
        cmd.Prepare();
      }
      CheckLocked();
    }

    [Test(Sequence = 60)]
    internal void LockTest()
    {
      CheckSQLite();

      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field6 FROM TestCase WHERE Field6 IS NOT NULL";
        byte[] b = new byte[4000];

        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read() == false) throw new Exception("No data to read!");

          rd.GetBytes(0, 0, b, 0, 4000);

          if (b[0] != 1) throw new Exception("Binary value non-match byte 0");
          if (b[100] != 2) throw new Exception("Binary value non-match byte 100");
          if (b[1000] != 3) throw new Exception("Binary value non-match byte 1000");
          if (b[2000] != 4) throw new Exception("Binary value non-match byte 2000");
          if (b[3000] != 5) throw new Exception("Binary value non-match byte 3000");

          using (DbConnection clone = (DbConnection)((ICloneable)_cnn).Clone())
          {
            if (clone.State != ConnectionState.Open) clone.Open();
            using (DbCommand newcmd = clone.CreateCommand())
            {
              newcmd.CommandText = "DELETE FROM TestCase WHERE Field6 IS NULL";
              newcmd.CommandTimeout = 2;
              int cmdStart = Environment.TickCount;
              int cmdEnd;

              try
              {
                newcmd.ExecuteNonQuery(); // should fail because there's a reader on the database
                throw new ArgumentException("Should not have allowed an execute with an open reader"); // If we got here, the test failed
              }
              catch (Exception e)
              {
                if (e is ArgumentException) throw new Exception(e.Message);

                cmdEnd = Environment.TickCount;
                if (cmdEnd - cmdStart < 2000 || cmdEnd - cmdStart > 3000)
                  throw new Exception("Did not give up the lock at the right time!"); // Didn't wait the right amount of time

              }
            }
          }
        }
      }
    }

    /// <summary>
    /// Execute multiple steps in a command and verify the results.  Makes sure that commands after a select still
    /// get executed even if MoveNext() isn't called explicitly to move things along.
    /// </summary>
    [Test]
    internal void MultiStepReaderTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        droptables.Add("stepreader");
        cmd.CommandText = "CREATE TABLE stepreader (id int primary key);INSERT INTO stepreader values(1);SELECT * FROM stepreader;UPDATE stepreader set id = id + 1;";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          if (reader.Read() == false) throw new Exception("Failed to read from the table");
          if (reader.GetInt32(0) != 1) throw new Exception(String.Format("Expected {0} got {1}", 1, reader.GetInt32(0)));
        }
        cmd.CommandText = "SELECT * FROM stepreader";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          if (reader.Read() == false) throw new Exception("Failed to read from the table");
          if (reader.GetInt32(0) != 2) throw new Exception(String.Format("Expected {0} got {1}", 2, reader.GetInt32(0)));
        }
      }
    }

    internal class MTTest
    {
      internal DbConnection cnn;
      internal Exception e;
      internal System.Threading.Thread t;
      internal int value;
      internal System.Threading.ManualResetEvent ev;
    }

    [Test(Sequence=11)]
    internal void MultithreadingTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        droptables.Add("MultiThreadedTest");
        if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) == -1)
          cmd.CommandText = "CREATE TABLE MultiThreadedTest(ID integer identity primary key, ThreadId integer, MyValue integer)";
        else
          cmd.CommandText = "CREATE TABLE MultiThreadedTest(ID integer primary key, ThreadId integer, MyValue integer)";

        cmd.ExecuteNonQuery();
      }

      System.Threading.ManualResetEvent[] events = new System.Threading.ManualResetEvent[NumThreads];
      MTTest[] arr = new MTTest[NumThreads];

      for (int n = 0; n < arr.Length; n++)
      {
        arr[n] = new MTTest();
        arr[n].t = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(MultithreadedTestThread));
        arr[n].t.IsBackground = true;
        arr[n].cnn = ((ICloneable)_cnn).Clone() as DbConnection;
        arr[n].ev = events[n] = new System.Threading.ManualResetEvent(false);
        arr[n].t.Start(arr[n]);
      }

      System.Threading.WaitHandle.WaitAll(events, ThreadTimeout);

      bool failed = false;
      Exception e = null;

      for (int n = 0; n < arr.Length; n++)
      {
        if (arr[n].t.Join(0) == false)
        {
          failed = true;
          arr[n].t.Abort();
          arr[n].t.Join();
        }
        if (arr[n].e != null) e = arr[n].e;
        arr[n].cnn.Dispose();
        arr[n].ev.Close();
      }
      if (failed) throw new Exception("One or more threads deadlocked");
      if (e != null) 
        throw e;
    }

    internal void MultithreadedTestThread(object obj)
    {
      MTTest test = obj as MTTest;

      if (test.cnn.State != ConnectionState.Open)
        test.cnn.Open();

      int start = Environment.TickCount;
      try
      {
        using (DbCommand cmd = test.cnn.CreateCommand())
        {
          bool once = false;
          while (!once || ((Environment.TickCount - start) < 2000))
          {
            using (DbTransaction trans = test.cnn.BeginTransaction())
            {
              cmd.CommandText = String.Format("SELECT * FROM MultiThreadedTest WHERE ThreadId = {0}", test.t.ManagedThreadId);
              cmd.Transaction = trans;
              using (DbDataReader reader = cmd.ExecuteReader())
              {
                while (reader.Read())
                {
                  test.value += Convert.ToInt32(reader[2]);
                }
              }
              cmd.CommandText = String.Format("INSERT INTO MultiThreadedTest(ThreadId, MyValue) VALUES({0}, {1})", test.t.ManagedThreadId, Environment.TickCount);
              cmd.ExecuteNonQuery();

              trans.Commit();
            }

            once = true;
          }
        }
      }
      catch (Exception e)
      {
        test.e = e;
      }
      finally
      {
        test.ev.Set();
      }
    }

    [Test]
    internal void ParameterizedInsert()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, [Fiëld3], [Fiæld4], Field5) VALUES(@p1,@p2,@p3,@p4,@p5)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
        DbParameter Field3 = cmd.CreateParameter();
        DbParameter Field4 = cmd.CreateParameter();
        DbParameter Field5 = cmd.CreateParameter();

        Field1.ParameterName = "@p1";
        Field2.ParameterName = "@p2";
        Field3.ParameterName = "@p3";
        Field4.ParameterName = "@p4";
        Field5.ParameterName = "@p5";

        Field1.Value = 2;
        Field2.Value = 3.14159;
        Field3.Value = "Param Field3";
        Field4.Value = "Field4 Par";
        Field5.Value = DateTime.Now;

        cmd.Parameters.Add(Field1);
        cmd.Parameters.Add(Field2);
        cmd.Parameters.Add(Field3);
        cmd.Parameters.Add(Field4);
        cmd.Parameters.Add(Field5);

        cmd.ExecuteNonQuery();
      }
    }

    [Test]
    internal void ParameterizedInsertMissingParams()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, [Fiëld3], [Fiæld4], Field5) VALUES(@p1,@p2,@p3,@p4,@p5)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
        DbParameter Field3 = cmd.CreateParameter();
        DbParameter Field4 = cmd.CreateParameter();
        DbParameter Field5 = cmd.CreateParameter();

        Field1.ParameterName = "@p1";
        Field2.ParameterName = "@p2";
        Field3.ParameterName = "@p3";
        Field4.ParameterName = "@p4";
        Field5.ParameterName = "@p5";

        Field1.DbType = System.Data.DbType.Int32;

        Field1.Value = 2;
        Field2.Value = 3.14159;
        Field3.Value = "Field3 Param";
        Field4.Value = "Field4 Par";
        Field5.Value = DateTime.Now;

        cmd.Parameters.Add(Field1);
        cmd.Parameters.Add(Field2);
        cmd.Parameters.Add(Field3);
        cmd.Parameters.Add(Field4);

        // Assertion here, not enough parameters
        try
        {
          cmd.ExecuteNonQuery();
          throw new Exception("Executed with a missing parameter");
        }
        catch (Exception) // Expected
        {
        }
      }
    }

    /// <summary>
    /// Call Prepare() on a multi-statement command text where the second command depends on the existence of the first.
    /// </summary>
    [Test]
    internal void PrepareTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        droptables.Add("nonexistent");
        cmd.CommandText = "CREATE TABLE nonexistent(id int primary key);SELECT id FROM nonexistent UNION SELECT 1";
        cmd.Prepare();
        object ob = cmd.ExecuteScalar();

        if (ob == null || ob == DBNull.Value) throw new Exception("Multiple statements may not be supported");
        if (Convert.ToInt32(ob) != 1) throw new Exception(String.Format("Expected {0} got {1}", 1, ob));
      }
    }

    /// <summary>
    /// Checks to make sure transactions are rolled back before a connection goes back onto the pool
    /// </summary>
    [Test]
    internal void PoolingWithStealthTransactionTest()
    {
      object value;
      if (_cnnstring.TryGetValue("Pooling", out value) == false) throw new Exception("Pooling not present in connection string");
      if ((bool)value == false) throw new InconclusiveException("Pooling not enabled in the connection string");

      maydroptable.Add("PoolTest");

      for (int n = 0; n < 100; n++)
      {
        using (DbConnection newcnn = ((ICloneable)_cnn).Clone() as DbConnection)
        {
          if (newcnn.State != ConnectionState.Open) newcnn.Open();
          using (DbCommand cmd = newcnn.CreateCommand())
          {
            cmd.CommandText = "BEGIN TRANSACTION";
            cmd.ExecuteNonQuery();

            cmd.CommandText = "CREATE TABLE PoolTest(ID int primary key)";
            cmd.ExecuteNonQuery();
          }
        }
      }
    }

    /// <summary>
    /// Checks to make sure transactions are rolled back before a connection goes back onto the pool
    /// </summary>
    [Test]
    internal void PoolingWithTransactionTest()
    {
      object value;
      if (_cnnstring.TryGetValue("Pooling", out value) == false) throw new Exception("Pooling not present in connection string");
      if ((bool)value == false) throw new InconclusiveException("Pooling not enabled in the connection string");

      maydroptable.Add("PoolTest");
      for (int n = 0; n < 100; n++)
      {
        using (DbConnection newcnn = ((ICloneable)_cnn).Clone() as DbConnection)
        {
          if (newcnn.State != ConnectionState.Open) newcnn.Open();
          DbTransaction trans = newcnn.BeginTransaction();
          using (DbCommand cmd = newcnn.CreateCommand())
          {
            cmd.Transaction = trans;
            cmd.CommandText = "CREATE TABLE PoolTest(ID int primary key)";
            cmd.ExecuteNonQuery();
          }
        }
      }
    }

    /// <summary>
    /// Checks to make sure we can open DB read only.
    /// </summary>
    [Test]
    internal void ReadOnlyTest()
    {
      string RO_connectionString = _cnnstring.ConnectionString;
      object value;
      if (_cnnstring.TryGetValue("Read Only", out value) == false)
      {
        throw new Exception("Read Only not supported by connection string");
      }
      if ((bool)value == false)
      {
        // "Read Only" not present in connection string - add it
        RO_connectionString += ";Read Only=true";
      }

      maydroptable.Add("ReadOnlyTest");

      using (DbConnection newcnn = ((ICloneable)_cnn).Clone() as DbConnection)
      {
        if (newcnn.State == ConnectionState.Open) 
        {
          newcnn.Close();
        }
        newcnn.ConnectionString = RO_connectionString;
        newcnn.Open();
        newcnn.Dispose();
      } 
    }

    /// <summary>
    /// Checks to extended error code result support.
    /// </summary>
    [Test]
    internal void ExtendedResultCodesTest()
    {
      if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) > -1)
      {
        SQLiteConnection cnn = new SQLiteConnection(_cnnstring.ConnectionString);

        cnn.Open();

        // Turn on extended result codes
        cnn.SetExtendedResultCodes(true);

        int rc = cnn.ResultCode();
        int xrc = cnn.ExtendedResultCode();

        cnn.Close();
      }
    }

    //Logging EventHandler
    public void OnLogEvent(object sender, LogEventArgs logEvent)
    {
        int err_code = logEvent.ErrorCode;
        string err_msg = logEvent.Message;
        logevents++;
    }

    /// <summary>
    /// Tests SQLITE_CONFIG_LOG support.
    /// </summary>
    [Test]
    internal void SetLogCallbackTest()
    {
        if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) > -1)
        {
            SQLiteConnection cnn = new SQLiteConnection(_cnnstring.ConnectionString);

            // create and add a log event handler
            SQLiteLogEventHandler logHandler = new SQLiteLogEventHandler(OnLogEvent);
            SQLiteFactory sqlite_fact = (SQLiteFactory)_fact;

            sqlite_fact.Log += logHandler;

            cnn.Open();

            logevents = 0;

            cnn.LogMessage(1, "test log event");

            if (logevents != 1)
                throw new Exception(String.Format(
                    "Log event count {0} incorrect.", logevents));

            cnn.Close();

            // remove the log handler before the connection is closed.
            sqlite_fact.Log -= logHandler;

        }
    }

    /// <summary>
    /// Open a reader and then attempt to write to test the writer's command timeout property
    /// SQLite doesn't allow a write when a reader is active.
    /// *** NOTE AS OF 3.3.8 this test no longer blocks because SQLite now allows you to update table(s)
    /// while a reader is active on the same connection.  Therefore the timeout test is invalid
    /// </summary>
    internal void TimeoutTest()
    {
      CheckSQLite();

      using (DbCommand cmdRead = _cnn.CreateCommand())
      {
        cmdRead.CommandText = "SELECT ID FROM TestCase";
        using (DbDataReader rd = cmdRead.ExecuteReader())
        {
          using (DbCommand cmdwrite = _cnn.CreateCommand())
          {
            cmdwrite.CommandText = "UPDATE [KeyInfoTest] SET [ID] = [ID]";
            cmdwrite.CommandTimeout = 5;

            int dwtick = Environment.TickCount;
            try
            {
              cmdwrite.ExecuteNonQuery();
            }
            catch (Exception)
            {
              dwtick = (Environment.TickCount - dwtick) / 1000;
              if (dwtick < 5 || dwtick > 6)
                throw new Exception("Timeout didn't wait long enough!");

              return;
            }
            throw new Exception("Operation should have failed but completed successfully");
          }
        }
      }
    }

    [Test(Sequence = 41)]
    internal void TransactionScopeTest()
    {
      using (TransactionScope scope = new TransactionScope())
      {
        using (DbConnection cnn2 = ((ICloneable)_cnn).Clone() as DbConnection)
        {
          if (cnn2.State != ConnectionState.Open) cnn2.Open();
          using (DbCommand cmd = cnn2.CreateCommand())
          {
            // Created a table inside the transaction scope
            cmd.CommandText = "CREATE TABLE VolatileTable (ID INTEGER PRIMARY KEY, MyValue VARCHAR(50))";
            cmd.ExecuteNonQuery();

            maydroptable.Add("VolatileTable");

            using (DbCommand cmd2 = cnn2.CreateCommand())
            {
              using (cmd2.Transaction = cnn2.BeginTransaction())
              {
                // Inserting a value inside the table, inside a transaction which is inside the transaction scope
                cmd2.CommandText = "INSERT INTO VolatileTable (ID, MyValue) VALUES(1, 'Hello')";
                cmd2.ExecuteNonQuery();
                cmd2.Transaction.Commit();
              }
            }
          }
          // Connection is disposed before the transactionscope leaves, thereby forcing the connection to stay open
        }
        // Exit the transactionscope without committing it, causing a rollback of both the create table and the insert
      }

      // Verify that the table does not exist
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT COUNT(*) FROM VolatileTable";
        try
        {
          object o = cmd.ExecuteScalar();
          cmd.CommandText = "DROP TABLE VolatileTable";
          cmd.ExecuteNonQuery();
          throw new InvalidOperationException("Transaction failed! The table exists!");
        }
        catch(Exception e)
        {
          if (e is InvalidOperationException) throw new Exception(e.Message);
          return; // Succeeded, the table should not have existed
        }
      }
    }

    /// <summary>
    /// Causes the user-defined aggregate to be iterated through
    /// </summary>
    /// <returns></returns>
    [Test]
    internal string UserAggregate()
    {
      CheckSQLite();

      StringBuilder builder = new StringBuilder();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int dtStart;
        int n = 0;
        int nCount;

        cmd.CommandText = "SELECT MyCount(*) FROM TestCase";

        nCount = 0;
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          n = Convert.ToInt32(cmd.ExecuteScalar());
          nCount++;
        }
        if (n != 120003) throw new Exception("Unexpected count");
        builder.Append(String.Format("UserAggregate executed {0} times in 1 second.", nCount));
      }
      return builder.ToString();
    }

    /// <summary>
    /// Causes the user-defined collation sequence to be iterated through
    /// </summary>
    [Test]
    internal void UserCollation()
    {
      CheckSQLite();

      using (DbCommand cmd = _cnn.CreateCommand())
      {
        // Using a default collating sequence in descending order, "Param Field3" will appear at the top
        // and "Field3" will be next, followed by a NULL.  Our user-defined collating sequence will 
        // deliberately place them out of order so Field3 is first.
        cmd.CommandText = "SELECT [Fiëld3] FROM TestCase ORDER BY [Fiëld3] COLLATE MYSEQUENCE DESC";
        string s = (string)cmd.ExecuteScalar();
        if (s != "Fiëld3") throw new Exception("MySequence didn't sort properly");
      }
    }

    /// <summary>
    /// Causes the user-defined function to be called
    /// </summary>
    /// <returns></returns>
    [Test]
    internal string UserFunction1()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int nTimes;
        int dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT Foo('ee','foo')";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        return String.Format("User (text) command executed {0} times in 1 second.", nTimes);
      }
    }

    [Test]
    internal string UserFunction2()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int nTimes;
        int dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT Foo(10,11)";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        return String.Format("UserFunction command executed {0} times in 1 second.", nTimes);
      }
    }

    [Test]
    internal string UserFunction3()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int nTimes;
        int dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT ABS(1)";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        return String.Format("Intrinsic command executed {0} times in 1 second.", nTimes);
      }
    }

    [Test]
    internal string UserFunction4()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int nTimes;
        int dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT lower('FOO')";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        return String.Format("Intrin (txt) command executed {0} times in 1 second.", nTimes);
      }
    }

    [Test]
    internal string UserFunction5()
    {
      CheckSQLite();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        int nTimes;
        int dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT 1";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        return String.Format("Raw Value command executed {0} times in 1 second.", nTimes);
      }
    }
    
    [Test(Sequence = 42)]
    internal void VerifyBinaryData()
    {
      BinaryInsert();
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field6 FROM TestCase WHERE Field6 IS NOT NULL";
        byte[] b = new byte[4000];

        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read() == false) throw new Exception("No data to read!");

          long n = rd.GetBytes(0, 0, null, 0, 0);
          if (n != 4000) throw new Exception("Invalid byte length!");

          rd.GetBytes(0, 0, b, 0, 4000);

          if (b[0] != 1) throw new Exception("Binary value non-match byte 0");
          if (b[100] != 2) throw new Exception("Binary value non-match byte 100");
          if (b[1000] != 3) throw new Exception("Binary value non-match byte 1000");
          if (b[2000] != 4) throw new Exception("Binary value non-match byte 2000");
          if (b[3000] != 5) throw new Exception("Binary value non-match byte 3000");
        }
      }
    }

    [Test]
    internal void DecimalTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        droptables.Add("DECTEST");

        cmd.CommandText = "CREATE TABLE DECTEST(x DECIMAL(38,18))";
        cmd.ExecuteNonQuery();

        cmd.CommandText = "INSERT INTO DECTEST(x) VALUES(0.00001)";
        cmd.ExecuteNonQuery();
        
        cmd.CommandText = "SELECT * FROM DECTEST";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          reader.Read();
          decimal d = (decimal)reader.GetValue(0);
          d = reader.GetDecimal(0);
        }
      }
    }

    [Test(Sequence = 98)]
    internal void ScalarPreTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        droptables.Add("SCALARTEST");

        cmd.CommandText = "CREATE TABLE SCALARTEST(x INTEGER PRIMARY KEY, y)";
        cmd.ExecuteNonQuery();

        for (int i = 1; i <= 1000; i++)
        {
          DbParameter param1 = cmd.CreateParameter();

          param1.ParameterName = "param1";
          param1.DbType = DbType.Int32;
          param1.Value = i;

          DbParameter param2 = cmd.CreateParameter();

          param2.ParameterName = "param2";
          param2.DbType = DbType.Int32;
          param2.Value = i;

          cmd.CommandText =
              "INSERT OR REPLACE INTO SCALARTEST(x, y) VALUES(?, ?)";

          cmd.Parameters.Clear();
          cmd.Parameters.Add(param1);
          cmd.Parameters.Add(param2);

          cmd.ExecuteNonQuery();
        }
      }
    }

    [Test(Sequence = 99)]
    internal void ScalarTest()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT x FROM SCALARTEST ORDER BY x";
        cmd.ExecuteScalar();
      }
    }

    [Test(Sequence = 30)]
    internal void VerifyInsert()
    {
      using (DbCommand cmd = _cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, [Fiëld3], [Fiæld4], Field5 FROM TestCase";
        cmd.Prepare();
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read())
          {
            int Field1 = rd.GetInt32(0);
            double Field2 = rd.GetDouble(1);
            string Field3 = rd.GetString(2);
            string Field4 = rd.GetString(3).TrimEnd();
            DateTime Field5 = rd.GetDateTime(4);

            if (Field1 != 1) throw new Exception(String.Format("Field1 {0} did not match {1}", Field1, 1));
            if (Field2 != 3.14159) throw new Exception(String.Format("Field2 {0} did not match {1}", Field2, 3.14159));
            if (Field3 != "Fiëld3") throw new Exception(String.Format("Field3 {0} did not match {1}", Field3, "Fiëld3"));
            if (Field4 != "Fiæld4") throw new Exception(String.Format("Field4 {0} did not match {1}", Field4, "Fiæld4"));
            if (Field5.CompareTo(DateTime.Parse("2005-01-01 13:49:00")) != 0) throw new Exception(String.Format("Field5 {0} did not match {1}", Field4, DateTime.Parse("2005-01-01 13:49:00")));

            if (rd.GetName(0) != "Field1") throw new Exception("Non-Match column name Field1");
            if (rd.GetName(1) != "Field2") throw new Exception("Non-Match column name Field2");
            if (rd.GetName(2) != "Fiëld3") throw new Exception("Non-Match column name Field3");
            if (rd.GetName(3) != "Fiæld4") throw new Exception("Non-Match column name Field4");
            if (rd.GetName(4) != "Field5") throw new Exception("Non-Match column name Field5");
          }
          else throw new Exception("No data in table");
        }
      }
    }
  }

  /// <summary>
  /// Scalar user-defined function.  In this example, the same class is declared twice with 
  /// different function names to demonstrate how to use alias names for user-defined functions.
  /// </summary>
  [SQLiteFunction(Name = "Foo", Arguments = 2, FuncType = FunctionType.Scalar)]
  [SQLiteFunction(Name = "TestFunc", Arguments = 2, FuncType = FunctionType.Scalar)]
  class TestFunc : SQLiteFunction
  {
    public override object Invoke(object[] args)
    {
      if (args[0].GetType() != typeof(int)) return args[0];

      int Param1 = Convert.ToInt32(args[0]); // First parameter
      int Param2 = Convert.ToInt32(args[1]); // Second parameter

      return Param1 + Param2;
    }
  }

  [SQLiteFunction(Name = "CASETEST", Arguments = 2, FuncType = FunctionType.Scalar)]
  class CaseTestFunc : SQLiteFunctionEx
  {
    public override object Invoke(object[] args)
    {
      CollationSequence seq = GetCollationSequence();
      return seq.Compare(args[0].ToString(), args[1].ToString());
    }
  }

  /// <summary>
  /// Aggregate user-defined function.  Arguments = -1 means any number of arguments is acceptable
  /// </summary>
  [SQLiteFunction(Name = "MyCount", Arguments = -1, FuncType = FunctionType.Aggregate)]
  class MyCount : SQLiteFunction
  {
    public override void Step(object[] args, int nStep, ref object contextData)
<
<
<
<
<
<
<




<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















<
<
<
<
<
<
<
<
<
<














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







using System;
using System.Data.Common;
using System.Data;
using System.Data.SQLite;




namespace test
{












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































  /// <summary>
  /// Scalar user-defined function.  In this example, the same class is declared twice with 
  /// different function names to demonstrate how to use alias names for user-defined functions.
  /// </summary>
  [SQLiteFunction(Name = "Foo", Arguments = 2, FuncType = FunctionType.Scalar)]
  [SQLiteFunction(Name = "TestFunc", Arguments = 2, FuncType = FunctionType.Scalar)]
  class TestFunc : SQLiteFunction
  {
    public override object Invoke(object[] args)
    {
      if (args[0].GetType() != typeof(int)) return args[0];

      int Param1 = Convert.ToInt32(args[0]); // First parameter
      int Param2 = Convert.ToInt32(args[1]); // Second parameter

      return Param1 + Param2;
    }
  }











  /// <summary>
  /// Aggregate user-defined function.  Arguments = -1 means any number of arguments is acceptable
  /// </summary>
  [SQLiteFunction(Name = "MyCount", Arguments = -1, FuncType = FunctionType.Aggregate)]
  class MyCount : SQLiteFunction
  {
    public override void Step(object[] args, int nStep, ref object contextData)
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129





2130


2131


2132


2133


2134


2135


2136


2137


2138


2139


2140


2141


2142


2143


2144


2145



2146




2147

2148


2149

2150
2151
2152
2153
2154
2155
2156
2157


2158
2159
2160
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

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

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
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

    public override object Final(object contextData)
    {
      return contextData;
    }
  }

  /// <summary>
  /// Sample regular expression function.  Example Usage:
  /// SELECT * FROM foo WHERE name REGEXP '$bar'
  /// SELECT * FROM foo WHERE REGEXP('$bar', name)
  /// 
  /// </summary>
  [SQLiteFunction(Name = "REGEXP", Arguments = 2, FuncType = FunctionType.Scalar)]
  class MyRegEx : SQLiteFunction
  {
    public override object Invoke(object[] args)
    {
      return System.Text.RegularExpressions.Regex.IsMatch(Convert.ToString(args[1]), Convert.ToString(args[0]));
    }
  }

  /// <summary>
  /// User-defined collating sequence.
  /// </summary>
  [SQLiteFunction(Name = "MYSEQUENCE", FuncType = FunctionType.Collation)]
  class MySequence : SQLiteFunction
  {
    public override int Compare(string param1, string param2)
    {
      // Make sure the string "Fiëld3" is sorted out of order
      if (param1 == "Fiëld3") return 1;
      if (param2 == "Fiëld3") return -1;
      return String.Compare(param1, param2, true);
    }
  }

  [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
  public sealed class TestAttribute : Attribute, IComparable<TestAttribute>
  {





    private static int _start = 65535;


    private int _sequence;





    public TestAttribute()


    {


      _sequence = _start;


      _start++;


    }





    public int Sequence


    {


      get { return _sequence; }


      set { _sequence = value; }


    }





    #region IComparable<TestAttribute> Members








    public int CompareTo(TestAttribute other)

    {


      return _sequence.CompareTo(other._sequence);

    }
    #endregion
  }

  internal enum TestResultEnum
  {
    Succeeded = 0,
    Failed = 1,


    Inconclusive = 2,
  }

  internal class InconclusiveException : Exception

  {
    internal InconclusiveException()



      : base()

    {







    }

























    internal InconclusiveException(string message)






      : base(message)





    {





    }

  }


  internal class TestEventArgs : EventArgs

  {
    public readonly string TestName;
    public readonly TestResultEnum Result;
    public readonly Exception Exception;
    public readonly string Message;
    public readonly int Duration;







    internal TestEventArgs(string testName, TestResultEnum success, int duration, Exception e, string message)











    {



      TestName = testName;






      Result = success;

      Exception = e;




      Message = message;

      Duration = duration;

    }

  }

  delegate void TestCompletedEvent(object sender, TestEventArgs args);
  delegate void TestStartingEvent(object sender, TestEventArgs args);


  internal abstract class TestCaseBase
  {
    protected DbProviderFactory _fact;
    protected DbConnection _cnn = null;
    protected DbConnectionStringBuilder _cnnstring;
    protected Dictionary<string, bool> _tests = new Dictionary<string,bool>();


    public event TestCompletedEvent OnTestFinished;

    public event TestStartingEvent OnTestStarting;








    public event EventHandler OnAllTestsDone;












    protected TestCaseBase()





    {




      SortedList<TestAttribute, System.Reflection.MethodInfo> items = new SortedList<TestAttribute, System.Reflection.MethodInfo>();




      foreach (System.Reflection.MethodInfo mi in GetType().GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod))


      {









        object[] att = mi.GetCustomAttributes(typeof(TestAttribute), false);




        if (att.Length == 1)
        {
          items.Add((TestAttribute)att[0], mi);


        }
      }


      foreach (KeyValuePair<TestAttribute, System.Reflection.MethodInfo> pair in items)


      {


        _tests.Add(pair.Value.Name, true);
      }
    }


















    protected TestCaseBase(DbProviderFactory factory, string connectionString)


    {
      _fact = factory;
      _cnn = _fact.CreateConnection();


      _cnn.ConnectionString = connectionString;
      _cnnstring = _fact.CreateConnectionStringBuilder();
      _cnnstring.ConnectionString = connectionString;
      _cnn.Open();
    }





    internal Dictionary<string, bool> Tests




    {
      get



      {

        return _tests;
      }

      set




      {

        _tests = value;
      }

    }









    internal void Run()




    {






      SortedList<TestAttribute, System.Reflection.MethodInfo> items = new SortedList<TestAttribute, System.Reflection.MethodInfo>();
      foreach (System.Reflection.MethodInfo mi in GetType().GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod))

      {
        object[] att = mi.GetCustomAttributes(typeof(TestAttribute), false);
        if (att.Length == 1 && _tests[mi.Name] == true)

        {




          items.Add((TestAttribute)att[0], mi);










        }

      }


      foreach (KeyValuePair<TestAttribute, System.Reflection.MethodInfo> pair in items)





      {
        if (OnTestStarting != null)
          OnTestStarting(this, new TestEventArgs(pair.Value.Name, TestResultEnum.Inconclusive, 0, null, null));








        int start = Environment.TickCount;



        try

        {


          object obj = pair.Value.Invoke(this, null);
          int duration = Environment.TickCount - start;




          if (OnTestFinished != null)
            OnTestFinished(this, new TestEventArgs(pair.Value.Name, TestResultEnum.Succeeded, duration, null, (obj is string) ? (string)obj : String.Empty));
        }

        catch (Exception e)


        {


          int duration = Environment.TickCount - start;
          Exception inner = e.InnerException;

          if (OnTestFinished != null)
          {
            if (inner is InconclusiveException)
            {
              OnTestFinished(this, new TestEventArgs(pair.Value.Name, TestResultEnum.Inconclusive, duration, null, inner.Message));
            }

            else
            {
              OnTestFinished(this, new TestEventArgs(pair.Value.Name, TestResultEnum.Failed, duration, inner, null));

            }


          }
        }
      }



      if (OnAllTestsDone != null)
        OnAllTestsDone(this, EventArgs.Empty);









    }
  }
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|
|
|




<
|

>
>
>
>
>
|
>
>
|
>
>

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

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

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

>
>
|
>
|
<
|

|
|
<
|
>
>
|
|
|
|
>
|
<
>
>
>
|
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
|
>
|
|
>
|
>
|
|
<
<
<
<
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
|
>
|
>
>
>
>
|
>
|
>
|
>
|
|
|
<
>
|
|
|
|
|
|
|
|
>
|
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>

>
|
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
|
<
>
>
|
|
>
|
<
>
>
|
>
>
|
|
|
>
>
>
>
>
>

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

<
|
>
>
|
<
<
<
|
>
>
>
>
|
<
>
>
>
>
|
|
>
>
>
|
>
|
|
>
|
>
>
>
>
|
>
|
|
>
|
>
>
>
>
|
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
|
<
>
|
<
<
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
|
>

<
>
>
>
>
>
|
<
<
>
>
>
>
>
>
|
>
|
>
>
>
|
>

>
>
|
|
>
>
>
>
|
<
|
>
|
>
>
|
>
>
|
<
|
|
|
|
|
|
<
>
|
|
|
>
|
>
>
|
|
|
>
>
|
<
<
>
>
>
>
>
>
>
>
>



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

    public override object Final(object contextData)
    {
      return contextData;
    }
  }
















  /// <summary>
  /// User-defined collating sequence.
  /// </summary>
  [SQLiteFunction(Name = "MYSEQUENCE", FuncType = FunctionType.Collation)]
  class MySequence : SQLiteFunction
  {
    public override int Compare(string param1, string param2)
    {
      // Make sure the string "Field3" is sorted out of order
      if (param1 == "Field3") return 1;
      if (param2 == "Field3") return -1;
      return String.Compare(param1, param2, true);
    }
  }


  internal class TestCases
  {
    internal static void Run(DbProviderFactory fact, DbConnection cnn)
    {
      Console.WriteLine("\r\nBeginning Test on " + cnn.GetType().ToString());
      try { CreateTable(cnn); Console.WriteLine("SUCCESS - CreateTable"); }
      catch (Exception) { Console.WriteLine("FAIL - CreateTable"); }

      try { InsertTable(cnn); Console.WriteLine("SUCCESS - InsertTable"); }
      catch (Exception) { Console.WriteLine("FAIL - InsertTable"); }

      try { VerifyInsert(cnn); Console.WriteLine("SUCCESS - VerifyInsert"); }
      catch (Exception) { Console.WriteLine("FAIL - VerifyInsert"); }

      try { CoersionTest(cnn); Console.WriteLine("FAIL - CoersionTest"); }
      catch (Exception) { Console.WriteLine("SUCCESS - CoersionTest"); }

      try { ParameterizedInsert(cnn); Console.WriteLine("SUCCESS - ParameterizedInsert"); }
      catch (Exception) { Console.WriteLine("FAIL - ParameterizedInsert"); }

      try { BinaryInsert(cnn); Console.WriteLine("SUCCESS - BinaryInsert"); }
      catch (Exception) { Console.WriteLine("FAIL - BinaryInsert"); }

      try { VerifyBinaryData(cnn); Console.WriteLine("SUCCESS - VerifyBinaryData"); }
      catch (Exception) { Console.WriteLine("FAIL - VerifyBinaryData"); }

      try { ParameterizedInsertMissingParams(cnn); Console.WriteLine("FAIL - ParameterizedInsertMissingParams"); }
      catch (Exception) { Console.WriteLine("SUCCESS - ParameterizedInsertMissingParams"); }

      try { InsertMany(fact, cnn, false); Console.WriteLine("SUCCESS - InsertMany"); }
      catch (Exception) { Console.WriteLine("FAIL - InsertMany"); }

      try { InsertMany(fact, cnn, true); Console.WriteLine("SUCCESS - InsertManyWithIdentityFetch"); }
      catch (Exception) { Console.WriteLine("FAIL - InsertManyWithIdentityFetch"); }

      try { IterationTest(cnn); Console.WriteLine("SUCCESS - Iteration Test"); }
      catch (Exception) { Console.WriteLine("FAIL - Iteration Test"); }

      try { UserFunction(cnn); Console.WriteLine("SUCCESS - UserFunction"); }
      catch (Exception) { Console.WriteLine("FAIL - UserFunction"); }

      try { UserAggregate(cnn); Console.WriteLine("SUCCESS - UserAggregate"); }
      catch (Exception) { Console.WriteLine("FAIL - UserAggregate"); }

      try { UserCollation(cnn); Console.WriteLine("SUCCESS - UserCollation"); }
      catch (Exception) { Console.WriteLine("FAIL - UserCollation"); }

      try { DropTable(cnn); Console.WriteLine("SUCCESS - DropTable"); }
      catch (Exception) { Console.WriteLine("FAIL - DropTable"); }

      Console.WriteLine("\r\nTests Finished.");
    }

    internal static void CreateTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "CREATE TABLE TestCase (ID integer primary key autoincrement, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)";
        cmd.ExecuteNonQuery();
      }
    }

    internal static void DropTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "DROP TABLE TestCase";
        cmd.ExecuteNonQuery();
      }

    }

    internal static void InsertTable(DbConnection cnn)
    {

      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(1, 3.14159, 'Field3', 'Field4', '2005-01-01 13:49:00')";
        cmd.ExecuteNonQuery();
      }
    }

    internal static void VerifyInsert(DbConnection cnn)
    {

      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, Field3, Field4, Field5 FROM TestCase";
        cmd.Prepare();
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read())
          {
            long Field1 = rd.GetInt64(0);
            double Field2 = rd.GetDouble(1);
            string Field3 = rd.GetString(2);
            string Field4 = rd.GetString(3).TrimEnd();
            DateTime Field5 = rd.GetDateTime(4);

            if (Field1 != 1) throw new ArgumentOutOfRangeException("Non-Match on Field1");
            if (Field2 != 3.14159) throw new ArgumentOutOfRangeException("Non-Match on Field2");
            if (Field3 != "Field3") throw new ArgumentOutOfRangeException("Non-Match on Field3");
            if (Field4 != "Field4") throw new ArgumentOutOfRangeException("Non-Match on Field4");
            if (Field5.CompareTo(DateTime.Parse("2005-01-01 13:49:00")) != 0) throw new ArgumentOutOfRangeException("Non-Match on Field5");
          }
          else throw new ArgumentOutOfRangeException("No data in table");
        }
      }
    }

    internal static void CoersionTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, Field3, Field4, Field5, 'A', 1, 1 + 1, 3.14159 FROM TestCase";
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read())
          {
            object Field1 = rd.GetInt32(0);
            object Field2 = rd.GetDouble(1);
            object Field3 = rd.GetString(2);
            object Field4 = rd.GetString(3).TrimEnd();
            object Field5 = rd.GetDateTime(4);

            // The next statement should cause an exception
            Field1 = rd.GetString(0);
            Field2 = rd.GetString(1);
            Field3 = rd.GetString(2);
            Field4 = rd.GetString(3);
            Field5 = rd.GetString(4);

            Field1 = rd.GetInt32(0);
            Field2 = rd.GetInt32(1);
            Field3 = rd.GetInt32(2);
            Field4 = rd.GetInt32(3);
            Field5 = rd.GetInt32(4);

            Field1 = rd.GetDecimal(0);
            Field2 = rd.GetDecimal(1);
            Field3 = rd.GetDecimal(2);
            Field4 = rd.GetDecimal(3);
            Field5 = rd.GetDecimal(4);
          }
          else throw new ArgumentOutOfRangeException("No data in table");
        }
      }
    }

    internal static void ParameterizedInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())




      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(?,?,?,?,?)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
        DbParameter Field3 = cmd.CreateParameter();
        DbParameter Field4 = cmd.CreateParameter();
        DbParameter Field5 = cmd.CreateParameter();

        Field1.Value = 2;
        Field2.Value = 3.14159;
        Field3.Value = "Param Field3";
        Field4.Value = "Field4 Par";
        Field5.Value = DateTime.Now;

        cmd.Parameters.Add(Field1);
        cmd.Parameters.Add(Field2);
        cmd.Parameters.Add(Field3);
        cmd.Parameters.Add(Field4);
        cmd.Parameters.Add(Field5);

        cmd.ExecuteNonQuery();
      }
    }

    internal static void BinaryInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field6) VALUES(?)";
        DbParameter Field6 = cmd.CreateParameter();

        byte[] b = new byte[4000];
        b[0] = 1;
        b[100] = 2;
        b[1000] = 3;
        b[2000] = 4;
        b[3000] = 5;

        Field6.Value = b;

        cmd.Parameters.Add(Field6);

        cmd.ExecuteNonQuery();
      }
    }


    internal static void VerifyBinaryData(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field6 FROM TestCase WHERE Field6 IS NOT NULL";
        byte[] b = new byte[4000];

        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read() == false) throw new ArgumentOutOfRangeException();

          rd.GetBytes(0, 0, b, 0, 4000);

          if (b[0] != 1) throw new ArgumentException();
          if (b[100] != 2) throw new ArgumentException();
          if (b[1000] != 3) throw new ArgumentException();
          if (b[2000] != 4) throw new ArgumentException();
          if (b[3000] != 5) throw new ArgumentException();
        }
      }
    }

    internal static void ParameterizedInsertMissingParams(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(?,?,?,?,?)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
        DbParameter Field3 = cmd.CreateParameter();
        DbParameter Field4 = cmd.CreateParameter();
        DbParameter Field5 = cmd.CreateParameter();

        Field1.DbType = System.Data.DbType.Int32;

        Field1.Value = 2;
        Field2.Value = 3.14159;
        Field3.Value = "Field3 Param";
        Field4.Value = "Field4 Par";
        Field5.Value = DateTime.Now;

        cmd.Parameters.Add(Field1);
        cmd.Parameters.Add(Field2);
        cmd.Parameters.Add(Field3);
        cmd.Parameters.Add(Field4);

        // Assertion here, not enough parameters
        cmd.ExecuteNonQuery();
      }
    }

    // Utilizes the SQLiteCommandBuilder, which in turn utilizes SQLiteDataReader's GetSchemaTable() functionality
    internal static void InsertMany(DbProviderFactory fact, DbConnection cnn, bool bWithIdentity)
    {
      using (DbTransaction dbTrans = cnn.BeginTransaction())
      {
        using (DbDataAdapter adp = fact.CreateDataAdapter())
        {
          using (DbCommand cmd = cnn.CreateCommand())
          {
            cmd.Transaction = dbTrans;
            cmd.CommandText = "SELECT * FROM TestCase WHERE 1=2";
            adp.SelectCommand = cmd;

            using (DbCommandBuilder bld = fact.CreateCommandBuilder())
            {
              bld.DataAdapter = adp;
              adp.InsertCommand = bld.GetInsertCommand();
              if (bWithIdentity)
              {

                adp.InsertCommand.CommandText += ";SELECT [ID] FROM TestCase WHERE RowID = last_insert_rowid()";
                adp.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
              }

              using (DataTable tbl = new DataTable())
              {

                adp.Fill(tbl);
                for (int n = 0; n < 100000; n++)
                {
                  DataRow row = tbl.NewRow();
                  row[1] = n + 10000;
                  tbl.Rows.Add(row);
                }

                Console.Write(String.Format("          InsertMany{0} (100000 rows) Begins ... ", (bWithIdentity == true) ? "WithIdentityFetch":"                 "));
                long dtStart = DateTime.Now.Ticks;
                adp.Update(tbl);
                long dtEnd = DateTime.Now.Ticks;
                dtEnd -= dtStart;
                Console.Write(String.Format("Ends in {0} ms ... ", (dtEnd / 10000)));

                dtStart = DateTime.Now.Ticks;
                dbTrans.Commit();
                dtEnd = DateTime.Now.Ticks;
                dtEnd -= dtStart;
                Console.WriteLine(String.Format("Commits in {0} ms", (dtEnd / 10000)));
              }
            }
          }
        }
      }
    }

    // Causes the user-defined function to be called
    internal static void UserFunction(DbConnection cnn)
    {

      using (DbCommand cmd = cnn.CreateCommand())
      {
        int nTimes;
        long dtStart;




        nTimes = 0;
        cmd.CommandText = "SELECT Foo('ee','foo')";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {

          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          User (text)  command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT Foo(10,11)";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          UserFunction command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT ABS(1)";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Intrinsic    command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT lower('FOO')";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Intrin (txt) command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT 1";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Raw Value    command executed {0} times in 1 second.", nTimes));
      }
    }


    internal static void IterationTest(DbConnection cnn)
    {


      using (DbCommand cmd = cnn.CreateCommand())
      {
        long dtStart;
        long dtEnd;
        int nCount;
        long n;

        cmd.CommandText = "SELECT Foo(ID, ID) FROM TestCase";
        cmd.Prepare();
        dtStart = DateTime.Now.Ticks;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = DateTime.Now.Ticks;
        }
        Console.WriteLine(String.Format("          User Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart) / 10000));


        cmd.CommandText = "SELECT ID FROM TestCase";
        cmd.Prepare();
        dtStart = DateTime.Now.Ticks;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {


          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = DateTime.Now.Ticks;
        }
        Console.WriteLine(String.Format("          Raw iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart) / 10000));

        cmd.CommandText = "SELECT ABS(ID) FROM TestCase";
        cmd.Prepare();
        dtStart = DateTime.Now.Ticks;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = DateTime.Now.Ticks;
        }
        Console.WriteLine(String.Format("          Intrinsic Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart) / 10000));


      }
    }

    // Causes the user-defined aggregate to be iterated through
    internal static void UserAggregate(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        long dtStart;

        int n = 0;
        int nCount;

        cmd.CommandText = "SELECT MyCount(*) FROM TestCase";

        nCount = 0;

        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          n = Convert.ToInt32(cmd.ExecuteScalar());
          nCount++;
        }
        if (n != 200003) throw new ArgumentOutOfRangeException("Unexpected count");
        Console.WriteLine(String.Format("          UserAggregate executed {0} times in 1 second.", nCount));
      }
    }

    // Causes the user-defined collation sequence to be iterated through
    internal static void UserCollation(DbConnection cnn)
    {


      using (DbCommand cmd = cnn.CreateCommand())
      {
        // Using a default collating sequence in descending order, "Param Field3" will appear at the top
        // and "Field3" will be next, followed by a NULL.  Our user-defined collating sequence will 
        // deliberately place them out of order so Field3 is first.
        cmd.CommandText = "SELECT Field3 FROM TestCase ORDER BY Field3 COLLATE MYSEQUENCE DESC";
        string s = (string)cmd.ExecuteScalar();
        if (s != "Field3") throw new ArgumentOutOfRangeException("MySequence didn't sort properly");
      }
    }
  }
}
Deleted test/TestCasesDialog.Designer.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace test
{
  partial class TestCasesDialog
  {
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      System.Windows.Forms.Label label1;
      System.Windows.Forms.Label label2;
      System.Windows.Forms.Button closeButton;
      System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
      System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
      this._provider = new System.Windows.Forms.ComboBox();
      this._connectionString = new System.Windows.Forms.ComboBox();
      this._grid = new System.Windows.Forms.DataGridView();
      this.Test = new System.Windows.Forms.DataGridViewTextBoxColumn();
      this.Result = new System.Windows.Forms.DataGridViewTextBoxColumn();
      this.Time = new System.Windows.Forms.DataGridViewTextBoxColumn();
      this.Information = new System.Windows.Forms.DataGridViewTextBoxColumn();
      this.runButton = new System.Windows.Forms.Button();
      this.menuStrip1 = new System.Windows.Forms.MenuStrip();
      this.testMenu = new System.Windows.Forms.ToolStripMenuItem();
      label1 = new System.Windows.Forms.Label();
      label2 = new System.Windows.Forms.Label();
      closeButton = new System.Windows.Forms.Button();
      ((System.ComponentModel.ISupportInitialize)(this._grid)).BeginInit();
      this.menuStrip1.SuspendLayout();
      this.SuspendLayout();
      // 
      // label1
      // 
      label1.AutoSize = true;
      label1.Location = new System.Drawing.Point(14, 35);
      label1.Name = "label1";
      label1.Size = new System.Drawing.Size(46, 13);
      label1.TabIndex = 0;
      label1.Text = "&Provider";
      // 
      // label2
      // 
      label2.AutoSize = true;
      label2.Location = new System.Drawing.Point(250, 35);
      label2.Name = "label2";
      label2.Size = new System.Drawing.Size(91, 13);
      label2.TabIndex = 2;
      label2.Text = "Connection &String";
      // 
      // closeButton
      // 
      closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
      closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
      closeButton.Location = new System.Drawing.Point(534, 514);
      closeButton.Name = "closeButton";
      closeButton.Size = new System.Drawing.Size(75, 23);
      closeButton.TabIndex = 5;
      closeButton.Text = "&Close";
      closeButton.UseVisualStyleBackColor = true;
      closeButton.Click += new System.EventHandler(this.closeButton_Click);
      // 
      // _provider
      // 
      this._provider.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
      this._provider.FormattingEnabled = true;
      this._provider.Location = new System.Drawing.Point(66, 32);
      this._provider.Name = "_provider";
      this._provider.Size = new System.Drawing.Size(178, 21);
      this._provider.TabIndex = 1;
      // 
      // _connectionString
      // 
      this._connectionString.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                  | System.Windows.Forms.AnchorStyles.Right)));
      this._connectionString.FormattingEnabled = true;
      this._connectionString.Location = new System.Drawing.Point(347, 32);
      this._connectionString.Name = "_connectionString";
      this._connectionString.Size = new System.Drawing.Size(262, 21);
      this._connectionString.TabIndex = 3;
      // 
      // _grid
      // 
      this._grid.AllowUserToAddRows = false;
      this._grid.AllowUserToDeleteRows = false;
      this._grid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                  | System.Windows.Forms.AnchorStyles.Left)
                  | System.Windows.Forms.AnchorStyles.Right)));
      this._grid.BackgroundColor = System.Drawing.SystemColors.Window;
      this._grid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
      this._grid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.Test,
            this.Result,
            this.Time,
            this.Information});
      this._grid.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
      this._grid.Location = new System.Drawing.Point(12, 58);
      this._grid.Name = "_grid";
      this._grid.ReadOnly = true;
      this._grid.RowHeadersVisible = false;
      this._grid.Size = new System.Drawing.Size(597, 450);
      this._grid.TabIndex = 4;
      // 
      // Test
      // 
      this.Test.Frozen = true;
      this.Test.HeaderText = "Test";
      this.Test.Name = "Test";
      this.Test.ReadOnly = true;
      this.Test.Width = 150;
      // 
      // Result
      // 
      this.Result.Frozen = true;
      this.Result.HeaderText = "Result";
      this.Result.Name = "Result";
      this.Result.ReadOnly = true;
      this.Result.Resizable = System.Windows.Forms.DataGridViewTriState.True;
      this.Result.Width = 150;
      // 
      // Time
      // 
      dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleRight;
      this.Time.DefaultCellStyle = dataGridViewCellStyle3;
      this.Time.HeaderText = "Time (ms)";
      this.Time.Name = "Time";
      this.Time.ReadOnly = true;
      // 
      // Information
      // 
      this.Information.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
      dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
      this.Information.DefaultCellStyle = dataGridViewCellStyle4;
      this.Information.HeaderText = "Information";
      this.Information.Name = "Information";
      this.Information.ReadOnly = true;
      // 
      // runButton
      // 
      this.runButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
      this.runButton.Location = new System.Drawing.Point(453, 514);
      this.runButton.Name = "runButton";
      this.runButton.Size = new System.Drawing.Size(75, 23);
      this.runButton.TabIndex = 6;
      this.runButton.Text = "&Run";
      this.runButton.UseVisualStyleBackColor = true;
      this.runButton.Click += new System.EventHandler(this.runButton_Click);
      // 
      // menuStrip1
      // 
      this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.testMenu});
      this.menuStrip1.Location = new System.Drawing.Point(0, 0);
      this.menuStrip1.Name = "menuStrip1";
      this.menuStrip1.Size = new System.Drawing.Size(621, 24);
      this.menuStrip1.TabIndex = 7;
      this.menuStrip1.Text = "menuStrip1";
      // 
      // testMenu
      // 
      this.testMenu.Name = "testMenu";
      this.testMenu.Size = new System.Drawing.Size(46, 20);
      this.testMenu.Text = "&Tests";
      // 
      // TestCasesDialog
      // 
      this.AcceptButton = this.runButton;
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.CancelButton = closeButton;
      this.ClientSize = new System.Drawing.Size(621, 549);
      this.Controls.Add(this.menuStrip1);
      this.Controls.Add(this.runButton);
      this.Controls.Add(closeButton);
      this.Controls.Add(this._grid);
      this.Controls.Add(this._connectionString);
      this.Controls.Add(label2);
      this.Controls.Add(this._provider);
      this.Controls.Add(label1);
      this.MainMenuStrip = this.menuStrip1;
      this.Name = "TestCasesDialog";
      this.Text = "ADO.NET Provider Test";
      ((System.ComponentModel.ISupportInitialize)(this._grid)).EndInit();
      this.menuStrip1.ResumeLayout(false);
      this.menuStrip1.PerformLayout();
      this.ResumeLayout(false);
      this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.ComboBox _provider;
    private System.Windows.Forms.ComboBox _connectionString;
    private System.Windows.Forms.DataGridView _grid;
    private System.Windows.Forms.Button runButton;
    private System.Windows.Forms.DataGridViewTextBoxColumn Test;
    private System.Windows.Forms.DataGridViewTextBoxColumn Result;
    private System.Windows.Forms.DataGridViewTextBoxColumn Time;
    private System.Windows.Forms.DataGridViewTextBoxColumn Information;
    private System.Windows.Forms.MenuStrip menuStrip1;
    private System.Windows.Forms.ToolStripMenuItem testMenu;
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































Deleted test/TestCasesDialog.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
/********************************************************
 * 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;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.Common;

namespace test
{
  public partial class TestCasesDialog : Form
  {
    private delegate void DelegateWithNoArgs();

    /// <summary>
    /// The total number of tests that have failed during the previous test run.
    /// </summary>
    private int _failed;

    /// <summary>
    /// If set, then automatically run all the tests and exit.
    /// </summary>
    private bool _autoRun;

    private TestCases _test;
    private TestCases _testitems;

    public TestCasesDialog(string fileName, bool autoRun)
    {
      InitializeComponent();

      using (DataTable tbl = DbProviderFactories.GetFactoryClasses())
      {
        foreach (DataRow row in tbl.Rows)
        {
          string prov = row[2].ToString();

          if (prov.IndexOf("SQLite", 0, StringComparison.OrdinalIgnoreCase) != -1
            || prov.IndexOf("SqlClient", 0, StringComparison.OrdinalIgnoreCase) != -1
            )
            _provider.Items.Add(prov);
          if (prov == "System.Data.SQLite") _provider.SelectedItem = prov;
        }
      }
      _connectionString.Items.Add(String.Format("Data Source={0};Pooling=true;FailIfMissing=false", fileName));
      _connectionString.Items.Add("Data Source=(local);Initial Catalog=sqlite;Integrated Security=True;Max Pool Size=10");
      _connectionString.SelectedIndex = 0;

      _autoRun = autoRun;
      _testitems = new TestCases();
      foreach (KeyValuePair<string, bool> pair in _testitems.Tests)
      {
        ToolStripMenuItem item = (ToolStripMenuItem)testMenu.DropDownItems.Add(pair.Key, null, new EventHandler(_tests_Clicked));
        item.Checked = true;
        item.CheckOnClick = true;
      }

      this.Load += new EventHandler(TestCasesDialog_Load);
    }

    private StringBuilder GridToText()
    {
        StringBuilder result = new StringBuilder();

        foreach (DataGridViewRow row in _grid.Rows)
        {
            if (result.Length > 0)
                result.Append(Environment.NewLine);

            result.AppendFormat("{0}\t{1}\t{2}\t{3}", row.Cells[0].Value,
                row.Cells[1].Value, row.Cells[2].Value, row.Cells[3].Value);
        }

        return result;
    }

    void TestCasesDialog_Load(object sender, EventArgs e)
    {
        //
        // NOTE: In "automatic" mode, run all the tests as soon as the form is
        //       fully loaded.
        //
        if (_autoRun)
        {
            BeginInvoke(new DelegateWithNoArgs(delegate()
            {
                runButton_Click(sender, e);
            }));
        }
    }

    void _tests_Clicked(object sender, EventArgs e)
    {
      ToolStripMenuItem item = sender as ToolStripMenuItem;
      if (item != null)
        _testitems.Tests[item.Text] = item.Checked;
    }

    private void runButton_Click(object sender, EventArgs e)
    {
      string factoryString = _provider.SelectedItem.ToString();
      DbProviderFactory factory = DbProviderFactories.GetFactory(factoryString);

      _failed = 0;

      _test = new TestCases(factory, _connectionString.Text);
      _test.Tests = _testitems.Tests;

      _test.OnTestStarting += new TestStartingEvent(_test_OnTestStarting);
      _test.OnTestFinished += new TestCompletedEvent(_test_OnTestFinished);
      _test.OnAllTestsDone += new EventHandler(_test_OnAllTestsDone);
      _grid.Rows.Clear();
      runButton.Enabled = false;

      System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(_threadFunc));
      t.IsBackground = true;
      t.Start();
    }

    void _test_OnAllTestsDone(object sender, EventArgs e)
    {
      if (InvokeRequired)
        Invoke(new EventHandler(_test_OnAllTestsDone), sender, e);
      else
        runButton.Enabled = true;

      //
      // NOTE: In "automatic" mode, check if any of the tests failed and return
      //       the appropriate error code to the operating system as we exit
      //       the process.  Also, attempt to write the entire contents of the
      //       test grid to the standard output channel via the console.  This
      //       may fail if we have no console; however, the failure will simply
      //       be ignored.
      //
      if (_autoRun)
      {
          try
          {
              Console.Write("{0}", GridToText());
          }
          catch
          {
              // do nothing, ignored.
          }

          Environment.Exit(_failed != 0 ? 1 : 0);
      }
    }

    void _threadFunc()
    {
      _test.Run();
    }

    void _test_OnTestFinished(object sender, TestEventArgs args)
    {
      if (InvokeRequired)
        Invoke(new TestCompletedEvent(_test_OnTestFinished), sender, args);
      else
      {
        _grid.Rows[_grid.Rows.Count - 1].SetValues(args.TestName, args.Result, args.Duration, (args.Exception == null) ? args.Message : args.Exception.Message);
        if (args.Result == TestResultEnum.Failed)
        {
          _failed++;

          _grid.Rows[_grid.Rows.Count - 1].Cells[1].Style.BackColor = Color.Red;
        }
        else if (args.Result == TestResultEnum.Inconclusive)
        {
          _grid.Rows[_grid.Rows.Count - 1].Cells[1].Style.BackColor = Color.LightBlue;
        }
        //_grid.Rows[_grid.Rows.Count - 1].Height = _grid.Rows[_grid.Rows.Count - 1].GetPreferredHeight(_grid.Rows.Count - 1, DataGridViewAutoSizeRowMode.AllCells, true);
      }
    }

    void _test_OnTestStarting(object sender, TestEventArgs args)
    {
      if (InvokeRequired)
        Invoke(new TestStartingEvent(_test_OnTestStarting), sender, args);
      else
      {
        _grid.Rows.Add(args.TestName, "Starting", null, null);
        _grid.FirstDisplayedScrollingRowIndex = _grid.Rows.Count - 1;
      }
    }

    private void closeButton_Click(object sender, EventArgs e)
    {
      if (_autoRun)
      {
        try
        {
          Console.Write("canceled...");
        }
        catch
        {
          // do nothing, ignored.
        }

        Environment.Exit(2);
      }

      Close();
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































Deleted test/TestCasesDialog.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="label1.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="label2.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="closeButton.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="Test.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="Result.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="Time.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="Information.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="Test.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="Result.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="Time.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="Information.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
    <value>17, 17</value>
  </metadata>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































Changes to test/app.config.
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.77.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
</configuration>



<
|



1
2
3

4
5
6
7
<configuration>
  <system.data>
    <DbProviderFactories>

      <add name="SQLite Data Provider" invariant="System.Data.SQLite" support="3F" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>
</configuration>
Deleted test/test.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * test.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}</ProjectGuid>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <OutputType>Exe</OutputType>
    <RootNamespace>test</RootNamespace>
    <AssemblyName>test</AssemblyName>
    <OldToolsVersion>2.0</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.2008.csproj">
      <Project>{AC139952-261A-4463-B6FA-AEBC25283A66}</Project>
      <Name>System.Data.SQLite.2008</Name>
      <Private>False</Private>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Transactions" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="TestCases.cs" />
    <Compile Include="TestCasesDialog.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="TestCasesDialog.Designer.cs">
      <DependentUpon>TestCasesDialog.cs</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <EmbeddedResource Include="TestCasesDialog.resx">
      <DependentUpon>TestCasesDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































Deleted test/test.2010.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * test.2010.csproj -
 *
 * 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>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.30319</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}</ProjectGuid>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <OutputType>Exe</OutputType>
    <RootNamespace>test</RootNamespace>
    <AssemblyName>test</AssemblyName>
    <OldToolsVersion>3.5</OldToolsVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <ConfigurationYear>2010</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.2010.csproj">
      <Project>{AC139952-261A-4463-B6FA-AEBC25283A66}</Project>
      <Name>System.Data.SQLite.2010</Name>
      <Private>False</Private>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Transactions" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="TestCases.cs" />
    <Compile Include="TestCasesDialog.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="TestCasesDialog.Designer.cs">
      <DependentUpon>TestCasesDialog.cs</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <EmbeddedResource Include="TestCasesDialog.resx">
      <DependentUpon>TestCasesDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































Added test/test.csproj.












































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.41202</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>test</RootNamespace>
    <AssemblyName>test</AssemblyName>
    <WarningLevel>4</WarningLevel>
    <IsWebBootstrapper>true</IsWebBootstrapper>
    <PublishUrl>http://localhost/test</PublishUrl>
    <Install>true</Install>
    <InstallFrom>Web</InstallFrom>
    <UpdateEnabled>true</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>false</MapFileExtensions>
    <ApplicationVersion>1.0.0.*</ApplicationVersion>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>.\bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>.\bin\Release\</OutputPath>
    <DefineConstants>
    </DefineConstants>
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
    <Compile Include="Program.cs" />
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="TestCases.cs" />
  </ItemGroup>
  <ItemGroup>
    <BootstrapperFile Include="Microsoft.Net.Framework.2.0">
      <InProject>False</InProject>
      <ProductName>.NET Framework 2.0</ProductName>
      <Install>true</Install>
    </BootstrapperFile>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.csproj">
      <Project>{AC139951-261A-4463-B6FA-AEBC25283A66}</Project>
      <Name>System.Data.SQLite</Name>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>
Added test/test.csproj.user.




































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <LastOpenVersion>8.0.41202</LastOpenVersion>
    <ProjectView>ProjectFiles</ProjectView>
    <ProjectTrust>0</ProjectTrust>
    <PublishUrlHistory>http://localhost/test||||</PublishUrlHistory>
    <InstallUrlHistory>||||</InstallUrlHistory>
    <SupportUrlHistory>||||</SupportUrlHistory>
    <UpdateUrlHistory>||||</UpdateUrlHistory>
    <BootstrapperUrlHistory>||||</BootstrapperUrlHistory>
    <ApplicationRevision>0</ApplicationRevision>
    <FallbackCulture>en-US</FallbackCulture>
    <VerifyUploadedFiles>true</VerifyUploadedFiles>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
  </PropertyGroup>
</Project>
Deleted testce/AssemblyInfo.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
/********************************************************
 * 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.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite Tester for Windows CE")]
[assembly: AssemblyDescription("ADO.NET Data Provider for SQLite")]
[assembly: AssemblyCompany("http://system.data.sqlite.org/")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM componenets.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("308969a2-e089-42db-afe3-bf564d8d62c3")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.77.0")]
// [assembly: AssemblyFileVersion("1.0.77.0")]

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































Deleted testce/Form1.Designer.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
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace test
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;
		private System.Windows.Forms.MainMenu mainMenu1;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
      this.mainMenu1 = new System.Windows.Forms.MainMenu();
      this.menuItem1 = new System.Windows.Forms.MenuItem();
      this.textBox1 = new System.Windows.Forms.TextBox();
      this.SuspendLayout();
      // 
      // mainMenu1
      // 
      this.mainMenu1.MenuItems.Add(this.menuItem1);
      // 
      // menuItem1
      // 
      this.menuItem1.Text = "Exit";
      this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
      // 
      // textBox1
      // 
      this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
      this.textBox1.Location = new System.Drawing.Point(0, 0);
      this.textBox1.Multiline = true;
      this.textBox1.Name = "textBox1";
      this.textBox1.Size = new System.Drawing.Size(176, 180);
      this.textBox1.TabIndex = 0;
      this.textBox1.WordWrap = false;
      // 
      // Form1
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
      this.ClientSize = new System.Drawing.Size(176, 180);
      this.Controls.Add(this.textBox1);
      this.Menu = this.mainMenu1;
      this.Name = "Form1";
      this.Text = "Form1";
      this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.TextBox textBox1;
    private System.Windows.Forms.MenuItem menuItem1;
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































Deleted testce/Form1.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
/********************************************************
 * 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.Windows.Forms;

namespace test
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
    }

		public void WriteLine(string str)
		{
			textBox1.Text += str + "\r\n";
		}

    public void Write(string str)
    {
      textBox1.Text += str;
    }

    private void menuItem1_Click(object sender, EventArgs e)
    {
      Close();
    }
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































Deleted testce/Form1.resx.
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
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
    <value>17, 17</value>
  </metadata>
  <metadata name="$this.FormFactorShadowProperty" xml:space="preserve">
    <value>Smartphone</value>
  </metadata>
  <metadata name="$this.Skin" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































Deleted testce/Program.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
using System;
using System.Data.Common;
using System.Data.SQLite;

namespace test
{
  class Program
  {
    [MTAThread]
    static void Main()
    {
      DbConnection cnn;

      SQLiteFunction.RegisterFunction(typeof(TestFunc));
      SQLiteFunction.RegisterFunction(typeof(MyCount));
      SQLiteFunction.RegisterFunction(typeof(MySequence));

      try
      {
        System.IO.File.Delete("test.db3");
      }
      catch
      {
      }

      //SQLiteConnection sqlite_con = new SQLiteConnection(@"data source=""|DataDirectory|donnees.db""");

      //SQLiteDataAdapter sqlite_da = new SQLiteDataAdapter();
      //DataSet dataSet = new DataSet();

      //sqlite_da.SelectCommand = new SQLiteCommand("select * from donnees", sqlite_con);



      //sqlite_con.Open();

      //sqlite_da.Fill(dataSet);

      //sqlite_con.Close();

      using (cnn = new SQLiteConnection())
      {
        TestCases tests = new TestCases();

        cnn.ConnectionString = "Data Source=test.db3;Password=yVXL39etehPX";
        cnn.Open();
        tests.Run(cnn);

        System.Windows.Forms.Application.Run(tests.frm);
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































Deleted testce/TestCases.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
/********************************************************
 * 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.Data.Common;
using System.Data;
using System.Data.SQLite;

namespace test
{

  /// <summary>
  /// Scalar user-defined function.  In this example, the same class is declared twice with 
  /// different function names to demonstrate how to use alias names for user-defined functions.
  /// </summary>
  [SQLiteFunction(Name = "Foo", Arguments = 2, FuncType = FunctionType.Scalar)]
  [SQLiteFunction(Name = "TestFunc", Arguments = 2, FuncType = FunctionType.Scalar)]
  class TestFunc : SQLiteFunction
  {
    public override object Invoke(object[] args)
    {
      if (args[0].GetType() != typeof(int)) return args[0];

      int Param1 = Convert.ToInt32(args[0]); // First parameter
      int Param2 = Convert.ToInt32(args[1]); // Second parameter

      return Param1 + Param2;
    }
  }

  /// <summary>
  /// Aggregate user-defined function.  Arguments = -1 means any number of arguments is acceptable
  /// </summary>
  [SQLiteFunction(Name = "MyCount", Arguments = -1, FuncType = FunctionType.Aggregate)]
  class MyCount : SQLiteFunction
  {
    public override void Step(object[] args, int nStep, ref object contextData)
    {
      if (contextData == null)
      {
        contextData = 1;
      }
      else
        contextData = (int)contextData + 1;
    }

    public override object Final(object contextData)
    {
      return contextData;
    }
  }

  /// <summary>
  /// User-defined collating sequence.
  /// </summary>
  [SQLiteFunction(Name = "MYSEQUENCE", FuncType = FunctionType.Collation)]
  class MySequence : SQLiteFunction
  {
    public override int Compare(string param1, string param2)
    {
      // Make sure the string "Field3" is sorted out of order
      if (param1 == "Field3") return 1;
      if (param2 == "Field3") return -1;
      return String.Compare(param1, param2, true);
    }
  }

  internal class TestCases
  {
    internal Form1 frm;

    internal void Run(DbConnection cnn)
    {
      frm = new Form1();

      frm.Show();

      frm.WriteLine("\r\nBeginning Test on " + cnn.GetType().ToString());
      try { CreateTable(cnn); frm.WriteLine("SUCCESS - CreateTable"); }
      catch (Exception) { frm.WriteLine("FAIL - CreateTable"); }

      try { DataTypeTest(cnn); frm.WriteLine("SUCCESS - DataType Test"); }
      catch (Exception) { frm.WriteLine("FAIL - DataType Test"); }

      try { FullTextTest(cnn); frm.WriteLine("SUCCESS - Full Text Search"); }
      catch (Exception) { frm.WriteLine("FAIL - Full Text Search"); }

      try { KeyInfoTest(cnn); frm.WriteLine("SUCCESS - KeyInfo Fetch"); }
      catch (Exception) { frm.WriteLine("FAIL - KeyInfo Fetch"); }

      try { InsertTable(cnn); frm.WriteLine("SUCCESS - InsertTable"); }
      catch (Exception) { frm.WriteLine("FAIL - InsertTable"); }

      try { VerifyInsert(cnn); frm.WriteLine("SUCCESS - VerifyInsert"); }
      catch (Exception) { frm.WriteLine("FAIL - VerifyInsert"); }

      try { CoersionTest(cnn); frm.WriteLine("FAIL - CoersionTest"); }
      catch (Exception) { frm.WriteLine("SUCCESS - CoersionTest"); }

      try { ParameterizedInsert(cnn); frm.WriteLine("SUCCESS - ParameterizedInsert"); }
      catch (Exception) { frm.WriteLine("FAIL - ParameterizedInsert"); }

      try { BinaryInsert(cnn); frm.WriteLine("SUCCESS - BinaryInsert"); }
      catch (Exception) { frm.WriteLine("FAIL - BinaryInsert"); }

      try { VerifyBinaryData(cnn); frm.WriteLine("SUCCESS - VerifyBinaryData"); }
      catch (Exception) { frm.WriteLine("FAIL - VerifyBinaryData"); }

      try { LockTest(cnn); frm.WriteLine("SUCCESS - LockTest"); }
      catch (Exception) { frm.WriteLine("FAIL - LockTest"); }

      try { ParameterizedInsertMissingParams(cnn); frm.WriteLine("FAIL - ParameterizedInsertMissingParams"); }
      catch (Exception) { frm.WriteLine("SUCCESS - ParameterizedInsertMissingParams"); }

      try { InsertMany(cnn, false); frm.WriteLine("SUCCESS - InsertMany"); }
      catch (Exception) { frm.WriteLine("FAIL - InsertMany"); }

      try { InsertMany(cnn, true); frm.WriteLine("SUCCESS - InsertManyWithIdentityFetch"); }
      catch (Exception) { frm.WriteLine("FAIL - InsertManyWithIdentityFetch"); }

      try { FastInsertMany(cnn); frm.WriteLine("SUCCESS - FastInsertMany"); }
      catch (Exception) { frm.WriteLine("FAIL - FastInsertMany"); }

      try { IterationTest(cnn); frm.WriteLine("SUCCESS - Iteration Test"); }
      catch (Exception) { frm.WriteLine("FAIL - Iteration Test"); }

      try { UserFunction(cnn); frm.WriteLine("SUCCESS - UserFunction"); }
      catch (Exception) { frm.WriteLine("FAIL - UserFunction"); }

      try { UserAggregate(cnn); frm.WriteLine("SUCCESS - UserAggregate"); }
      catch (Exception) { frm.WriteLine("FAIL - UserAggregate"); }

      try { UserCollation(cnn); frm.WriteLine("SUCCESS - UserCollation"); }
      catch (Exception) { frm.WriteLine("FAIL - UserCollation"); }

      try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); }
      catch (Exception) { frm.WriteLine("FAIL - DropTable"); }

      frm.WriteLine("\r\nTests Finished.");
    }

    internal static void KeyInfoTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        // First test against integer primary key (optimized) keyinfo fetch
        cmd.CommandText = "Create table keyinfotest (id integer primary key, myuniquevalue integer unique not null, myvalue varchar(50))";
        cmd.ExecuteNonQuery();

        cmd.CommandText = "Select * from keyinfotest";
        using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
        {
          using (DataTable tbl = reader.GetSchemaTable())
          {
            if (tbl.Rows.Count != 3) throw new ArgumentOutOfRangeException("Wrong number of columns returned");
          }
        }

        cmd.CommandText = "SELECT MyValue FROM keyinfotest";
        using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
        {
          using (DataTable tbl = reader.GetSchemaTable())
          {
            if (tbl.Rows.Count != 2) throw new ArgumentOutOfRangeException("Wrong number of columns returned");
          }
        }

        cmd.CommandText = "DROP TABLE keyinfotest";
        cmd.ExecuteNonQuery();

        // Now test against non-integer primary key (unoptimized) subquery keyinfo fetch
        cmd.CommandText = "Create table keyinfotest (id char primary key, myuniquevalue integer unique not null, myvalue varchar(50))";
        cmd.ExecuteNonQuery();

        cmd.CommandText = "SELECT MyValue FROM keyinfotest";
        using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
        {
          using (DataTable tbl = reader.GetSchemaTable())
          {
            if (tbl.Rows.Count != 2) throw new ArgumentOutOfRangeException("Wrong number of columns returned");
          }
        }

        cmd.CommandText = "Select * from keyinfotest";
        using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
        {
          using (DataTable tbl = reader.GetSchemaTable())
          {
            if (tbl.Rows.Count != 3) throw new ArgumentOutOfRangeException("Wrong number of columns returned");
          }
        }

        // Make sure commandbuilder can generate an update command with the correct parameter count
        using (DbDataAdapter adp = new SQLiteDataAdapter())
        using (DbCommandBuilder builder = new SQLiteCommandBuilder())
        {
          adp.SelectCommand = cmd;
          builder.DataAdapter = adp;
          builder.ConflictOption = ConflictOption.OverwriteChanges;

          using (DbCommand updatecmd = builder.GetUpdateCommand())
          {
            if (updatecmd.Parameters.Count != 4)
              throw new ArgumentOutOfRangeException("Wrong number of parameters in update command!");
          }
        }
      }
    }

    internal static void DataTypeTest(DbConnection cnn)
    {
      DateTime now = DateTime.Now;
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "create table datatypetest(id integer primary key, myvalue, datetimevalue datetime, decimalvalue decimal)";
        cmd.ExecuteNonQuery();

        cmd.CommandText = "insert into datatypetest(myvalue, datetimevalue, decimalvalue) values(?,?,?)";
        DbParameter p1 = cmd.CreateParameter();
        DbParameter p2 = cmd.CreateParameter();
        DbParameter p3 = cmd.CreateParameter();

        cmd.Parameters.Add(p1);
        cmd.Parameters.Add(p2);
        cmd.Parameters.Add(p3);

        p1.Value = 1;
        p2.Value = DateTime.MinValue;
        p3.Value = (Decimal)1.05;
        cmd.ExecuteNonQuery();

        p1.ResetDbType();
        p2.ResetDbType();
        p3.ResetDbType();

        p1.Value = "One";
        p2.Value = "2001-01-01";
        p3.Value = (Decimal)1.0;
        cmd.ExecuteNonQuery();

        p1.ResetDbType();
        p2.ResetDbType();
        p3.ResetDbType();

        p1.Value = 1.01;
        p2.Value = now;
        p3.Value = (Decimal)9.91;
        cmd.ExecuteNonQuery();

        cmd.CommandText = "select myvalue, datetimevalue, decimalvalue from datatypetest";
        using (DbDataReader reader = cmd.ExecuteReader())
        {
          for (int n = 0; n < 3; n++)
          {
            reader.Read();
            if (reader.GetValue(1).GetType() != reader.GetDateTime(1).GetType()) throw new ArgumentOutOfRangeException();
            if (reader.GetValue(2).GetType() != reader.GetDecimal(2).GetType()) throw new ArgumentOutOfRangeException();

            switch (n)
            {
              case 0:
                if (reader.GetValue(0).GetType() != typeof(long)) throw new ArgumentOutOfRangeException();

                if (reader.GetValue(0).Equals((long)1) == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(1).Equals(DateTime.MinValue) == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(2).Equals((Decimal)1.05) == false) throw new ArgumentOutOfRangeException();

                if (reader.GetInt64(0) != (long)1) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(1).Equals(reader.GetDateTime(1)) == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(2).Equals(reader.GetDecimal(2)) == false) throw new ArgumentOutOfRangeException();
                break;
              case 1:
                if (reader.GetValue(0).GetType() != typeof(string)) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(0).Equals("One") == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(1).Equals(new DateTime(2001, 1, 1)) == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(2).Equals((Decimal)1.0) == false) throw new ArgumentOutOfRangeException();

                if (reader.GetString(0) != "One") throw new ArgumentOutOfRangeException();
                if (reader.GetValue(1).Equals(reader.GetDateTime(1)) == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(2).Equals(reader.GetDecimal(2)) == false) throw new ArgumentOutOfRangeException();
                break;
              case 2:
                if (reader.GetValue(0).GetType() != typeof(double)) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(0).Equals(1.01) == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(1).Equals(now) == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(2).Equals((Decimal)9.91) == false) throw new ArgumentOutOfRangeException();

                if (reader.GetDouble(0) != 1.01) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(1).Equals(reader.GetDateTime(1)) == false) throw new ArgumentOutOfRangeException();
                if (reader.GetValue(2).Equals(reader.GetDecimal(2)) == false) throw new ArgumentOutOfRangeException();
                break;
            }
          }
        }
      }
    }

    internal static void FullTextTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "CREATE VIRTUAL TABLE FullText USING FTS3(name, ingredients);";
        cmd.ExecuteNonQuery();

        string[] names = { "broccoli stew", "pumpkin stew", "broccoli pie", "pumpkin pie" };
        string[] ingredients = { "broccoli peppers cheese tomatoes", "pumpkin onions garlic celery", "broccoli cheese onions flour", "pumpkin sugar flour butter" };
        int n;

        cmd.CommandText = "insert into FullText (name, ingredients) values (@name, @ingredient);";
        DbParameter name = cmd.CreateParameter();
        DbParameter ingredient = cmd.CreateParameter();

        name.ParameterName = "@name";
        ingredient.ParameterName = "@ingredient";

        cmd.Parameters.Add(name);
        cmd.Parameters.Add(ingredient);

        for (n = 0; n < names.Length; n++)
        {
          name.Value = names[n];
          ingredient.Value = ingredients[n];

          cmd.ExecuteNonQuery();
        }

        cmd.CommandText = "select rowid, name, ingredients from FullText where name match 'pie';";

        int[] rowids = { 3, 4 };
        n = 0;

        using (DbDataReader reader = cmd.ExecuteReader())
        {
          while (reader.Read())
          {
            if (reader.GetInt64(0) != rowids[n++])
              throw new ArgumentException("Unexpected rowid returned");

            if (n > rowids.Length) throw new ArgumentException("Too many rows returned");
          }
        }
      }
    }

    internal void CreateTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "CREATE TABLE TestCase (ID integer primary key autoincrement, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)";
        //cmd.CommandText = "CREATE TABLE TestCase (ID bigint primary key identity, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)";
        cmd.ExecuteNonQuery();
      }
    }

    internal void DropTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "DROP TABLE TestCase";
        cmd.ExecuteNonQuery();
      }
    }

    internal void InsertTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(1, 3.14159, 'Field3', 'Field4', '2005-01-01 13:49:00')";
        cmd.ExecuteNonQuery();
      }
    }

    internal void VerifyInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, Field3, Field4, Field5 FROM TestCase";
        cmd.Prepare();
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read())
          {
            long Field1 = rd.GetInt64(0);
            double Field2 = rd.GetDouble(1);
            string Field3 = rd.GetString(2);
            string Field4 = rd.GetString(3).TrimEnd();
            DateTime Field5 = rd.GetDateTime(4);

            if (Field1 != 1) throw new ArgumentOutOfRangeException("Non-Match on Field1");
            if (Field2 != 3.14159) throw new ArgumentOutOfRangeException("Non-Match on Field2");
            if (Field3 != "Field3") throw new ArgumentOutOfRangeException("Non-Match on Field3");
            if (Field4 != "Field4") throw new ArgumentOutOfRangeException("Non-Match on Field4");
            if (Field5.CompareTo(DateTime.Parse("2005-01-01 13:49:00")) != 0) throw new ArgumentOutOfRangeException("Non-Match on Field5");
          }
          else throw new ArgumentOutOfRangeException("No data in table");
        }
      }
    }

    internal void CoersionTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, Field3, Field4, Field5, 'A', 1, 1 + 1, 3.14159 FROM TestCase";
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read())
          {
            object Field1 = rd.GetInt32(0);
            object Field2 = rd.GetDouble(1);
            object Field3 = rd.GetString(2);
            object Field4 = rd.GetString(3).TrimEnd();
            object Field5 = rd.GetDateTime(4);

            // The next statement should cause an exception
            Field1 = rd.GetString(0);
            Field2 = rd.GetString(1);
            Field3 = rd.GetString(2);
            Field4 = rd.GetString(3);
            Field5 = rd.GetString(4);

            Field1 = rd.GetInt32(0);
            Field2 = rd.GetInt32(1);
            Field3 = rd.GetInt32(2);
            Field4 = rd.GetInt32(3);
            Field5 = rd.GetInt32(4);

            Field1 = rd.GetDecimal(0);
            Field2 = rd.GetDecimal(1);
            Field3 = rd.GetDecimal(2);
            Field4 = rd.GetDecimal(3);
            Field5 = rd.GetDecimal(4);
          }
          else throw new ArgumentOutOfRangeException("No data in table");
        }
      }
    }

    internal void ParameterizedInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(?,?,?,?,?)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
        DbParameter Field3 = cmd.CreateParameter();
        DbParameter Field4 = cmd.CreateParameter();
        DbParameter Field5 = cmd.CreateParameter();

        Field1.Value = 2;
        Field2.Value = 3.14159;
        Field3.Value = "Param Field3";
        Field4.Value = "Field4 Par";
        Field5.Value = DateTime.Now;

        cmd.Parameters.Add(Field1);
        cmd.Parameters.Add(Field2);
        cmd.Parameters.Add(Field3);
        cmd.Parameters.Add(Field4);
        cmd.Parameters.Add(Field5);

        cmd.ExecuteNonQuery();
      }
    }

    internal void BinaryInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field6) VALUES(?)";
        DbParameter Field6 = cmd.CreateParameter();

        byte[] b = new byte[4000];
        b[0] = 1;
        b[100] = 2;
        b[1000] = 3;
        b[2000] = 4;
        b[3000] = 5;

        Field6.Value = b;

        cmd.Parameters.Add(Field6);

        cmd.ExecuteNonQuery();
      }
    }

    internal void VerifyBinaryData(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field6 FROM TestCase WHERE Field6 IS NOT NULL";
        byte[] b = new byte[4000];

        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read() == false) throw new ArgumentOutOfRangeException();

          rd.GetBytes(0, 0, b, 0, 4000);

          if (b[0] != 1) throw new ArgumentException();
          if (b[100] != 2) throw new ArgumentException();
          if (b[1000] != 3) throw new ArgumentException();
          if (b[2000] != 4) throw new ArgumentException();
          if (b[3000] != 5) throw new ArgumentException();
        }
      }
    }

    internal static void LockTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field6 FROM TestCase WHERE Field6 IS NOT NULL";
        byte[] b = new byte[4000];

        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read() == false) throw new ArgumentOutOfRangeException();

          rd.GetBytes(0, 0, b, 0, 4000);

          if (b[0] != 1) throw new ArgumentException();
          if (b[100] != 2) throw new ArgumentException();
          if (b[1000] != 3) throw new ArgumentException();
          if (b[2000] != 4) throw new ArgumentException();
          if (b[3000] != 5) throw new ArgumentException();

          using (DbConnection clone = (DbConnection)((ICloneable)cnn).Clone())
          {
            using (DbCommand newcmd = clone.CreateCommand())
            {
              newcmd.CommandText = "DELETE FROM TestCase WHERE Field6 IS NULL";
              newcmd.CommandTimeout = 2;
              int cmdStart = Environment.TickCount;
              int cmdEnd;

              try
              {
                newcmd.ExecuteNonQuery(); // should fail because there's a reader on the database
                throw new ArgumentException(); // If we got here, the test failed
              }
              catch
              {
                cmdEnd = Environment.TickCount;
                if (cmdEnd - cmdStart < 2000 || cmdEnd - cmdStart > 3000)
                  throw new ArgumentException(); // Didn't wait the right amount of time
              }
            }
          }
        }
      }
    }

    internal void ParameterizedInsertMissingParams(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(?,?,?,?,?)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
        DbParameter Field3 = cmd.CreateParameter();
        DbParameter Field4 = cmd.CreateParameter();
        DbParameter Field5 = cmd.CreateParameter();

        Field1.DbType = System.Data.DbType.Int32;

        Field1.Value = 2;
        Field2.Value = 3.14159;
        Field3.Value = "Field3 Param";
        Field4.Value = "Field4 Par";
        Field5.Value = DateTime.Now;

        cmd.Parameters.Add(Field1);
        cmd.Parameters.Add(Field2);
        cmd.Parameters.Add(Field3);
        cmd.Parameters.Add(Field4);

        // Assertion here, not enough parameters
        cmd.ExecuteNonQuery();
      }
    }

    // Utilizes the SQLiteCommandBuilder, which in turn utilizes SQLiteDataReader's GetSchemaTable() functionality
    internal void InsertMany(DbConnection cnn, bool bWithIdentity)
    {
      int nmax = 1000;

      using (DbTransaction dbTrans = cnn.BeginTransaction())
      {
        using (DbDataAdapter adp = new SQLiteDataAdapter())
        {
          using (DbCommand cmd = cnn.CreateCommand())
          {
            cmd.Transaction = dbTrans;
            cmd.CommandText = "SELECT * FROM TestCase WHERE 1=2";
            adp.SelectCommand = cmd;

            using (DbCommandBuilder bld = new SQLiteCommandBuilder())
            {
              bld.DataAdapter = adp;
              using (adp.InsertCommand = (SQLiteCommand)((ICloneable)bld.GetInsertCommand()).Clone())
              {
                bld.DataAdapter = null;
                if (bWithIdentity)
                {
                  adp.InsertCommand.CommandText += ";SELECT last_insert_rowid() AS [ID]";
                  adp.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
                }

                using (DataTable tbl = new DataTable())
                {
                  adp.Fill(tbl);
                  for (int n = 0; n < nmax; n++)
                  {
                    DataRow row = tbl.NewRow();
                    row[1] = n + nmax;
                    tbl.Rows.Add(row);
                  }

                  frm.Write(String.Format("          InsertMany{0} ({1} rows) Begins ... ", (bWithIdentity == true) ? "WithIdentityFetch" : "                 ", nmax));
                  int dtStart = Environment.TickCount;
                  adp.Update(tbl);
                  int dtEnd = Environment.TickCount;
                  dtEnd -= dtStart;
                  frm.Write(String.Format("Ends in {0} ms ... ", (dtEnd)));

                  dtStart = Environment.TickCount;
                  dbTrans.Commit();
                  dtEnd = Environment.TickCount;
                  dtEnd -= dtStart;
                  frm.WriteLine(String.Format("Commits in {0} ms", (dtEnd)));
                }
              }
            }
          }
        }
      }
    }

    internal void FastInsertMany(DbConnection cnn)
    {
      using (DbTransaction dbTrans = cnn.BeginTransaction())
      {
        int dtStart;
        int dtEnd;

        using (DbCommand cmd = cnn.CreateCommand())
        {
          cmd.CommandText = "INSERT INTO TestCase(Field1) VALUES(?)";
          DbParameter Field1 = cmd.CreateParameter();

          cmd.Parameters.Add(Field1);

          frm.WriteLine(String.Format("          Fast insert using parameters and prepared statement\r\n          -> (10,000 rows) Begins ... "));
          dtStart = Environment.TickCount;
          for (int n = 0; n < 10000; n++)
          {
            Field1.Value = n + 100000;
            cmd.ExecuteNonQuery();
          }

          dtEnd = Environment.TickCount;
          dtEnd -= dtStart;
          frm.Write(String.Format("          -> Ends in {0} ms ... ", (dtEnd)));
        }

        dtStart = Environment.TickCount;
        dbTrans.Rollback();
        dtEnd = Environment.TickCount;
        dtEnd -= dtStart;
        frm.WriteLine(String.Format("Rolled back in {0} ms", (dtEnd)));
      }
    }

    // Causes the user-defined function to be called
    internal void UserFunction(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int nTimes;
        int dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT Foo('ee','foo')";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          User (text)  command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT Foo(10,11)";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          UserFunction command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT ABS(1)";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          Intrinsic    command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT lower('FOO')";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          Intrin (txt) command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT 1";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          Raw Value    command executed {0} times in 1 second.", nTimes));
      }
    }

    internal void IterationTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int dtStart;
        int dtEnd;
        int nCount;
        long n;

        cmd.CommandText = "SELECT Foo(ID, ID) FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        frm.WriteLine(String.Format("          User Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

        cmd.CommandText = "SELECT ID FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        frm.WriteLine(String.Format("          Raw iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

        cmd.CommandText = "SELECT ABS(ID) FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        frm.WriteLine(String.Format("          Intrinsic Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

      }
    }

    // Causes the user-defined aggregate to be iterated through
    internal void UserAggregate(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int dtStart;
        int n = 0;
        int nCount;

        cmd.CommandText = "SELECT MyCount(*) FROM TestCase";

        nCount = 0;
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          n = Convert.ToInt32(cmd.ExecuteScalar());
          nCount++;
        }
        if (n != 2003) throw new ArgumentOutOfRangeException("Unexpected count");
        frm.WriteLine(String.Format("          UserAggregate executed {0} times in 1 second.", nCount));
      }
    }

    // Causes the user-defined collation sequence to be iterated through
    internal void UserCollation(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        // Using a default collating sequence in descending order, "Param Field3" will appear at the top
        // and "Field3" will be next, followed by a NULL.  Our user-defined collating sequence will 
        // deliberately place them out of order so Field3 is first.
        cmd.CommandText = "SELECT Field3 FROM TestCase ORDER BY Field3 COLLATE MYSEQUENCE DESC";
        string s = (string)cmd.ExecuteScalar();
        if (s != "Field3") throw new ArgumentOutOfRangeException("MySequence didn't sort properly");
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted testce/testce.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * testce.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>test</RootNamespace>
    <AssemblyName>testce</AssemblyName>
    <ProjectTypeGuids>{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <PlatformFamilyName>WindowsCE</PlatformFamilyName>
    <PlatformID>E2BECB1F-8C8C-41ba-B736-9BE7D946A398</PlatformID>
    <OSVersion>5.0</OSVersion>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <OldToolsVersion>2.0</OldToolsVersion>
    <NativePlatformName>Windows CE</NativePlatformName>
    <FormFactorID></FormFactorID>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
    <ConfigurationSuffix>Compact</ConfigurationSuffix>
    <DeployDirSuffix>testce</DeployDirSuffix>
    <DeployDirPrefix>%25CSIDL_PROGRAM_FILES%25</DeployDirPrefix>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE;$(PlatformFamilyName)</DefineConstants>
    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <ErrorReport>prompt</ErrorReport>
    <GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE;$(PlatformFamilyName)</DefineConstants>
    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <ErrorReport>prompt</ErrorReport>
    <GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="mscorlib" />
    <Reference Include="System">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Data">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Drawing">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Windows.Forms">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Xml">
      <Private>False</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="Form1.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Form1.Designer.cs">
      <DependentUpon>Form1.cs</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="TestCases.cs">
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Form1.resx">
      <DependentUpon>Form1.cs</DependentUpon>
      <SubType>Designer</SubType>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.Compact.2008.csproj">
      <Project>{AC139951-261A-4463-B6FA-AEBC25283A66}</Project>
      <Name>System.Data.SQLite.Compact.2008</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Condition="'$(TargetFrameworkVersion)' == 'v1.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.v1.targets" />
  <Import Condition="'$(TargetFrameworkVersion)' == 'v2.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
  <Import Condition="'$(TargetFrameworkVersion)' == 'v3.5'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
  <ProjectExtensions>
    <VisualStudio>
      <FlavorProperties GUID="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}">
        <HostingProcess disable="1" />
      </FlavorProperties>
    </VisualStudio>
  </ProjectExtensions>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































Deleted testlinq/2008/App.config.
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.77.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>
<
<
<
<
<
<
<
<
<
<
<
<
























Deleted testlinq/2010/App.config.
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.77.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>
<
<
<
<
<
<
<
<
<
<
<
<
























Deleted testlinq/NorthwindModel2008.Designer.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
/********************************************************
 * 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!
 ********************************************************/

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.3053
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

[assembly: global::System.Data.Objects.DataClasses.EdmSchemaAttribute()]
[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("northwindEFModel", "FK_Products_CategoryID_CategoryID", "Categories", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(testlinq.Categories), "Products", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Products))]
[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("northwindEFModel", "FK_Orders_CustomerID_CustomerID", "Customers", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(testlinq.Customers), "Orders", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Orders))]
[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("northwindEFModel", "FK_InternationalOrders_OrderID_OrderID", "Orders", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(testlinq.Orders), "InternationalOrders", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(testlinq.InternationalOrders))]
[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("northwindEFModel", "FK_OrderDetails_OrderID_OrderID", "Orders", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(testlinq.Orders), "OrderDetails", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.OrderDetails))]
[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("northwindEFModel", "FK_OrderDetails_ProductID_ProductID", "Products", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(testlinq.Products), "OrderDetails", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.OrderDetails))]
[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("northwindEFModel", "FK_Products_SupplierID_SupplierID", "Suppliers", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(testlinq.Suppliers), "Products", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Products))]
[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("northwindEFModel", "FK_Territories_RegionID_RegionID", "Regions", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(testlinq.Regions), "Territories", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Territories))]
[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("northwindEFModel", "EmployeesTerritories", "Employees", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Employees), "Territories", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Territories))]

// Original file name:
// Generation date: 8/25/2008 8:54:05 AM
namespace testlinq
{
    
    /// <summary>
    /// There are no comments for northwindEFEntities in the schema.
    /// </summary>
    public partial class northwindEFEntities : global::System.Data.Objects.ObjectContext
    {
        /// <summary>
        /// Initializes a new northwindEFEntities object using the connection string found in the 'northwindEFEntities' section of the application configuration file.
        /// </summary>
        public northwindEFEntities() : 
                base("name=northwindEFEntities", "northwindEFEntities")
        {
            this.OnContextCreated();
        }
        /// <summary>
        /// Initialize a new northwindEFEntities object.
        /// </summary>
        public northwindEFEntities(string connectionString) : 
                base(connectionString, "northwindEFEntities")
        {
            this.OnContextCreated();
        }
        /// <summary>
        /// Initialize a new northwindEFEntities object.
        /// </summary>
        public northwindEFEntities(global::System.Data.EntityClient.EntityConnection connection) : 
                base(connection, "northwindEFEntities")
        {
            this.OnContextCreated();
        }
        partial void OnContextCreated();
        /// <summary>
        /// There are no comments for Categories in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<Categories> Categories
        {
            get
            {
                if ((this._Categories == null))
                {
                    this._Categories = base.CreateQuery<Categories>("[Categories]");
                }
                return this._Categories;
            }
        }
        private global::System.Data.Objects.ObjectQuery<Categories> _Categories;
        /// <summary>
        /// There are no comments for Customers in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<Customers> Customers
        {
            get
            {
                if ((this._Customers == null))
                {
                    this._Customers = base.CreateQuery<Customers>("[Customers]");
                }
                return this._Customers;
            }
        }
        private global::System.Data.Objects.ObjectQuery<Customers> _Customers;
        /// <summary>
        /// There are no comments for Employees in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<Employees> Employees
        {
            get
            {
                if ((this._Employees == null))
                {
                    this._Employees = base.CreateQuery<Employees>("[Employees]");
                }
                return this._Employees;
            }
        }
        private global::System.Data.Objects.ObjectQuery<Employees> _Employees;
        /// <summary>
        /// There are no comments for InternationalOrders in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<InternationalOrders> InternationalOrders
        {
            get
            {
                if ((this._InternationalOrders == null))
                {
                    this._InternationalOrders = base.CreateQuery<InternationalOrders>("[InternationalOrders]");
                }
                return this._InternationalOrders;
            }
        }
        private global::System.Data.Objects.ObjectQuery<InternationalOrders> _InternationalOrders;
        /// <summary>
        /// There are no comments for OrderDetails in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<OrderDetails> OrderDetails
        {
            get
            {
                if ((this._OrderDetails == null))
                {
                    this._OrderDetails = base.CreateQuery<OrderDetails>("[OrderDetails]");
                }
                return this._OrderDetails;
            }
        }
        private global::System.Data.Objects.ObjectQuery<OrderDetails> _OrderDetails;
        /// <summary>
        /// There are no comments for Orders in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<Orders> Orders
        {
            get
            {
                if ((this._Orders == null))
                {
                    this._Orders = base.CreateQuery<Orders>("[Orders]");
                }
                return this._Orders;
            }
        }
        private global::System.Data.Objects.ObjectQuery<Orders> _Orders;
        /// <summary>
        /// There are no comments for PreviousEmployees in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<PreviousEmployees> PreviousEmployees
        {
            get
            {
                if ((this._PreviousEmployees == null))
                {
                    this._PreviousEmployees = base.CreateQuery<PreviousEmployees>("[PreviousEmployees]");
                }
                return this._PreviousEmployees;
            }
        }
        private global::System.Data.Objects.ObjectQuery<PreviousEmployees> _PreviousEmployees;
        /// <summary>
        /// There are no comments for Products in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<Products> Products
        {
            get
            {
                if ((this._Products == null))
                {
                    this._Products = base.CreateQuery<Products>("[Products]");
                }
                return this._Products;
            }
        }
        private global::System.Data.Objects.ObjectQuery<Products> _Products;
        /// <summary>
        /// There are no comments for Regions in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<Regions> Regions
        {
            get
            {
                if ((this._Regions == null))
                {
                    this._Regions = base.CreateQuery<Regions>("[Regions]");
                }
                return this._Regions;
            }
        }
        private global::System.Data.Objects.ObjectQuery<Regions> _Regions;
        /// <summary>
        /// There are no comments for Suppliers in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<Suppliers> Suppliers
        {
            get
            {
                if ((this._Suppliers == null))
                {
                    this._Suppliers = base.CreateQuery<Suppliers>("[Suppliers]");
                }
                return this._Suppliers;
            }
        }
        private global::System.Data.Objects.ObjectQuery<Suppliers> _Suppliers;
        /// <summary>
        /// There are no comments for Territories in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectQuery<Territories> Territories
        {
            get
            {
                if ((this._Territories == null))
                {
                    this._Territories = base.CreateQuery<Territories>("[Territories]");
                }
                return this._Territories;
            }
        }
        private global::System.Data.Objects.ObjectQuery<Territories> _Territories;
        /// <summary>
        /// There are no comments for Categories in the schema.
        /// </summary>
        public void AddToCategories(Categories categories)
        {
            base.AddObject("Categories", categories);
        }
        /// <summary>
        /// There are no comments for Customers in the schema.
        /// </summary>
        public void AddToCustomers(Customers customers)
        {
            base.AddObject("Customers", customers);
        }
        /// <summary>
        /// There are no comments for Employees in the schema.
        /// </summary>
        public void AddToEmployees(Employees employees)
        {
            base.AddObject("Employees", employees);
        }
        /// <summary>
        /// There are no comments for InternationalOrders in the schema.
        /// </summary>
        public void AddToInternationalOrders(InternationalOrders internationalOrders)
        {
            base.AddObject("InternationalOrders", internationalOrders);
        }
        /// <summary>
        /// There are no comments for OrderDetails in the schema.
        /// </summary>
        public void AddToOrderDetails(OrderDetails orderDetails)
        {
            base.AddObject("OrderDetails", orderDetails);
        }
        /// <summary>
        /// There are no comments for Orders in the schema.
        /// </summary>
        public void AddToOrders(Orders orders)
        {
            base.AddObject("Orders", orders);
        }
        /// <summary>
        /// There are no comments for PreviousEmployees in the schema.
        /// </summary>
        public void AddToPreviousEmployees(PreviousEmployees previousEmployees)
        {
            base.AddObject("PreviousEmployees", previousEmployees);
        }
        /// <summary>
        /// There are no comments for Products in the schema.
        /// </summary>
        public void AddToProducts(Products products)
        {
            base.AddObject("Products", products);
        }
        /// <summary>
        /// There are no comments for Regions in the schema.
        /// </summary>
        public void AddToRegions(Regions regions)
        {
            base.AddObject("Regions", regions);
        }
        /// <summary>
        /// There are no comments for Suppliers in the schema.
        /// </summary>
        public void AddToSuppliers(Suppliers suppliers)
        {
            base.AddObject("Suppliers", suppliers);
        }
        /// <summary>
        /// There are no comments for Territories in the schema.
        /// </summary>
        public void AddToTerritories(Territories territories)
        {
            base.AddObject("Territories", territories);
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.Categories in the schema.
    /// </summary>
    /// <KeyProperties>
    /// CategoryID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Categories")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class Categories : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new Categories object.
        /// </summary>
        /// <param name="categoryID">Initial value of CategoryID.</param>
        /// <param name="categoryName">Initial value of CategoryName.</param>
        public static Categories CreateCategories(long categoryID, string categoryName)
        {
            Categories categories = new Categories();
            categories.CategoryID = categoryID;
            categories.CategoryName = categoryName;
            return categories;
        }
        /// <summary>
        /// There are no comments for Property CategoryID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long CategoryID
        {
            get
            {
                return this._CategoryID;
            }
            set
            {
                this.OnCategoryIDChanging(value);
                this.ReportPropertyChanging("CategoryID");
                this._CategoryID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("CategoryID");
                this.OnCategoryIDChanged();
            }
        }
        private long _CategoryID;
        partial void OnCategoryIDChanging(long value);
        partial void OnCategoryIDChanged();
        /// <summary>
        /// There are no comments for Property CategoryName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string CategoryName
        {
            get
            {
                return this._CategoryName;
            }
            set
            {
                this.OnCategoryNameChanging(value);
                this.ReportPropertyChanging("CategoryName");
                this._CategoryName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("CategoryName");
                this.OnCategoryNameChanged();
            }
        }
        private string _CategoryName;
        partial void OnCategoryNameChanging(string value);
        partial void OnCategoryNameChanged();
        /// <summary>
        /// There are no comments for Property Description in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Description
        {
            get
            {
                return this._Description;
            }
            set
            {
                this.OnDescriptionChanging(value);
                this.ReportPropertyChanging("Description");
                this._Description = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Description");
                this.OnDescriptionChanged();
            }
        }
        private string _Description;
        partial void OnDescriptionChanging(string value);
        partial void OnDescriptionChanged();
        /// <summary>
        /// There are no comments for Property Picture in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public byte[] Picture
        {
            get
            {
                return global::System.Data.Objects.DataClasses.StructuralObject.GetValidValue(this._Picture);
            }
            set
            {
                this.OnPictureChanging(value);
                this.ReportPropertyChanging("Picture");
                this._Picture = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Picture");
                this.OnPictureChanged();
            }
        }
        private byte[] _Picture;
        partial void OnPictureChanging(byte[] value);
        partial void OnPictureChanged();
        /// <summary>
        /// There are no comments for Products in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Products_CategoryID_CategoryID", "Products")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityCollection<Products> Products
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<Products>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Products");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<Products>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Products", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.Customers in the schema.
    /// </summary>
    /// <KeyProperties>
    /// CustomerID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Customers")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class Customers : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new Customers object.
        /// </summary>
        /// <param name="customerID">Initial value of CustomerID.</param>
        /// <param name="companyName">Initial value of CompanyName.</param>
        public static Customers CreateCustomers(string customerID, string companyName)
        {
            Customers customers = new Customers();
            customers.CustomerID = customerID;
            customers.CompanyName = companyName;
            return customers;
        }
        /// <summary>
        /// There are no comments for Property CustomerID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string CustomerID
        {
            get
            {
                return this._CustomerID;
            }
            set
            {
                this.OnCustomerIDChanging(value);
                this.ReportPropertyChanging("CustomerID");
                this._CustomerID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("CustomerID");
                this.OnCustomerIDChanged();
            }
        }
        private string _CustomerID;
        partial void OnCustomerIDChanging(string value);
        partial void OnCustomerIDChanged();
        /// <summary>
        /// There are no comments for Property CompanyName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string CompanyName
        {
            get
            {
                return this._CompanyName;
            }
            set
            {
                this.OnCompanyNameChanging(value);
                this.ReportPropertyChanging("CompanyName");
                this._CompanyName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("CompanyName");
                this.OnCompanyNameChanged();
            }
        }
        private string _CompanyName;
        partial void OnCompanyNameChanging(string value);
        partial void OnCompanyNameChanged();
        /// <summary>
        /// There are no comments for Property ContactName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ContactName
        {
            get
            {
                return this._ContactName;
            }
            set
            {
                this.OnContactNameChanging(value);
                this.ReportPropertyChanging("ContactName");
                this._ContactName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ContactName");
                this.OnContactNameChanged();
            }
        }
        private string _ContactName;
        partial void OnContactNameChanging(string value);
        partial void OnContactNameChanged();
        /// <summary>
        /// There are no comments for Property ContactTitle in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ContactTitle
        {
            get
            {
                return this._ContactTitle;
            }
            set
            {
                this.OnContactTitleChanging(value);
                this.ReportPropertyChanging("ContactTitle");
                this._ContactTitle = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ContactTitle");
                this.OnContactTitleChanged();
            }
        }
        private string _ContactTitle;
        partial void OnContactTitleChanging(string value);
        partial void OnContactTitleChanged();
        /// <summary>
        /// There are no comments for Property Address in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Address
        {
            get
            {
                return this._Address;
            }
            set
            {
                this.OnAddressChanging(value);
                this.ReportPropertyChanging("Address");
                this._Address = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Address");
                this.OnAddressChanged();
            }
        }
        private string _Address;
        partial void OnAddressChanging(string value);
        partial void OnAddressChanged();
        /// <summary>
        /// There are no comments for Property City in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string City
        {
            get
            {
                return this._City;
            }
            set
            {
                this.OnCityChanging(value);
                this.ReportPropertyChanging("City");
                this._City = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("City");
                this.OnCityChanged();
            }
        }
        private string _City;
        partial void OnCityChanging(string value);
        partial void OnCityChanged();
        /// <summary>
        /// There are no comments for Property Region in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Region
        {
            get
            {
                return this._Region;
            }
            set
            {
                this.OnRegionChanging(value);
                this.ReportPropertyChanging("Region");
                this._Region = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Region");
                this.OnRegionChanged();
            }
        }
        private string _Region;
        partial void OnRegionChanging(string value);
        partial void OnRegionChanged();
        /// <summary>
        /// There are no comments for Property PostalCode in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string PostalCode
        {
            get
            {
                return this._PostalCode;
            }
            set
            {
                this.OnPostalCodeChanging(value);
                this.ReportPropertyChanging("PostalCode");
                this._PostalCode = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("PostalCode");
                this.OnPostalCodeChanged();
            }
        }
        private string _PostalCode;
        partial void OnPostalCodeChanging(string value);
        partial void OnPostalCodeChanged();
        /// <summary>
        /// There are no comments for Property Country in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Country
        {
            get
            {
                return this._Country;
            }
            set
            {
                this.OnCountryChanging(value);
                this.ReportPropertyChanging("Country");
                this._Country = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Country");
                this.OnCountryChanged();
            }
        }
        private string _Country;
        partial void OnCountryChanging(string value);
        partial void OnCountryChanged();
        /// <summary>
        /// There are no comments for Property Phone in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Phone
        {
            get
            {
                return this._Phone;
            }
            set
            {
                this.OnPhoneChanging(value);
                this.ReportPropertyChanging("Phone");
                this._Phone = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Phone");
                this.OnPhoneChanged();
            }
        }
        private string _Phone;
        partial void OnPhoneChanging(string value);
        partial void OnPhoneChanged();
        /// <summary>
        /// There are no comments for Property Fax in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Fax
        {
            get
            {
                return this._Fax;
            }
            set
            {
                this.OnFaxChanging(value);
                this.ReportPropertyChanging("Fax");
                this._Fax = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Fax");
                this.OnFaxChanged();
            }
        }
        private string _Fax;
        partial void OnFaxChanging(string value);
        partial void OnFaxChanged();
        /// <summary>
        /// There are no comments for Orders in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Orders_CustomerID_CustomerID", "Orders")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityCollection<Orders> Orders
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<Orders>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Orders");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<Orders>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Orders", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.Employees in the schema.
    /// </summary>
    /// <KeyProperties>
    /// EmployeeID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Employees")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class Employees : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new Employees object.
        /// </summary>
        /// <param name="employeeID">Initial value of EmployeeID.</param>
        /// <param name="lastName">Initial value of LastName.</param>
        /// <param name="firstName">Initial value of FirstName.</param>
        public static Employees CreateEmployees(long employeeID, string lastName, string firstName)
        {
            Employees employees = new Employees();
            employees.EmployeeID = employeeID;
            employees.LastName = lastName;
            employees.FirstName = firstName;
            return employees;
        }
        /// <summary>
        /// There are no comments for Property EmployeeID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long EmployeeID
        {
            get
            {
                return this._EmployeeID;
            }
            set
            {
                this.OnEmployeeIDChanging(value);
                this.ReportPropertyChanging("EmployeeID");
                this._EmployeeID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("EmployeeID");
                this.OnEmployeeIDChanged();
            }
        }
        private long _EmployeeID;
        partial void OnEmployeeIDChanging(long value);
        partial void OnEmployeeIDChanged();
        /// <summary>
        /// There are no comments for Property LastName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string LastName
        {
            get
            {
                return this._LastName;
            }
            set
            {
                this.OnLastNameChanging(value);
                this.ReportPropertyChanging("LastName");
                this._LastName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("LastName");
                this.OnLastNameChanged();
            }
        }
        private string _LastName;
        partial void OnLastNameChanging(string value);
        partial void OnLastNameChanged();
        /// <summary>
        /// There are no comments for Property FirstName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string FirstName
        {
            get
            {
                return this._FirstName;
            }
            set
            {
                this.OnFirstNameChanging(value);
                this.ReportPropertyChanging("FirstName");
                this._FirstName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("FirstName");
                this.OnFirstNameChanged();
            }
        }
        private string _FirstName;
        partial void OnFirstNameChanging(string value);
        partial void OnFirstNameChanged();
        /// <summary>
        /// There are no comments for Property Title in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Title
        {
            get
            {
                return this._Title;
            }
            set
            {
                this.OnTitleChanging(value);
                this.ReportPropertyChanging("Title");
                this._Title = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Title");
                this.OnTitleChanged();
            }
        }
        private string _Title;
        partial void OnTitleChanging(string value);
        partial void OnTitleChanged();
        /// <summary>
        /// There are no comments for Property TitleOfCourtesy in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string TitleOfCourtesy
        {
            get
            {
                return this._TitleOfCourtesy;
            }
            set
            {
                this.OnTitleOfCourtesyChanging(value);
                this.ReportPropertyChanging("TitleOfCourtesy");
                this._TitleOfCourtesy = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("TitleOfCourtesy");
                this.OnTitleOfCourtesyChanged();
            }
        }
        private string _TitleOfCourtesy;
        partial void OnTitleOfCourtesyChanging(string value);
        partial void OnTitleOfCourtesyChanged();
        /// <summary>
        /// There are no comments for Property BirthDate in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<global::System.DateTime> BirthDate
        {
            get
            {
                return this._BirthDate;
            }
            set
            {
                this.OnBirthDateChanging(value);
                this.ReportPropertyChanging("BirthDate");
                this._BirthDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("BirthDate");
                this.OnBirthDateChanged();
            }
        }
        private global::System.Nullable<global::System.DateTime> _BirthDate;
        partial void OnBirthDateChanging(global::System.Nullable<global::System.DateTime> value);
        partial void OnBirthDateChanged();
        /// <summary>
        /// There are no comments for Property HireDate in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<global::System.DateTime> HireDate
        {
            get
            {
                return this._HireDate;
            }
            set
            {
                this.OnHireDateChanging(value);
                this.ReportPropertyChanging("HireDate");
                this._HireDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("HireDate");
                this.OnHireDateChanged();
            }
        }
        private global::System.Nullable<global::System.DateTime> _HireDate;
        partial void OnHireDateChanging(global::System.Nullable<global::System.DateTime> value);
        partial void OnHireDateChanged();
        /// <summary>
        /// There are no comments for Property Address in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Address
        {
            get
            {
                return this._Address;
            }
            set
            {
                this.OnAddressChanging(value);
                this.ReportPropertyChanging("Address");
                this._Address = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Address");
                this.OnAddressChanged();
            }
        }
        private string _Address;
        partial void OnAddressChanging(string value);
        partial void OnAddressChanged();
        /// <summary>
        /// There are no comments for Property City in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string City
        {
            get
            {
                return this._City;
            }
            set
            {
                this.OnCityChanging(value);
                this.ReportPropertyChanging("City");
                this._City = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("City");
                this.OnCityChanged();
            }
        }
        private string _City;
        partial void OnCityChanging(string value);
        partial void OnCityChanged();
        /// <summary>
        /// There are no comments for Property Region in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Region
        {
            get
            {
                return this._Region;
            }
            set
            {
                this.OnRegionChanging(value);
                this.ReportPropertyChanging("Region");
                this._Region = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Region");
                this.OnRegionChanged();
            }
        }
        private string _Region;
        partial void OnRegionChanging(string value);
        partial void OnRegionChanged();
        /// <summary>
        /// There are no comments for Property PostalCode in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string PostalCode
        {
            get
            {
                return this._PostalCode;
            }
            set
            {
                this.OnPostalCodeChanging(value);
                this.ReportPropertyChanging("PostalCode");
                this._PostalCode = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("PostalCode");
                this.OnPostalCodeChanged();
            }
        }
        private string _PostalCode;
        partial void OnPostalCodeChanging(string value);
        partial void OnPostalCodeChanged();
        /// <summary>
        /// There are no comments for Property Country in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Country
        {
            get
            {
                return this._Country;
            }
            set
            {
                this.OnCountryChanging(value);
                this.ReportPropertyChanging("Country");
                this._Country = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Country");
                this.OnCountryChanged();
            }
        }
        private string _Country;
        partial void OnCountryChanging(string value);
        partial void OnCountryChanged();
        /// <summary>
        /// There are no comments for Property HomePhone in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string HomePhone
        {
            get
            {
                return this._HomePhone;
            }
            set
            {
                this.OnHomePhoneChanging(value);
                this.ReportPropertyChanging("HomePhone");
                this._HomePhone = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("HomePhone");
                this.OnHomePhoneChanged();
            }
        }
        private string _HomePhone;
        partial void OnHomePhoneChanging(string value);
        partial void OnHomePhoneChanged();
        /// <summary>
        /// There are no comments for Property Extension in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Extension
        {
            get
            {
                return this._Extension;
            }
            set
            {
                this.OnExtensionChanging(value);
                this.ReportPropertyChanging("Extension");
                this._Extension = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Extension");
                this.OnExtensionChanged();
            }
        }
        private string _Extension;
        partial void OnExtensionChanging(string value);
        partial void OnExtensionChanged();
        /// <summary>
        /// There are no comments for Property Photo in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public byte[] Photo
        {
            get
            {
                return global::System.Data.Objects.DataClasses.StructuralObject.GetValidValue(this._Photo);
            }
            set
            {
                this.OnPhotoChanging(value);
                this.ReportPropertyChanging("Photo");
                this._Photo = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Photo");
                this.OnPhotoChanged();
            }
        }
        private byte[] _Photo;
        partial void OnPhotoChanging(byte[] value);
        partial void OnPhotoChanged();
        /// <summary>
        /// There are no comments for Property Notes in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Notes
        {
            get
            {
                return this._Notes;
            }
            set
            {
                this.OnNotesChanging(value);
                this.ReportPropertyChanging("Notes");
                this._Notes = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Notes");
                this.OnNotesChanged();
            }
        }
        private string _Notes;
        partial void OnNotesChanging(string value);
        partial void OnNotesChanged();
        /// <summary>
        /// There are no comments for Property PhotoPath in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string PhotoPath
        {
            get
            {
                return this._PhotoPath;
            }
            set
            {
                this.OnPhotoPathChanging(value);
                this.ReportPropertyChanging("PhotoPath");
                this._PhotoPath = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("PhotoPath");
                this.OnPhotoPathChanged();
            }
        }
        private string _PhotoPath;
        partial void OnPhotoPathChanging(string value);
        partial void OnPhotoPathChanged();
        /// <summary>
        /// There are no comments for Territories in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "EmployeesTerritories", "Territories")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityCollection<Territories> Territories
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<Territories>("northwindEFModel.EmployeesTerritories", "Territories");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<Territories>("northwindEFModel.EmployeesTerritories", "Territories", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.InternationalOrders in the schema.
    /// </summary>
    /// <KeyProperties>
    /// OrderID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="InternationalOrders")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class InternationalOrders : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new InternationalOrders object.
        /// </summary>
        /// <param name="orderID">Initial value of OrderID.</param>
        /// <param name="customsDescription">Initial value of CustomsDescription.</param>
        /// <param name="exciseTax">Initial value of ExciseTax.</param>
        public static InternationalOrders CreateInternationalOrders(long orderID, string customsDescription, decimal exciseTax)
        {
            InternationalOrders internationalOrders = new InternationalOrders();
            internationalOrders.OrderID = orderID;
            internationalOrders.CustomsDescription = customsDescription;
            internationalOrders.ExciseTax = exciseTax;
            return internationalOrders;
        }
        /// <summary>
        /// There are no comments for Property OrderID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long OrderID
        {
            get
            {
                return this._OrderID;
            }
            set
            {
                this.OnOrderIDChanging(value);
                this.ReportPropertyChanging("OrderID");
                this._OrderID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("OrderID");
                this.OnOrderIDChanged();
            }
        }
        private long _OrderID;
        partial void OnOrderIDChanging(long value);
        partial void OnOrderIDChanged();
        /// <summary>
        /// There are no comments for Property CustomsDescription in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string CustomsDescription
        {
            get
            {
                return this._CustomsDescription;
            }
            set
            {
                this.OnCustomsDescriptionChanging(value);
                this.ReportPropertyChanging("CustomsDescription");
                this._CustomsDescription = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("CustomsDescription");
                this.OnCustomsDescriptionChanged();
            }
        }
        private string _CustomsDescription;
        partial void OnCustomsDescriptionChanging(string value);
        partial void OnCustomsDescriptionChanged();
        /// <summary>
        /// There are no comments for Property ExciseTax in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public decimal ExciseTax
        {
            get
            {
                return this._ExciseTax;
            }
            set
            {
                this.OnExciseTaxChanging(value);
                this.ReportPropertyChanging("ExciseTax");
                this._ExciseTax = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("ExciseTax");
                this.OnExciseTaxChanged();
            }
        }
        private decimal _ExciseTax;
        partial void OnExciseTaxChanging(decimal value);
        partial void OnExciseTaxChanged();
        /// <summary>
        /// There are no comments for Orders in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_InternationalOrders_OrderID_OrderID", "Orders")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public Orders Orders
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "Orders").Value;
            }
            set
            {
                ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "Orders").Value = value;
            }
        }
        /// <summary>
        /// There are no comments for Orders in the schema.
        /// </summary>
        [global::System.ComponentModel.BrowsableAttribute(false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityReference<Orders> OrdersReference
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "Orders");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<Orders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "Orders", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.OrderDetails in the schema.
    /// </summary>
    /// <KeyProperties>
    /// OrderID
    /// ProductID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="OrderDetails")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class OrderDetails : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new OrderDetails object.
        /// </summary>
        /// <param name="orderID">Initial value of OrderID.</param>
        /// <param name="productID">Initial value of ProductID.</param>
        /// <param name="unitPrice">Initial value of UnitPrice.</param>
        /// <param name="quantity">Initial value of Quantity.</param>
        /// <param name="discount">Initial value of Discount.</param>
        public static OrderDetails CreateOrderDetails(long orderID, long productID, decimal unitPrice, short quantity, float discount)
        {
            OrderDetails orderDetails = new OrderDetails();
            orderDetails.OrderID = orderID;
            orderDetails.ProductID = productID;
            orderDetails.UnitPrice = unitPrice;
            orderDetails.Quantity = quantity;
            orderDetails.Discount = discount;
            return orderDetails;
        }
        /// <summary>
        /// There are no comments for Property OrderID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long OrderID
        {
            get
            {
                return this._OrderID;
            }
            set
            {
                this.OnOrderIDChanging(value);
                this.ReportPropertyChanging("OrderID");
                this._OrderID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("OrderID");
                this.OnOrderIDChanged();
            }
        }
        private long _OrderID;
        partial void OnOrderIDChanging(long value);
        partial void OnOrderIDChanged();
        /// <summary>
        /// There are no comments for Property ProductID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long ProductID
        {
            get
            {
                return this._ProductID;
            }
            set
            {
                this.OnProductIDChanging(value);
                this.ReportPropertyChanging("ProductID");
                this._ProductID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("ProductID");
                this.OnProductIDChanged();
            }
        }
        private long _ProductID;
        partial void OnProductIDChanging(long value);
        partial void OnProductIDChanged();
        /// <summary>
        /// There are no comments for Property UnitPrice in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public decimal UnitPrice
        {
            get
            {
                return this._UnitPrice;
            }
            set
            {
                this.OnUnitPriceChanging(value);
                this.ReportPropertyChanging("UnitPrice");
                this._UnitPrice = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("UnitPrice");
                this.OnUnitPriceChanged();
            }
        }
        private decimal _UnitPrice;
        partial void OnUnitPriceChanging(decimal value);
        partial void OnUnitPriceChanged();
        /// <summary>
        /// There are no comments for Property Quantity in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public short Quantity
        {
            get
            {
                return this._Quantity;
            }
            set
            {
                this.OnQuantityChanging(value);
                this.ReportPropertyChanging("Quantity");
                this._Quantity = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("Quantity");
                this.OnQuantityChanged();
            }
        }
        private short _Quantity;
        partial void OnQuantityChanging(short value);
        partial void OnQuantityChanged();
        /// <summary>
        /// There are no comments for Property Discount in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public float Discount
        {
            get
            {
                return this._Discount;
            }
            set
            {
                this.OnDiscountChanging(value);
                this.ReportPropertyChanging("Discount");
                this._Discount = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("Discount");
                this.OnDiscountChanged();
            }
        }
        private float _Discount;
        partial void OnDiscountChanging(float value);
        partial void OnDiscountChanged();
        /// <summary>
        /// There are no comments for Orders in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_OrderDetails_OrderID_OrderID", "Orders")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public Orders Orders
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "Orders").Value;
            }
            set
            {
                ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "Orders").Value = value;
            }
        }
        /// <summary>
        /// There are no comments for Orders in the schema.
        /// </summary>
        [global::System.ComponentModel.BrowsableAttribute(false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityReference<Orders> OrdersReference
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "Orders");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<Orders>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "Orders", value);
                }
            }
        }
        /// <summary>
        /// There are no comments for Products in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_OrderDetails_ProductID_ProductID", "Products")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public Products Products
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Products>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "Products").Value;
            }
            set
            {
                ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Products>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "Products").Value = value;
            }
        }
        /// <summary>
        /// There are no comments for Products in the schema.
        /// </summary>
        [global::System.ComponentModel.BrowsableAttribute(false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityReference<Products> ProductsReference
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Products>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "Products");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<Products>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "Products", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.Orders in the schema.
    /// </summary>
    /// <KeyProperties>
    /// OrderID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Orders")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class Orders : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new Orders object.
        /// </summary>
        /// <param name="orderID">Initial value of OrderID.</param>
        public static Orders CreateOrders(long orderID)
        {
            Orders orders = new Orders();
            orders.OrderID = orderID;
            return orders;
        }
        /// <summary>
        /// There are no comments for Property OrderID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long OrderID
        {
            get
            {
                return this._OrderID;
            }
            set
            {
                this.OnOrderIDChanging(value);
                this.ReportPropertyChanging("OrderID");
                this._OrderID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("OrderID");
                this.OnOrderIDChanged();
            }
        }
        private long _OrderID;
        partial void OnOrderIDChanging(long value);
        partial void OnOrderIDChanged();
        /// <summary>
        /// There are no comments for Property EmployeeID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<long> EmployeeID
        {
            get
            {
                return this._EmployeeID;
            }
            set
            {
                this.OnEmployeeIDChanging(value);
                this.ReportPropertyChanging("EmployeeID");
                this._EmployeeID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("EmployeeID");
                this.OnEmployeeIDChanged();
            }
        }
        private global::System.Nullable<long> _EmployeeID;
        partial void OnEmployeeIDChanging(global::System.Nullable<long> value);
        partial void OnEmployeeIDChanged();
        /// <summary>
        /// There are no comments for Property OrderDate in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<global::System.DateTime> OrderDate
        {
            get
            {
                return this._OrderDate;
            }
            set
            {
                this.OnOrderDateChanging(value);
                this.ReportPropertyChanging("OrderDate");
                this._OrderDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("OrderDate");
                this.OnOrderDateChanged();
            }
        }
        private global::System.Nullable<global::System.DateTime> _OrderDate;
        partial void OnOrderDateChanging(global::System.Nullable<global::System.DateTime> value);
        partial void OnOrderDateChanged();
        /// <summary>
        /// There are no comments for Property RequiredDate in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<global::System.DateTime> RequiredDate
        {
            get
            {
                return this._RequiredDate;
            }
            set
            {
                this.OnRequiredDateChanging(value);
                this.ReportPropertyChanging("RequiredDate");
                this._RequiredDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("RequiredDate");
                this.OnRequiredDateChanged();
            }
        }
        private global::System.Nullable<global::System.DateTime> _RequiredDate;
        partial void OnRequiredDateChanging(global::System.Nullable<global::System.DateTime> value);
        partial void OnRequiredDateChanged();
        /// <summary>
        /// There are no comments for Property ShippedDate in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<global::System.DateTime> ShippedDate
        {
            get
            {
                return this._ShippedDate;
            }
            set
            {
                this.OnShippedDateChanging(value);
                this.ReportPropertyChanging("ShippedDate");
                this._ShippedDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("ShippedDate");
                this.OnShippedDateChanged();
            }
        }
        private global::System.Nullable<global::System.DateTime> _ShippedDate;
        partial void OnShippedDateChanging(global::System.Nullable<global::System.DateTime> value);
        partial void OnShippedDateChanged();
        /// <summary>
        /// There are no comments for Property Freight in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<decimal> Freight
        {
            get
            {
                return this._Freight;
            }
            set
            {
                this.OnFreightChanging(value);
                this.ReportPropertyChanging("Freight");
                this._Freight = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("Freight");
                this.OnFreightChanged();
            }
        }
        private global::System.Nullable<decimal> _Freight;
        partial void OnFreightChanging(global::System.Nullable<decimal> value);
        partial void OnFreightChanged();
        /// <summary>
        /// There are no comments for Property ShipName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ShipName
        {
            get
            {
                return this._ShipName;
            }
            set
            {
                this.OnShipNameChanging(value);
                this.ReportPropertyChanging("ShipName");
                this._ShipName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ShipName");
                this.OnShipNameChanged();
            }
        }
        private string _ShipName;
        partial void OnShipNameChanging(string value);
        partial void OnShipNameChanged();
        /// <summary>
        /// There are no comments for Property ShipAddress in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ShipAddress
        {
            get
            {
                return this._ShipAddress;
            }
            set
            {
                this.OnShipAddressChanging(value);
                this.ReportPropertyChanging("ShipAddress");
                this._ShipAddress = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ShipAddress");
                this.OnShipAddressChanged();
            }
        }
        private string _ShipAddress;
        partial void OnShipAddressChanging(string value);
        partial void OnShipAddressChanged();
        /// <summary>
        /// There are no comments for Property ShipCity in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ShipCity
        {
            get
            {
                return this._ShipCity;
            }
            set
            {
                this.OnShipCityChanging(value);
                this.ReportPropertyChanging("ShipCity");
                this._ShipCity = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ShipCity");
                this.OnShipCityChanged();
            }
        }
        private string _ShipCity;
        partial void OnShipCityChanging(string value);
        partial void OnShipCityChanged();
        /// <summary>
        /// There are no comments for Property ShipRegion in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ShipRegion
        {
            get
            {
                return this._ShipRegion;
            }
            set
            {
                this.OnShipRegionChanging(value);
                this.ReportPropertyChanging("ShipRegion");
                this._ShipRegion = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ShipRegion");
                this.OnShipRegionChanged();
            }
        }
        private string _ShipRegion;
        partial void OnShipRegionChanging(string value);
        partial void OnShipRegionChanged();
        /// <summary>
        /// There are no comments for Property ShipPostalCode in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ShipPostalCode
        {
            get
            {
                return this._ShipPostalCode;
            }
            set
            {
                this.OnShipPostalCodeChanging(value);
                this.ReportPropertyChanging("ShipPostalCode");
                this._ShipPostalCode = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ShipPostalCode");
                this.OnShipPostalCodeChanged();
            }
        }
        private string _ShipPostalCode;
        partial void OnShipPostalCodeChanging(string value);
        partial void OnShipPostalCodeChanged();
        /// <summary>
        /// There are no comments for Property ShipCountry in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ShipCountry
        {
            get
            {
                return this._ShipCountry;
            }
            set
            {
                this.OnShipCountryChanging(value);
                this.ReportPropertyChanging("ShipCountry");
                this._ShipCountry = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ShipCountry");
                this.OnShipCountryChanged();
            }
        }
        private string _ShipCountry;
        partial void OnShipCountryChanging(string value);
        partial void OnShipCountryChanged();
        /// <summary>
        /// There are no comments for Customers in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Orders_CustomerID_CustomerID", "Customers")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public Customers Customers
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Customers>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Customers").Value;
            }
            set
            {
                ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Customers>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Customers").Value = value;
            }
        }
        /// <summary>
        /// There are no comments for Customers in the schema.
        /// </summary>
        [global::System.ComponentModel.BrowsableAttribute(false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityReference<Customers> CustomersReference
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Customers>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Customers");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<Customers>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Customers", value);
                }
            }
        }
        /// <summary>
        /// There are no comments for InternationalOrders in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_InternationalOrders_OrderID_OrderID", "InternationalOrders")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public InternationalOrders InternationalOrders
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<InternationalOrders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "InternationalOrders").Value;
            }
            set
            {
                ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<InternationalOrders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "InternationalOrders").Value = value;
            }
        }
        /// <summary>
        /// There are no comments for InternationalOrders in the schema.
        /// </summary>
        [global::System.ComponentModel.BrowsableAttribute(false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityReference<InternationalOrders> InternationalOrdersReference
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<InternationalOrders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "InternationalOrders");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<InternationalOrders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "InternationalOrders", value);
                }
            }
        }
        /// <summary>
        /// There are no comments for OrderDetails in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_OrderDetails_OrderID_OrderID", "OrderDetails")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityCollection<OrderDetails> OrderDetails
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<OrderDetails>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "OrderDetails");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<OrderDetails>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "OrderDetails", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.PreviousEmployees in the schema.
    /// </summary>
    /// <KeyProperties>
    /// EmployeeID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="PreviousEmployees")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class PreviousEmployees : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new PreviousEmployees object.
        /// </summary>
        /// <param name="employeeID">Initial value of EmployeeID.</param>
        /// <param name="lastName">Initial value of LastName.</param>
        /// <param name="firstName">Initial value of FirstName.</param>
        public static PreviousEmployees CreatePreviousEmployees(long employeeID, string lastName, string firstName)
        {
            PreviousEmployees previousEmployees = new PreviousEmployees();
            previousEmployees.EmployeeID = employeeID;
            previousEmployees.LastName = lastName;
            previousEmployees.FirstName = firstName;
            return previousEmployees;
        }
        /// <summary>
        /// There are no comments for Property EmployeeID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long EmployeeID
        {
            get
            {
                return this._EmployeeID;
            }
            set
            {
                this.OnEmployeeIDChanging(value);
                this.ReportPropertyChanging("EmployeeID");
                this._EmployeeID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("EmployeeID");
                this.OnEmployeeIDChanged();
            }
        }
        private long _EmployeeID;
        partial void OnEmployeeIDChanging(long value);
        partial void OnEmployeeIDChanged();
        /// <summary>
        /// There are no comments for Property LastName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string LastName
        {
            get
            {
                return this._LastName;
            }
            set
            {
                this.OnLastNameChanging(value);
                this.ReportPropertyChanging("LastName");
                this._LastName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("LastName");
                this.OnLastNameChanged();
            }
        }
        private string _LastName;
        partial void OnLastNameChanging(string value);
        partial void OnLastNameChanged();
        /// <summary>
        /// There are no comments for Property FirstName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string FirstName
        {
            get
            {
                return this._FirstName;
            }
            set
            {
                this.OnFirstNameChanging(value);
                this.ReportPropertyChanging("FirstName");
                this._FirstName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("FirstName");
                this.OnFirstNameChanged();
            }
        }
        private string _FirstName;
        partial void OnFirstNameChanging(string value);
        partial void OnFirstNameChanged();
        /// <summary>
        /// There are no comments for Property Title in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Title
        {
            get
            {
                return this._Title;
            }
            set
            {
                this.OnTitleChanging(value);
                this.ReportPropertyChanging("Title");
                this._Title = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Title");
                this.OnTitleChanged();
            }
        }
        private string _Title;
        partial void OnTitleChanging(string value);
        partial void OnTitleChanged();
        /// <summary>
        /// There are no comments for Property TitleOfCourtesy in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string TitleOfCourtesy
        {
            get
            {
                return this._TitleOfCourtesy;
            }
            set
            {
                this.OnTitleOfCourtesyChanging(value);
                this.ReportPropertyChanging("TitleOfCourtesy");
                this._TitleOfCourtesy = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("TitleOfCourtesy");
                this.OnTitleOfCourtesyChanged();
            }
        }
        private string _TitleOfCourtesy;
        partial void OnTitleOfCourtesyChanging(string value);
        partial void OnTitleOfCourtesyChanged();
        /// <summary>
        /// There are no comments for Property BirthDate in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<global::System.DateTime> BirthDate
        {
            get
            {
                return this._BirthDate;
            }
            set
            {
                this.OnBirthDateChanging(value);
                this.ReportPropertyChanging("BirthDate");
                this._BirthDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("BirthDate");
                this.OnBirthDateChanged();
            }
        }
        private global::System.Nullable<global::System.DateTime> _BirthDate;
        partial void OnBirthDateChanging(global::System.Nullable<global::System.DateTime> value);
        partial void OnBirthDateChanged();
        /// <summary>
        /// There are no comments for Property HireDate in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<global::System.DateTime> HireDate
        {
            get
            {
                return this._HireDate;
            }
            set
            {
                this.OnHireDateChanging(value);
                this.ReportPropertyChanging("HireDate");
                this._HireDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("HireDate");
                this.OnHireDateChanged();
            }
        }
        private global::System.Nullable<global::System.DateTime> _HireDate;
        partial void OnHireDateChanging(global::System.Nullable<global::System.DateTime> value);
        partial void OnHireDateChanged();
        /// <summary>
        /// There are no comments for Property Address in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Address
        {
            get
            {
                return this._Address;
            }
            set
            {
                this.OnAddressChanging(value);
                this.ReportPropertyChanging("Address");
                this._Address = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Address");
                this.OnAddressChanged();
            }
        }
        private string _Address;
        partial void OnAddressChanging(string value);
        partial void OnAddressChanged();
        /// <summary>
        /// There are no comments for Property City in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string City
        {
            get
            {
                return this._City;
            }
            set
            {
                this.OnCityChanging(value);
                this.ReportPropertyChanging("City");
                this._City = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("City");
                this.OnCityChanged();
            }
        }
        private string _City;
        partial void OnCityChanging(string value);
        partial void OnCityChanged();
        /// <summary>
        /// There are no comments for Property Region in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Region
        {
            get
            {
                return this._Region;
            }
            set
            {
                this.OnRegionChanging(value);
                this.ReportPropertyChanging("Region");
                this._Region = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Region");
                this.OnRegionChanged();
            }
        }
        private string _Region;
        partial void OnRegionChanging(string value);
        partial void OnRegionChanged();
        /// <summary>
        /// There are no comments for Property PostalCode in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string PostalCode
        {
            get
            {
                return this._PostalCode;
            }
            set
            {
                this.OnPostalCodeChanging(value);
                this.ReportPropertyChanging("PostalCode");
                this._PostalCode = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("PostalCode");
                this.OnPostalCodeChanged();
            }
        }
        private string _PostalCode;
        partial void OnPostalCodeChanging(string value);
        partial void OnPostalCodeChanged();
        /// <summary>
        /// There are no comments for Property Country in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Country
        {
            get
            {
                return this._Country;
            }
            set
            {
                this.OnCountryChanging(value);
                this.ReportPropertyChanging("Country");
                this._Country = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Country");
                this.OnCountryChanged();
            }
        }
        private string _Country;
        partial void OnCountryChanging(string value);
        partial void OnCountryChanged();
        /// <summary>
        /// There are no comments for Property HomePhone in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string HomePhone
        {
            get
            {
                return this._HomePhone;
            }
            set
            {
                this.OnHomePhoneChanging(value);
                this.ReportPropertyChanging("HomePhone");
                this._HomePhone = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("HomePhone");
                this.OnHomePhoneChanged();
            }
        }
        private string _HomePhone;
        partial void OnHomePhoneChanging(string value);
        partial void OnHomePhoneChanged();
        /// <summary>
        /// There are no comments for Property Extension in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Extension
        {
            get
            {
                return this._Extension;
            }
            set
            {
                this.OnExtensionChanging(value);
                this.ReportPropertyChanging("Extension");
                this._Extension = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Extension");
                this.OnExtensionChanged();
            }
        }
        private string _Extension;
        partial void OnExtensionChanging(string value);
        partial void OnExtensionChanged();
        /// <summary>
        /// There are no comments for Property Photo in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public byte[] Photo
        {
            get
            {
                return global::System.Data.Objects.DataClasses.StructuralObject.GetValidValue(this._Photo);
            }
            set
            {
                this.OnPhotoChanging(value);
                this.ReportPropertyChanging("Photo");
                this._Photo = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Photo");
                this.OnPhotoChanged();
            }
        }
        private byte[] _Photo;
        partial void OnPhotoChanging(byte[] value);
        partial void OnPhotoChanged();
        /// <summary>
        /// There are no comments for Property Notes in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Notes
        {
            get
            {
                return this._Notes;
            }
            set
            {
                this.OnNotesChanging(value);
                this.ReportPropertyChanging("Notes");
                this._Notes = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Notes");
                this.OnNotesChanged();
            }
        }
        private string _Notes;
        partial void OnNotesChanging(string value);
        partial void OnNotesChanged();
        /// <summary>
        /// There are no comments for Property PhotoPath in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string PhotoPath
        {
            get
            {
                return this._PhotoPath;
            }
            set
            {
                this.OnPhotoPathChanging(value);
                this.ReportPropertyChanging("PhotoPath");
                this._PhotoPath = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("PhotoPath");
                this.OnPhotoPathChanged();
            }
        }
        private string _PhotoPath;
        partial void OnPhotoPathChanging(string value);
        partial void OnPhotoPathChanged();
    }
    /// <summary>
    /// There are no comments for northwindEFModel.Products in the schema.
    /// </summary>
    /// <KeyProperties>
    /// ProductID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Products")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class Products : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new Products object.
        /// </summary>
        /// <param name="productID">Initial value of ProductID.</param>
        /// <param name="productName">Initial value of ProductName.</param>
        /// <param name="discontinued">Initial value of Discontinued.</param>
        public static Products CreateProducts(long productID, string productName, bool discontinued)
        {
            Products products = new Products();
            products.ProductID = productID;
            products.ProductName = productName;
            products.Discontinued = discontinued;
            return products;
        }
        /// <summary>
        /// There are no comments for Property ProductID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long ProductID
        {
            get
            {
                return this._ProductID;
            }
            set
            {
                this.OnProductIDChanging(value);
                this.ReportPropertyChanging("ProductID");
                this._ProductID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("ProductID");
                this.OnProductIDChanged();
            }
        }
        private long _ProductID;
        partial void OnProductIDChanging(long value);
        partial void OnProductIDChanged();
        /// <summary>
        /// There are no comments for Property ProductName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ProductName
        {
            get
            {
                return this._ProductName;
            }
            set
            {
                this.OnProductNameChanging(value);
                this.ReportPropertyChanging("ProductName");
                this._ProductName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("ProductName");
                this.OnProductNameChanged();
            }
        }
        private string _ProductName;
        partial void OnProductNameChanging(string value);
        partial void OnProductNameChanged();
        /// <summary>
        /// There are no comments for Property QuantityPerUnit in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string QuantityPerUnit
        {
            get
            {
                return this._QuantityPerUnit;
            }
            set
            {
                this.OnQuantityPerUnitChanging(value);
                this.ReportPropertyChanging("QuantityPerUnit");
                this._QuantityPerUnit = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("QuantityPerUnit");
                this.OnQuantityPerUnitChanged();
            }
        }
        private string _QuantityPerUnit;
        partial void OnQuantityPerUnitChanging(string value);
        partial void OnQuantityPerUnitChanged();
        /// <summary>
        /// There are no comments for Property UnitPrice in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<decimal> UnitPrice
        {
            get
            {
                return this._UnitPrice;
            }
            set
            {
                this.OnUnitPriceChanging(value);
                this.ReportPropertyChanging("UnitPrice");
                this._UnitPrice = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("UnitPrice");
                this.OnUnitPriceChanged();
            }
        }
        private global::System.Nullable<decimal> _UnitPrice;
        partial void OnUnitPriceChanging(global::System.Nullable<decimal> value);
        partial void OnUnitPriceChanged();
        /// <summary>
        /// There are no comments for Property UnitsInStock in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<short> UnitsInStock
        {
            get
            {
                return this._UnitsInStock;
            }
            set
            {
                this.OnUnitsInStockChanging(value);
                this.ReportPropertyChanging("UnitsInStock");
                this._UnitsInStock = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("UnitsInStock");
                this.OnUnitsInStockChanged();
            }
        }
        private global::System.Nullable<short> _UnitsInStock;
        partial void OnUnitsInStockChanging(global::System.Nullable<short> value);
        partial void OnUnitsInStockChanged();
        /// <summary>
        /// There are no comments for Property UnitsOnOrder in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<short> UnitsOnOrder
        {
            get
            {
                return this._UnitsOnOrder;
            }
            set
            {
                this.OnUnitsOnOrderChanging(value);
                this.ReportPropertyChanging("UnitsOnOrder");
                this._UnitsOnOrder = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("UnitsOnOrder");
                this.OnUnitsOnOrderChanged();
            }
        }
        private global::System.Nullable<short> _UnitsOnOrder;
        partial void OnUnitsOnOrderChanging(global::System.Nullable<short> value);
        partial void OnUnitsOnOrderChanged();
        /// <summary>
        /// There are no comments for Property ReorderLevel in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<short> ReorderLevel
        {
            get
            {
                return this._ReorderLevel;
            }
            set
            {
                this.OnReorderLevelChanging(value);
                this.ReportPropertyChanging("ReorderLevel");
                this._ReorderLevel = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("ReorderLevel");
                this.OnReorderLevelChanged();
            }
        }
        private global::System.Nullable<short> _ReorderLevel;
        partial void OnReorderLevelChanging(global::System.Nullable<short> value);
        partial void OnReorderLevelChanged();
        /// <summary>
        /// There are no comments for Property Discontinued in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public bool Discontinued
        {
            get
            {
                return this._Discontinued;
            }
            set
            {
                this.OnDiscontinuedChanging(value);
                this.ReportPropertyChanging("Discontinued");
                this._Discontinued = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("Discontinued");
                this.OnDiscontinuedChanged();
            }
        }
        private bool _Discontinued;
        partial void OnDiscontinuedChanging(bool value);
        partial void OnDiscontinuedChanged();
        /// <summary>
        /// There are no comments for Property DiscontinuedDate in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Nullable<global::System.DateTime> DiscontinuedDate
        {
            get
            {
                return this._DiscontinuedDate;
            }
            set
            {
                this.OnDiscontinuedDateChanging(value);
                this.ReportPropertyChanging("DiscontinuedDate");
                this._DiscontinuedDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("DiscontinuedDate");
                this.OnDiscontinuedDateChanged();
            }
        }
        private global::System.Nullable<global::System.DateTime> _DiscontinuedDate;
        partial void OnDiscontinuedDateChanging(global::System.Nullable<global::System.DateTime> value);
        partial void OnDiscontinuedDateChanged();
        /// <summary>
        /// There are no comments for Categories in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Products_CategoryID_CategoryID", "Categories")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public Categories Categories
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Categories>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Categories").Value;
            }
            set
            {
                ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Categories>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Categories").Value = value;
            }
        }
        /// <summary>
        /// There are no comments for Categories in the schema.
        /// </summary>
        [global::System.ComponentModel.BrowsableAttribute(false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityReference<Categories> CategoriesReference
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Categories>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Categories");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<Categories>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Categories", value);
                }
            }
        }
        /// <summary>
        /// There are no comments for OrderDetails in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_OrderDetails_ProductID_ProductID", "OrderDetails")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityCollection<OrderDetails> OrderDetails
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<OrderDetails>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "OrderDetails");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<OrderDetails>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "OrderDetails", value);
                }
            }
        }
        /// <summary>
        /// There are no comments for Suppliers in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Products_SupplierID_SupplierID", "Suppliers")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public Suppliers Suppliers
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Suppliers>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Suppliers").Value;
            }
            set
            {
                ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Suppliers>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Suppliers").Value = value;
            }
        }
        /// <summary>
        /// There are no comments for Suppliers in the schema.
        /// </summary>
        [global::System.ComponentModel.BrowsableAttribute(false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityReference<Suppliers> SuppliersReference
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Suppliers>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Suppliers");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<Suppliers>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Suppliers", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.Regions in the schema.
    /// </summary>
    /// <KeyProperties>
    /// RegionID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Regions")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class Regions : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new Regions object.
        /// </summary>
        /// <param name="regionID">Initial value of RegionID.</param>
        /// <param name="regionDescription">Initial value of RegionDescription.</param>
        public static Regions CreateRegions(long regionID, string regionDescription)
        {
            Regions regions = new Regions();
            regions.RegionID = regionID;
            regions.RegionDescription = regionDescription;
            return regions;
        }
        /// <summary>
        /// There are no comments for Property RegionID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long RegionID
        {
            get
            {
                return this._RegionID;
            }
            set
            {
                this.OnRegionIDChanging(value);
                this.ReportPropertyChanging("RegionID");
                this._RegionID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("RegionID");
                this.OnRegionIDChanged();
            }
        }
        private long _RegionID;
        partial void OnRegionIDChanging(long value);
        partial void OnRegionIDChanged();
        /// <summary>
        /// There are no comments for Property RegionDescription in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string RegionDescription
        {
            get
            {
                return this._RegionDescription;
            }
            set
            {
                this.OnRegionDescriptionChanging(value);
                this.ReportPropertyChanging("RegionDescription");
                this._RegionDescription = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("RegionDescription");
                this.OnRegionDescriptionChanged();
            }
        }
        private string _RegionDescription;
        partial void OnRegionDescriptionChanging(string value);
        partial void OnRegionDescriptionChanged();
        /// <summary>
        /// There are no comments for Territories in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Territories_RegionID_RegionID", "Territories")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityCollection<Territories> Territories
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<Territories>("northwindEFModel.FK_Territories_RegionID_RegionID", "Territories");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<Territories>("northwindEFModel.FK_Territories_RegionID_RegionID", "Territories", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.Suppliers in the schema.
    /// </summary>
    /// <KeyProperties>
    /// SupplierID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Suppliers")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class Suppliers : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new Suppliers object.
        /// </summary>
        /// <param name="supplierID">Initial value of SupplierID.</param>
        /// <param name="companyName">Initial value of CompanyName.</param>
        public static Suppliers CreateSuppliers(long supplierID, string companyName)
        {
            Suppliers suppliers = new Suppliers();
            suppliers.SupplierID = supplierID;
            suppliers.CompanyName = companyName;
            return suppliers;
        }
        /// <summary>
        /// There are no comments for Property SupplierID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long SupplierID
        {
            get
            {
                return this._SupplierID;
            }
            set
            {
                this.OnSupplierIDChanging(value);
                this.ReportPropertyChanging("SupplierID");
                this._SupplierID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("SupplierID");
                this.OnSupplierIDChanged();
            }
        }
        private long _SupplierID;
        partial void OnSupplierIDChanging(long value);
        partial void OnSupplierIDChanged();
        /// <summary>
        /// There are no comments for Property CompanyName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string CompanyName
        {
            get
            {
                return this._CompanyName;
            }
            set
            {
                this.OnCompanyNameChanging(value);
                this.ReportPropertyChanging("CompanyName");
                this._CompanyName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("CompanyName");
                this.OnCompanyNameChanged();
            }
        }
        private string _CompanyName;
        partial void OnCompanyNameChanging(string value);
        partial void OnCompanyNameChanged();
        /// <summary>
        /// There are no comments for Property ContactName in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ContactName
        {
            get
            {
                return this._ContactName;
            }
            set
            {
                this.OnContactNameChanging(value);
                this.ReportPropertyChanging("ContactName");
                this._ContactName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ContactName");
                this.OnContactNameChanged();
            }
        }
        private string _ContactName;
        partial void OnContactNameChanging(string value);
        partial void OnContactNameChanged();
        /// <summary>
        /// There are no comments for Property ContactTitle in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string ContactTitle
        {
            get
            {
                return this._ContactTitle;
            }
            set
            {
                this.OnContactTitleChanging(value);
                this.ReportPropertyChanging("ContactTitle");
                this._ContactTitle = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("ContactTitle");
                this.OnContactTitleChanged();
            }
        }
        private string _ContactTitle;
        partial void OnContactTitleChanging(string value);
        partial void OnContactTitleChanged();
        /// <summary>
        /// There are no comments for Property Address in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Address
        {
            get
            {
                return this._Address;
            }
            set
            {
                this.OnAddressChanging(value);
                this.ReportPropertyChanging("Address");
                this._Address = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Address");
                this.OnAddressChanged();
            }
        }
        private string _Address;
        partial void OnAddressChanging(string value);
        partial void OnAddressChanged();
        /// <summary>
        /// There are no comments for Property City in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string City
        {
            get
            {
                return this._City;
            }
            set
            {
                this.OnCityChanging(value);
                this.ReportPropertyChanging("City");
                this._City = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("City");
                this.OnCityChanged();
            }
        }
        private string _City;
        partial void OnCityChanging(string value);
        partial void OnCityChanged();
        /// <summary>
        /// There are no comments for Property Region in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Region
        {
            get
            {
                return this._Region;
            }
            set
            {
                this.OnRegionChanging(value);
                this.ReportPropertyChanging("Region");
                this._Region = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Region");
                this.OnRegionChanged();
            }
        }
        private string _Region;
        partial void OnRegionChanging(string value);
        partial void OnRegionChanged();
        /// <summary>
        /// There are no comments for Property PostalCode in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string PostalCode
        {
            get
            {
                return this._PostalCode;
            }
            set
            {
                this.OnPostalCodeChanging(value);
                this.ReportPropertyChanging("PostalCode");
                this._PostalCode = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("PostalCode");
                this.OnPostalCodeChanged();
            }
        }
        private string _PostalCode;
        partial void OnPostalCodeChanging(string value);
        partial void OnPostalCodeChanged();
        /// <summary>
        /// There are no comments for Property Country in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Country
        {
            get
            {
                return this._Country;
            }
            set
            {
                this.OnCountryChanging(value);
                this.ReportPropertyChanging("Country");
                this._Country = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Country");
                this.OnCountryChanged();
            }
        }
        private string _Country;
        partial void OnCountryChanging(string value);
        partial void OnCountryChanged();
        /// <summary>
        /// There are no comments for Property Phone in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Phone
        {
            get
            {
                return this._Phone;
            }
            set
            {
                this.OnPhoneChanging(value);
                this.ReportPropertyChanging("Phone");
                this._Phone = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Phone");
                this.OnPhoneChanged();
            }
        }
        private string _Phone;
        partial void OnPhoneChanging(string value);
        partial void OnPhoneChanged();
        /// <summary>
        /// There are no comments for Property Fax in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Fax
        {
            get
            {
                return this._Fax;
            }
            set
            {
                this.OnFaxChanging(value);
                this.ReportPropertyChanging("Fax");
                this._Fax = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("Fax");
                this.OnFaxChanged();
            }
        }
        private string _Fax;
        partial void OnFaxChanging(string value);
        partial void OnFaxChanged();
        /// <summary>
        /// There are no comments for Property HomePage in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string HomePage
        {
            get
            {
                return this._HomePage;
            }
            set
            {
                this.OnHomePageChanging(value);
                this.ReportPropertyChanging("HomePage");
                this._HomePage = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
                this.ReportPropertyChanged("HomePage");
                this.OnHomePageChanged();
            }
        }
        private string _HomePage;
        partial void OnHomePageChanging(string value);
        partial void OnHomePageChanged();
        /// <summary>
        /// There are no comments for Products in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Products_SupplierID_SupplierID", "Products")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityCollection<Products> Products
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<Products>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Products");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<Products>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Products", value);
                }
            }
        }
    }
    /// <summary>
    /// There are no comments for northwindEFModel.Territories in the schema.
    /// </summary>
    /// <KeyProperties>
    /// TerritoryID
    /// </KeyProperties>
    [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Territories")]
    [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
    [global::System.Serializable()]
    public partial class Territories : global::System.Data.Objects.DataClasses.EntityObject
    {
        /// <summary>
        /// Create a new Territories object.
        /// </summary>
        /// <param name="territoryID">Initial value of TerritoryID.</param>
        /// <param name="territoryDescription">Initial value of TerritoryDescription.</param>
        public static Territories CreateTerritories(long territoryID, string territoryDescription)
        {
            Territories territories = new Territories();
            territories.TerritoryID = territoryID;
            territories.TerritoryDescription = territoryDescription;
            return territories;
        }
        /// <summary>
        /// There are no comments for Property TerritoryID in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public long TerritoryID
        {
            get
            {
                return this._TerritoryID;
            }
            set
            {
                this.OnTerritoryIDChanging(value);
                this.ReportPropertyChanging("TerritoryID");
                this._TerritoryID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
                this.ReportPropertyChanged("TerritoryID");
                this.OnTerritoryIDChanged();
            }
        }
        private long _TerritoryID;
        partial void OnTerritoryIDChanging(long value);
        partial void OnTerritoryIDChanged();
        /// <summary>
        /// There are no comments for Property TerritoryDescription in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string TerritoryDescription
        {
            get
            {
                return this._TerritoryDescription;
            }
            set
            {
                this.OnTerritoryDescriptionChanging(value);
                this.ReportPropertyChanging("TerritoryDescription");
                this._TerritoryDescription = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
                this.ReportPropertyChanged("TerritoryDescription");
                this.OnTerritoryDescriptionChanged();
            }
        }
        private string _TerritoryDescription;
        partial void OnTerritoryDescriptionChanging(string value);
        partial void OnTerritoryDescriptionChanged();
        /// <summary>
        /// There are no comments for Regions in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Territories_RegionID_RegionID", "Regions")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public Regions Regions
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Regions>("northwindEFModel.FK_Territories_RegionID_RegionID", "Regions").Value;
            }
            set
            {
                ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Regions>("northwindEFModel.FK_Territories_RegionID_RegionID", "Regions").Value = value;
            }
        }
        /// <summary>
        /// There are no comments for Regions in the schema.
        /// </summary>
        [global::System.ComponentModel.BrowsableAttribute(false)]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityReference<Regions> RegionsReference
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Regions>("northwindEFModel.FK_Territories_RegionID_RegionID", "Regions");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<Regions>("northwindEFModel.FK_Territories_RegionID_RegionID", "Regions", value);
                }
            }
        }
        /// <summary>
        /// There are no comments for Employees in the schema.
        /// </summary>
        [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "EmployeesTerritories", "Employees")]
        [global::System.Xml.Serialization.XmlIgnoreAttribute()]
        [global::System.Xml.Serialization.SoapIgnoreAttribute()]
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public global::System.Data.Objects.DataClasses.EntityCollection<Employees> Employees
        {
            get
            {
                return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<Employees>("northwindEFModel.EmployeesTerritories", "Employees");
            }
            set
            {
                if ((value != null))
                {
                    ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<Employees>("northwindEFModel.EmployeesTerritories", "Employees", value);
                }
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted testlinq/NorthwindModel2008.edmx.
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
<?xml version="1.0" encoding="utf-8"?>

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
  <!-- EF Runtime content -->
  <edmx:Runtime>
    <!-- SSDL content -->
    <edmx:StorageModels>
    <Schema Namespace="northwindEFModel.Store" Alias="Self" Provider="System.Data.SQLite" ProviderManifestToken="ISO8601" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
        <EntityContainer Name="northwindEFModelStoreContainer">
          <EntitySet Name="Categories" EntityType="northwindEFModel.Store.Categories" store:Type="Tables" />
          <EntitySet Name="Customers" EntityType="northwindEFModel.Store.Customers" store:Type="Tables" />
          <EntitySet Name="Employees" EntityType="northwindEFModel.Store.Employees" store:Type="Tables" />
          <EntitySet Name="EmployeesTerritories" EntityType="northwindEFModel.Store.EmployeesTerritories" store:Type="Tables" />
          <EntitySet Name="InternationalOrders" EntityType="northwindEFModel.Store.InternationalOrders" store:Type="Tables" />
          <EntitySet Name="OrderDetails" EntityType="northwindEFModel.Store.OrderDetails" store:Type="Tables" />
          <EntitySet Name="Orders" EntityType="northwindEFModel.Store.Orders" store:Type="Tables" />
          <EntitySet Name="PreviousEmployees" EntityType="northwindEFModel.Store.PreviousEmployees" store:Type="Tables" />
          <EntitySet Name="Products" EntityType="northwindEFModel.Store.Products" store:Type="Tables" />
          <EntitySet Name="Regions" EntityType="northwindEFModel.Store.Regions" store:Type="Tables" />
          <EntitySet Name="Suppliers" EntityType="northwindEFModel.Store.Suppliers" store:Type="Tables" />
          <EntitySet Name="Territories" EntityType="northwindEFModel.Store.Territories" store:Type="Tables" />
          <AssociationSet Name="FK_EmployeesTerritories_EmployeeID_EmployeeID" Association="northwindEFModel.Store.FK_EmployeesTerritories_EmployeeID_EmployeeID">
            <End Role="Employees" EntitySet="Employees" />
            <End Role="EmployeesTerritories" EntitySet="EmployeesTerritories" />
          </AssociationSet>
          <AssociationSet Name="FK_EmployeesTerritories_TerritoryID_TerritoryID" Association="northwindEFModel.Store.FK_EmployeesTerritories_TerritoryID_TerritoryID">
            <End Role="Territories" EntitySet="Territories" />
            <End Role="EmployeesTerritories" EntitySet="EmployeesTerritories" />
          </AssociationSet>
          <AssociationSet Name="FK_InternationalOrders_OrderID_OrderID" Association="northwindEFModel.Store.FK_InternationalOrders_OrderID_OrderID">
            <End Role="Orders" EntitySet="Orders" />
            <End Role="InternationalOrders" EntitySet="InternationalOrders" />
          </AssociationSet>
          <AssociationSet Name="FK_OrderDetails_OrderID_OrderID" Association="northwindEFModel.Store.FK_OrderDetails_OrderID_OrderID">
            <End Role="Orders" EntitySet="Orders" />
            <End Role="OrderDetails" EntitySet="OrderDetails" />
          </AssociationSet>
          <AssociationSet Name="FK_OrderDetails_ProductID_ProductID" Association="northwindEFModel.Store.FK_OrderDetails_ProductID_ProductID">
            <End Role="Products" EntitySet="Products" />
            <End Role="OrderDetails" EntitySet="OrderDetails" />
          </AssociationSet>
          <AssociationSet Name="FK_Orders_CustomerID_CustomerID" Association="northwindEFModel.Store.FK_Orders_CustomerID_CustomerID">
            <End Role="Customers" EntitySet="Customers" />
            <End Role="Orders" EntitySet="Orders" />
          </AssociationSet>
          <AssociationSet Name="FK_Products_CategoryID_CategoryID" Association="northwindEFModel.Store.FK_Products_CategoryID_CategoryID">
            <End Role="Categories" EntitySet="Categories" />
            <End Role="Products" EntitySet="Products" />
          </AssociationSet>
          <AssociationSet Name="FK_Products_SupplierID_SupplierID" Association="northwindEFModel.Store.FK_Products_SupplierID_SupplierID">
            <End Role="Suppliers" EntitySet="Suppliers" />
            <End Role="Products" EntitySet="Products" />
          </AssociationSet>
          <AssociationSet Name="FK_Territories_RegionID_RegionID" Association="northwindEFModel.Store.FK_Territories_RegionID_RegionID">
            <End Role="Regions" EntitySet="Regions" />
            <End Role="Territories" EntitySet="Territories" />
          </AssociationSet>
        </EntityContainer>
        <EntityType Name="Categories">
          <Key>
            <PropertyRef Name="CategoryID" />
          </Key>
          <Property Name="CategoryID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="CategoryName" Type="nvarchar" Nullable="false" MaxLength="15" />
          <Property Name="Description" Type="nvarchar" />
          <Property Name="Picture" Type="blob" />
        </EntityType>
        <EntityType Name="Customers">
          <Key>
            <PropertyRef Name="CustomerID" />
          </Key>
          <Property Name="CustomerID" Type="nvarchar" Nullable="false" MaxLength="5" />
          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
          <Property Name="ContactName" Type="nvarchar" MaxLength="30" />
          <Property Name="ContactTitle" Type="nvarchar" MaxLength="30" />
          <Property Name="Address" Type="nvarchar" MaxLength="60" />
          <Property Name="City" Type="nvarchar" MaxLength="15" />
          <Property Name="Region" Type="nvarchar" MaxLength="15" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="Country" Type="nvarchar" MaxLength="15" />
          <Property Name="Phone" Type="nvarchar" MaxLength="24" />
          <Property Name="Fax" Type="nvarchar" MaxLength="24" />
        </EntityType>
        <EntityType Name="Employees">
          <Key>
            <PropertyRef Name="EmployeeID" />
          </Key>
          <Property Name="EmployeeID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="20" />
          <Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="10" />
          <Property Name="Title" Type="nvarchar" MaxLength="30" />
          <Property Name="TitleOfCourtesy" Type="nvarchar" MaxLength="25" />
          <Property Name="BirthDate" Type="datetime" />
          <Property Name="HireDate" Type="datetime" />
          <Property Name="Address" Type="nvarchar" MaxLength="60" />
          <Property Name="City" Type="nvarchar" MaxLength="15" />
          <Property Name="Region" Type="nvarchar" MaxLength="15" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="Country" Type="nvarchar" MaxLength="15" />
          <Property Name="HomePhone" Type="nvarchar" MaxLength="24" />
          <Property Name="Extension" Type="nvarchar" MaxLength="4" />
          <Property Name="Photo" Type="blob" />
          <Property Name="Notes" Type="nvarchar" />
          <Property Name="PhotoPath" Type="nvarchar" MaxLength="255" />
        </EntityType>
        <EntityType Name="EmployeesTerritories">
          <Key>
            <PropertyRef Name="EmployeeID" />
            <PropertyRef Name="TerritoryID" />
          </Key>
          <Property Name="EmployeeID" Type="integer" Nullable="false" />
          <Property Name="TerritoryID" Type="integer" Nullable="false" />
        </EntityType>
        <EntityType Name="InternationalOrders">
          <Key>
            <PropertyRef Name="OrderID" />
          </Key>
          <Property Name="OrderID" Type="integer" Nullable="false" />
          <Property Name="CustomsDescription" Type="nvarchar" Nullable="false" MaxLength="100" />
          <Property Name="ExciseTax" Type="decimal" Nullable="false" Precision="53" />
        </EntityType>
        <EntityType Name="OrderDetails">
          <Key>
            <PropertyRef Name="OrderID" />
            <PropertyRef Name="ProductID" />
          </Key>
          <Property Name="OrderID" Type="integer" Nullable="false" />
          <Property Name="ProductID" Type="integer" Nullable="false" />
          <Property Name="UnitPrice" Type="decimal" Nullable="false" Precision="53" />
          <Property Name="Quantity" Type="smallint" Nullable="false" />
          <Property Name="Discount" Type="real" Nullable="false" />
        </EntityType>
        <EntityType Name="Orders">
          <Key>
            <PropertyRef Name="OrderID" />
          </Key>
          <Property Name="OrderID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="CustomerID" Type="nvarchar" MaxLength="5" />
          <Property Name="EmployeeID" Type="integer" />
          <Property Name="OrderDate" Type="datetime" />
          <Property Name="RequiredDate" Type="datetime" />
          <Property Name="ShippedDate" Type="datetime" />
          <Property Name="Freight" Type="decimal" Precision="53" />
          <Property Name="ShipName" Type="nvarchar" MaxLength="40" />
          <Property Name="ShipAddress" Type="nvarchar" MaxLength="60" />
          <Property Name="ShipCity" Type="nvarchar" MaxLength="15" />
          <Property Name="ShipRegion" Type="nvarchar" MaxLength="15" />
          <Property Name="ShipPostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="ShipCountry" Type="nvarchar" MaxLength="15" />
        </EntityType>
        <EntityType Name="PreviousEmployees">
          <Key>
            <PropertyRef Name="EmployeeID" />
          </Key>
          <Property Name="EmployeeID" Type="integer" Nullable="false" />
          <Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="20" />
          <Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="10" />
          <Property Name="Title" Type="nvarchar" MaxLength="30" />
          <Property Name="TitleOfCourtesy" Type="nvarchar" MaxLength="25" />
          <Property Name="BirthDate" Type="datetime" />
          <Property Name="HireDate" Type="datetime" />
          <Property Name="Address" Type="nvarchar" MaxLength="60" />
          <Property Name="City" Type="nvarchar" MaxLength="15" />
          <Property Name="Region" Type="nvarchar" MaxLength="15" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="Country" Type="nvarchar" MaxLength="15" />
          <Property Name="HomePhone" Type="nvarchar" MaxLength="24" />
          <Property Name="Extension" Type="nvarchar" MaxLength="4" />
          <Property Name="Photo" Type="blob" />
          <Property Name="Notes" Type="nvarchar" />
          <Property Name="PhotoPath" Type="nvarchar" MaxLength="255" />
        </EntityType>
        <EntityType Name="Products">
          <Key>
            <PropertyRef Name="ProductID" />
          </Key>
          <Property Name="ProductID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
          <Property Name="SupplierID" Type="integer" />
          <Property Name="CategoryID" Type="integer" />
          <Property Name="QuantityPerUnit" Type="nvarchar" MaxLength="20" />
          <Property Name="UnitPrice" Type="decimal" Precision="53" />
          <Property Name="UnitsInStock" Type="smallint" />
          <Property Name="UnitsOnOrder" Type="smallint" />
          <Property Name="ReorderLevel" Type="smallint" />
          <Property Name="Discontinued" Type="bit" Nullable="false" />
          <Property Name="DiscontinuedDate" Type="datetime" />
        </EntityType>
        <EntityType Name="Regions">
          <Key>
            <PropertyRef Name="RegionID" />
          </Key>
          <Property Name="RegionID" Type="integer" Nullable="false" />
          <Property Name="RegionDescription" Type="nvarchar" Nullable="false" MaxLength="50" />
        </EntityType>
        <EntityType Name="Suppliers">
          <Key>
            <PropertyRef Name="SupplierID" />
          </Key>
          <Property Name="SupplierID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
          <Property Name="ContactName" Type="nvarchar" MaxLength="30" />
          <Property Name="ContactTitle" Type="nvarchar" MaxLength="30" />
          <Property Name="Address" Type="nvarchar" MaxLength="60" />
          <Property Name="City" Type="nvarchar" MaxLength="15" />
          <Property Name="Region" Type="nvarchar" MaxLength="15" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="Country" Type="nvarchar" MaxLength="15" />
          <Property Name="Phone" Type="nvarchar" MaxLength="24" />
          <Property Name="Fax" Type="nvarchar" MaxLength="24" />
          <Property Name="HomePage" Type="nvarchar" />
        </EntityType>
        <EntityType Name="Territories">
          <Key>
            <PropertyRef Name="TerritoryID" />
          </Key>
          <Property Name="TerritoryID" Type="integer" Nullable="false" />
          <Property Name="TerritoryDescription" Type="nvarchar" Nullable="false" MaxLength="50" />
          <Property Name="RegionID" Type="integer" Nullable="false" />
        </EntityType>
        <Association Name="FK_EmployeesTerritories_EmployeeID_EmployeeID">
          <End Role="Employees" Type="northwindEFModel.Store.Employees" Multiplicity="1" />
          <End Role="EmployeesTerritories" Type="northwindEFModel.Store.EmployeesTerritories" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Employees">
              <PropertyRef Name="EmployeeID" />
            </Principal>
            <Dependent Role="EmployeesTerritories">
              <PropertyRef Name="EmployeeID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_EmployeesTerritories_TerritoryID_TerritoryID">
          <End Role="Territories" Type="northwindEFModel.Store.Territories" Multiplicity="1" />
          <End Role="EmployeesTerritories" Type="northwindEFModel.Store.EmployeesTerritories" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Territories">
              <PropertyRef Name="TerritoryID" />
            </Principal>
            <Dependent Role="EmployeesTerritories">
              <PropertyRef Name="TerritoryID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_InternationalOrders_OrderID_OrderID">
          <End Role="Orders" Type="northwindEFModel.Store.Orders" Multiplicity="1" />
          <End Role="InternationalOrders" Type="northwindEFModel.Store.InternationalOrders" Multiplicity="0..1" />
          <ReferentialConstraint>
            <Principal Role="Orders">
              <PropertyRef Name="OrderID" />
            </Principal>
            <Dependent Role="InternationalOrders">
              <PropertyRef Name="OrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_OrderDetails_OrderID_OrderID">
          <End Role="Orders" Type="northwindEFModel.Store.Orders" Multiplicity="1" />
          <End Role="OrderDetails" Type="northwindEFModel.Store.OrderDetails" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Orders">
              <PropertyRef Name="OrderID" />
            </Principal>
            <Dependent Role="OrderDetails">
              <PropertyRef Name="OrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_OrderDetails_ProductID_ProductID">
          <End Role="Products" Type="northwindEFModel.Store.Products" Multiplicity="1" />
          <End Role="OrderDetails" Type="northwindEFModel.Store.OrderDetails" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Products">
              <PropertyRef Name="ProductID" />
            </Principal>
            <Dependent Role="OrderDetails">
              <PropertyRef Name="ProductID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Orders_CustomerID_CustomerID">
          <End Role="Customers" Type="northwindEFModel.Store.Customers" Multiplicity="0..1" />
          <End Role="Orders" Type="northwindEFModel.Store.Orders" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Customers">
              <PropertyRef Name="CustomerID" />
            </Principal>
            <Dependent Role="Orders">
              <PropertyRef Name="CustomerID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Products_CategoryID_CategoryID">
          <End Role="Categories" Type="northwindEFModel.Store.Categories" Multiplicity="0..1" />
          <End Role="Products" Type="northwindEFModel.Store.Products" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Categories">
              <PropertyRef Name="CategoryID" />
            </Principal>
            <Dependent Role="Products">
              <PropertyRef Name="CategoryID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Products_SupplierID_SupplierID">
          <End Role="Suppliers" Type="northwindEFModel.Store.Suppliers" Multiplicity="0..1" />
          <End Role="Products" Type="northwindEFModel.Store.Products" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Suppliers">
              <PropertyRef Name="SupplierID" />
            </Principal>
            <Dependent Role="Products">
              <PropertyRef Name="SupplierID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Territories_RegionID_RegionID">
          <End Role="Regions" Type="northwindEFModel.Store.Regions" Multiplicity="1" />
          <End Role="Territories" Type="northwindEFModel.Store.Territories" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Regions">
              <PropertyRef Name="RegionID" />
            </Principal>
            <Dependent Role="Territories">
              <PropertyRef Name="RegionID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
      </Schema></edmx:StorageModels>
    <!-- CSDL content -->
    <edmx:ConceptualModels>
      <Schema Namespace="northwindEFModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
        <EntityContainer Name="northwindEFEntities">
          <EntitySet Name="Categories" EntityType="northwindEFModel.Categories" />
          <EntitySet Name="Customers" EntityType="northwindEFModel.Customers" />
          <EntitySet Name="Employees" EntityType="northwindEFModel.Employees" />
          <EntitySet Name="InternationalOrders" EntityType="northwindEFModel.InternationalOrders" />
          <EntitySet Name="OrderDetails" EntityType="northwindEFModel.OrderDetails" />
          <EntitySet Name="Orders" EntityType="northwindEFModel.Orders" />
          <EntitySet Name="PreviousEmployees" EntityType="northwindEFModel.PreviousEmployees" />
          <EntitySet Name="Products" EntityType="northwindEFModel.Products" />
          <EntitySet Name="Regions" EntityType="northwindEFModel.Regions" />
          <EntitySet Name="Suppliers" EntityType="northwindEFModel.Suppliers" />
          <EntitySet Name="Territories" EntityType="northwindEFModel.Territories" />
          <AssociationSet Name="FK_Products_CategoryID_CategoryID" Association="northwindEFModel.FK_Products_CategoryID_CategoryID">
            <End Role="Categories" EntitySet="Categories" />
            <End Role="Products" EntitySet="Products" />
          </AssociationSet>
          <AssociationSet Name="FK_Orders_CustomerID_CustomerID" Association="northwindEFModel.FK_Orders_CustomerID_CustomerID">
            <End Role="Customers" EntitySet="Customers" />
            <End Role="Orders" EntitySet="Orders" />
          </AssociationSet>
          <AssociationSet Name="FK_InternationalOrders_OrderID_OrderID" Association="northwindEFModel.FK_InternationalOrders_OrderID_OrderID">
            <End Role="Orders" EntitySet="Orders" />
            <End Role="InternationalOrders" EntitySet="InternationalOrders" />
          </AssociationSet>
          <AssociationSet Name="FK_OrderDetails_OrderID_OrderID" Association="northwindEFModel.FK_OrderDetails_OrderID_OrderID">
            <End Role="Orders" EntitySet="Orders" />
            <End Role="OrderDetails" EntitySet="OrderDetails" />
          </AssociationSet>
          <AssociationSet Name="FK_OrderDetails_ProductID_ProductID" Association="northwindEFModel.FK_OrderDetails_ProductID_ProductID">
            <End Role="Products" EntitySet="Products" />
            <End Role="OrderDetails" EntitySet="OrderDetails" />
          </AssociationSet>
          <AssociationSet Name="FK_Products_SupplierID_SupplierID" Association="northwindEFModel.FK_Products_SupplierID_SupplierID">
            <End Role="Suppliers" EntitySet="Suppliers" />
            <End Role="Products" EntitySet="Products" />
          </AssociationSet>
          <AssociationSet Name="FK_Territories_RegionID_RegionID" Association="northwindEFModel.FK_Territories_RegionID_RegionID">
            <End Role="Regions" EntitySet="Regions" />
            <End Role="Territories" EntitySet="Territories" />
          </AssociationSet>
          <AssociationSet Name="EmployeesTerritories" Association="northwindEFModel.EmployeesTerritories">
            <End Role="Employees" EntitySet="Employees" />
            <End Role="Territories" EntitySet="Territories" />
          </AssociationSet>
          </EntityContainer>
        <EntityType Name="Categories">
          <Key>
            <PropertyRef Name="CategoryID" />
          </Key>
          <Property Name="CategoryID" Type="Int64" Nullable="false" />
          <Property Name="CategoryName" Type="String" Nullable="false" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Description" Type="String" MaxLength="2147483647" Unicode="true" FixedLength="false" />
          <Property Name="Picture" Type="Binary" MaxLength="2147483647" FixedLength="false" />
          <NavigationProperty Name="Products" Relationship="northwindEFModel.FK_Products_CategoryID_CategoryID" FromRole="Categories" ToRole="Products" />
        </EntityType>
        <EntityType Name="Customers">
          <Key>
            <PropertyRef Name="CustomerID" />
          </Key>
          <Property Name="CustomerID" Type="String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="false" />
          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
          <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Orders" Relationship="northwindEFModel.FK_Orders_CustomerID_CustomerID" FromRole="Customers" ToRole="Orders" />
        </EntityType>
        <EntityType Name="Employees">
          <Key>
            <PropertyRef Name="EmployeeID" />
          </Key>
          <Property Name="EmployeeID" Type="Int64" Nullable="false" />
          <Property Name="LastName" Type="String" Nullable="false" MaxLength="20" Unicode="true" FixedLength="false" />
          <Property Name="FirstName" Type="String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Title" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="TitleOfCourtesy" Type="String" MaxLength="25" Unicode="true" FixedLength="false" />
          <Property Name="BirthDate" Type="DateTime" />
          <Property Name="HireDate" Type="DateTime" />
          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="HomePhone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="Extension" Type="String" MaxLength="4" Unicode="true" FixedLength="false" />
          <Property Name="Photo" Type="Binary" MaxLength="2147483647" FixedLength="false" />
          <Property Name="Notes" Type="String" MaxLength="2147483647" Unicode="true" FixedLength="false" />
          <Property Name="PhotoPath" Type="String" MaxLength="255" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Territories" Relationship="northwindEFModel.EmployeesTerritories" FromRole="Employees" ToRole="Territories" />
        </EntityType>
        <EntityType Name="InternationalOrders">
          <Key>
            <PropertyRef Name="OrderID" />
          </Key>
          <Property Name="OrderID" Type="Int64" Nullable="false" />
          <Property Name="CustomsDescription" Type="String" Nullable="false" MaxLength="100" Unicode="true" FixedLength="false" />
          <Property Name="ExciseTax" Type="Decimal" Nullable="false" Precision="53" Scale="0" />
          <NavigationProperty Name="Orders" Relationship="northwindEFModel.FK_InternationalOrders_OrderID_OrderID" FromRole="InternationalOrders" ToRole="Orders" />
        </EntityType>
        <EntityType Name="OrderDetails">
          <Key>
            <PropertyRef Name="OrderID" />
            <PropertyRef Name="ProductID" />
          </Key>
          <Property Name="OrderID" Type="Int64" Nullable="false" />
          <Property Name="ProductID" Type="Int64" Nullable="false" />
          <Property Name="UnitPrice" Type="Decimal" Nullable="false" Precision="53" Scale="0" />
          <Property Name="Quantity" Type="Int16" Nullable="false" />
          <Property Name="Discount" Type="Single" Nullable="false" />
          <NavigationProperty Name="Orders" Relationship="northwindEFModel.FK_OrderDetails_OrderID_OrderID" FromRole="OrderDetails" ToRole="Orders" />
          <NavigationProperty Name="Products" Relationship="northwindEFModel.FK_OrderDetails_ProductID_ProductID" FromRole="OrderDetails" ToRole="Products" />
        </EntityType>
        <EntityType Name="Orders">
          <Key>
            <PropertyRef Name="OrderID" />
          </Key>
          <Property Name="OrderID" Type="Int64" Nullable="false" />
          <Property Name="EmployeeID" Type="Int64" />
          <Property Name="OrderDate" Type="DateTime" />
          <Property Name="RequiredDate" Type="DateTime" />
          <Property Name="ShippedDate" Type="DateTime" />
          <Property Name="Freight" Type="Decimal" Precision="53" Scale="0" />
          <Property Name="ShipName" Type="String" MaxLength="40" Unicode="true" FixedLength="false" />
          <Property Name="ShipAddress" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="ShipCity" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="ShipRegion" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="ShipPostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="ShipCountry" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Customers" Relationship="northwindEFModel.FK_Orders_CustomerID_CustomerID" FromRole="Orders" ToRole="Customers" />
          <NavigationProperty Name="InternationalOrders" Relationship="northwindEFModel.FK_InternationalOrders_OrderID_OrderID" FromRole="Orders" ToRole="InternationalOrders" />
          <NavigationProperty Name="OrderDetails" Relationship="northwindEFModel.FK_OrderDetails_OrderID_OrderID" FromRole="Orders" ToRole="OrderDetails" />
        </EntityType>
        <EntityType Name="PreviousEmployees">
          <Key>
            <PropertyRef Name="EmployeeID" />
          </Key>
          <Property Name="EmployeeID" Type="Int64" Nullable="false" />
          <Property Name="LastName" Type="String" Nullable="false" MaxLength="20" Unicode="true" FixedLength="false" />
          <Property Name="FirstName" Type="String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Title" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="TitleOfCourtesy" Type="String" MaxLength="25" Unicode="true" FixedLength="false" />
          <Property Name="BirthDate" Type="DateTime" />
          <Property Name="HireDate" Type="DateTime" />
          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="HomePhone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="Extension" Type="String" MaxLength="4" Unicode="true" FixedLength="false" />
          <Property Name="Photo" Type="Binary" MaxLength="2147483647" FixedLength="false" />
          <Property Name="Notes" Type="String" MaxLength="2147483647" Unicode="true" FixedLength="false" />
          <Property Name="PhotoPath" Type="String" MaxLength="255" Unicode="true" FixedLength="false" />
        </EntityType>
        <EntityType Name="Products">
          <Key>
            <PropertyRef Name="ProductID" />
          </Key>
          <Property Name="ProductID" Type="Int64" Nullable="false" />
          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
          <Property Name="QuantityPerUnit" Type="String" MaxLength="20" Unicode="true" FixedLength="false" />
          <Property Name="UnitPrice" Type="Decimal" Precision="53" Scale="0" />
          <Property Name="UnitsInStock" Type="Int16" />
          <Property Name="UnitsOnOrder" Type="Int16" />
          <Property Name="ReorderLevel" Type="Int16" />
          <Property Name="Discontinued" Type="Boolean" Nullable="false" />
          <Property Name="DiscontinuedDate" Type="DateTime" />
          <NavigationProperty Name="Categories" Relationship="northwindEFModel.FK_Products_CategoryID_CategoryID" FromRole="Products" ToRole="Categories" />
          <NavigationProperty Name="OrderDetails" Relationship="northwindEFModel.FK_OrderDetails_ProductID_ProductID" FromRole="Products" ToRole="OrderDetails" />
          <NavigationProperty Name="Suppliers" Relationship="northwindEFModel.FK_Products_SupplierID_SupplierID" FromRole="Products" ToRole="Suppliers" />
        </EntityType>
        <EntityType Name="Regions">
          <Key>
            <PropertyRef Name="RegionID" />
          </Key>
          <Property Name="RegionID" Type="Int64" Nullable="false" />
          <Property Name="RegionDescription" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Territories" Relationship="northwindEFModel.FK_Territories_RegionID_RegionID" FromRole="Regions" ToRole="Territories" />
        </EntityType>
        <EntityType Name="Suppliers">
          <Key>
            <PropertyRef Name="SupplierID" />
          </Key>
          <Property Name="SupplierID" Type="Int64" Nullable="false" />
          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
          <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="HomePage" Type="String" MaxLength="2147483647" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Products" Relationship="northwindEFModel.FK_Products_SupplierID_SupplierID" FromRole="Suppliers" ToRole="Products" />
        </EntityType>
        <EntityType Name="Territories">
          <Key>
            <PropertyRef Name="TerritoryID" />
          </Key>
          <Property Name="TerritoryID" Type="Int64" Nullable="false" />
          <Property Name="TerritoryDescription" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Regions" Relationship="northwindEFModel.FK_Territories_RegionID_RegionID" FromRole="Territories" ToRole="Regions" />
          <NavigationProperty Name="Employees" Relationship="northwindEFModel.EmployeesTerritories" FromRole="Territories" ToRole="Employees" />
        </EntityType>
        <Association Name="FK_Products_CategoryID_CategoryID">
          <End Role="Categories" Type="northwindEFModel.Categories" Multiplicity="0..1" />
          <End Role="Products" Type="northwindEFModel.Products" Multiplicity="*" />
        </Association>
        <Association Name="FK_Orders_CustomerID_CustomerID">
          <End Role="Customers" Type="northwindEFModel.Customers" Multiplicity="0..1" />
          <End Role="Orders" Type="northwindEFModel.Orders" Multiplicity="*" />
        </Association>
        <Association Name="FK_InternationalOrders_OrderID_OrderID">
          <End Role="Orders" Type="northwindEFModel.Orders" Multiplicity="1" />
          <End Role="InternationalOrders" Type="northwindEFModel.InternationalOrders" Multiplicity="0..1" />
          <ReferentialConstraint>
            <Principal Role="Orders">
              <PropertyRef Name="OrderID" />
            </Principal>
            <Dependent Role="InternationalOrders">
              <PropertyRef Name="OrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_OrderDetails_OrderID_OrderID">
          <End Role="Orders" Type="northwindEFModel.Orders" Multiplicity="1" />
          <End Role="OrderDetails" Type="northwindEFModel.OrderDetails" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Orders">
              <PropertyRef Name="OrderID" />
            </Principal>
            <Dependent Role="OrderDetails">
              <PropertyRef Name="OrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_OrderDetails_ProductID_ProductID">
          <End Role="Products" Type="northwindEFModel.Products" Multiplicity="1" />
          <End Role="OrderDetails" Type="northwindEFModel.OrderDetails" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Products">
              <PropertyRef Name="ProductID" />
            </Principal>
            <Dependent Role="OrderDetails">
              <PropertyRef Name="ProductID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Products_SupplierID_SupplierID">
          <End Role="Suppliers" Type="northwindEFModel.Suppliers" Multiplicity="0..1" />
          <End Role="Products" Type="northwindEFModel.Products" Multiplicity="*" />
        </Association>
        <Association Name="FK_Territories_RegionID_RegionID">
          <End Role="Regions" Type="northwindEFModel.Regions" Multiplicity="1" />
          <End Role="Territories" Type="northwindEFModel.Territories" Multiplicity="*" />
        </Association>
        <Association Name="EmployeesTerritories">
          <End Role="Employees" Type="northwindEFModel.Employees" Multiplicity="*" />
          <End Role="Territories" Type="northwindEFModel.Territories" Multiplicity="*" />
        </Association>
        </Schema>
    </edmx:ConceptualModels>
    <!-- C-S mapping content -->
    <edmx:Mappings>
      <Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
        <EntityContainerMapping StorageEntityContainer="northwindEFModelStoreContainer" CdmEntityContainer="northwindEFEntities">
          <EntitySetMapping Name="Categories">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Categories)">
              <MappingFragment StoreEntitySet="Categories">
                <ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
                <ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
                <ScalarProperty Name="Description" ColumnName="Description" />
                <ScalarProperty Name="Picture" ColumnName="Picture" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Customers">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Customers)">
              <MappingFragment StoreEntitySet="Customers">
                <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
                <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
                <ScalarProperty Name="ContactName" ColumnName="ContactName" />
                <ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
                <ScalarProperty Name="Address" ColumnName="Address" />
                <ScalarProperty Name="City" ColumnName="City" />
                <ScalarProperty Name="Region" ColumnName="Region" />
                <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
                <ScalarProperty Name="Country" ColumnName="Country" />
                <ScalarProperty Name="Phone" ColumnName="Phone" />
                <ScalarProperty Name="Fax" ColumnName="Fax" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Employees">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Employees)">
              <MappingFragment StoreEntitySet="Employees">
                <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
                <ScalarProperty Name="LastName" ColumnName="LastName" />
                <ScalarProperty Name="FirstName" ColumnName="FirstName" />
                <ScalarProperty Name="Title" ColumnName="Title" />
                <ScalarProperty Name="TitleOfCourtesy" ColumnName="TitleOfCourtesy" />
                <ScalarProperty Name="BirthDate" ColumnName="BirthDate" />
                <ScalarProperty Name="HireDate" ColumnName="HireDate" />
                <ScalarProperty Name="Address" ColumnName="Address" />
                <ScalarProperty Name="City" ColumnName="City" />
                <ScalarProperty Name="Region" ColumnName="Region" />
                <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
                <ScalarProperty Name="Country" ColumnName="Country" />
                <ScalarProperty Name="HomePhone" ColumnName="HomePhone" />
                <ScalarProperty Name="Extension" ColumnName="Extension" />
                <ScalarProperty Name="Photo" ColumnName="Photo" />
                <ScalarProperty Name="Notes" ColumnName="Notes" />
                <ScalarProperty Name="PhotoPath" ColumnName="PhotoPath" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="InternationalOrders">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.InternationalOrders)">
              <MappingFragment StoreEntitySet="InternationalOrders">
                <ScalarProperty Name="OrderID" ColumnName="OrderID" />
                <ScalarProperty Name="CustomsDescription" ColumnName="CustomsDescription" />
                <ScalarProperty Name="ExciseTax" ColumnName="ExciseTax" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="OrderDetails">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.OrderDetails)">
              <MappingFragment StoreEntitySet="OrderDetails">
                <ScalarProperty Name="OrderID" ColumnName="OrderID" />
                <ScalarProperty Name="ProductID" ColumnName="ProductID" />
                <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
                <ScalarProperty Name="Quantity" ColumnName="Quantity" />
                <ScalarProperty Name="Discount" ColumnName="Discount" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Orders">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Orders)">
              <MappingFragment StoreEntitySet="Orders">
                <ScalarProperty Name="OrderID" ColumnName="OrderID" />
                <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
                <ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
                <ScalarProperty Name="RequiredDate" ColumnName="RequiredDate" />
                <ScalarProperty Name="ShippedDate" ColumnName="ShippedDate" />
                <ScalarProperty Name="Freight" ColumnName="Freight" />
                <ScalarProperty Name="ShipName" ColumnName="ShipName" />
                <ScalarProperty Name="ShipAddress" ColumnName="ShipAddress" />
                <ScalarProperty Name="ShipCity" ColumnName="ShipCity" />
                <ScalarProperty Name="ShipRegion" ColumnName="ShipRegion" />
                <ScalarProperty Name="ShipPostalCode" ColumnName="ShipPostalCode" />
                <ScalarProperty Name="ShipCountry" ColumnName="ShipCountry" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="PreviousEmployees">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.PreviousEmployees)">
              <MappingFragment StoreEntitySet="PreviousEmployees">
                <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
                <ScalarProperty Name="LastName" ColumnName="LastName" />
                <ScalarProperty Name="FirstName" ColumnName="FirstName" />
                <ScalarProperty Name="Title" ColumnName="Title" />
                <ScalarProperty Name="TitleOfCourtesy" ColumnName="TitleOfCourtesy" />
                <ScalarProperty Name="BirthDate" ColumnName="BirthDate" />
                <ScalarProperty Name="HireDate" ColumnName="HireDate" />
                <ScalarProperty Name="Address" ColumnName="Address" />
                <ScalarProperty Name="City" ColumnName="City" />
                <ScalarProperty Name="Region" ColumnName="Region" />
                <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
                <ScalarProperty Name="Country" ColumnName="Country" />
                <ScalarProperty Name="HomePhone" ColumnName="HomePhone" />
                <ScalarProperty Name="Extension" ColumnName="Extension" />
                <ScalarProperty Name="Photo" ColumnName="Photo" />
                <ScalarProperty Name="Notes" ColumnName="Notes" />
                <ScalarProperty Name="PhotoPath" ColumnName="PhotoPath" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Products">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Products)">
              <MappingFragment StoreEntitySet="Products">
                <ScalarProperty Name="ProductID" ColumnName="ProductID" />
                <ScalarProperty Name="ProductName" ColumnName="ProductName" />
                <ScalarProperty Name="QuantityPerUnit" ColumnName="QuantityPerUnit" />
                <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
                <ScalarProperty Name="UnitsInStock" ColumnName="UnitsInStock" />
                <ScalarProperty Name="UnitsOnOrder" ColumnName="UnitsOnOrder" />
                <ScalarProperty Name="ReorderLevel" ColumnName="ReorderLevel" />
                <ScalarProperty Name="Discontinued" ColumnName="Discontinued" />
                <ScalarProperty Name="DiscontinuedDate" ColumnName="DiscontinuedDate" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Regions">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Regions)">
              <MappingFragment StoreEntitySet="Regions">
                <ScalarProperty Name="RegionID" ColumnName="RegionID" />
                <ScalarProperty Name="RegionDescription" ColumnName="RegionDescription" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Suppliers">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Suppliers)">
              <MappingFragment StoreEntitySet="Suppliers">
                <ScalarProperty Name="SupplierID" ColumnName="SupplierID" />
                <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
                <ScalarProperty Name="ContactName" ColumnName="ContactName" />
                <ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
                <ScalarProperty Name="Address" ColumnName="Address" />
                <ScalarProperty Name="City" ColumnName="City" />
                <ScalarProperty Name="Region" ColumnName="Region" />
                <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
                <ScalarProperty Name="Country" ColumnName="Country" />
                <ScalarProperty Name="Phone" ColumnName="Phone" />
                <ScalarProperty Name="Fax" ColumnName="Fax" />
                <ScalarProperty Name="HomePage" ColumnName="HomePage" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Territories">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Territories)">
              <MappingFragment StoreEntitySet="Territories">
                <ScalarProperty Name="TerritoryID" ColumnName="TerritoryID" />
                <ScalarProperty Name="TerritoryDescription" ColumnName="TerritoryDescription" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <AssociationSetMapping Name="FK_Products_CategoryID_CategoryID" TypeName="northwindEFModel.FK_Products_CategoryID_CategoryID" StoreEntitySet="Products">
            <EndProperty Name="Categories">
              <ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
            </EndProperty>
            <EndProperty Name="Products">
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
            <Condition ColumnName="CategoryID" IsNull="false" />
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_Orders_CustomerID_CustomerID" TypeName="northwindEFModel.FK_Orders_CustomerID_CustomerID" StoreEntitySet="Orders">
            <EndProperty Name="Customers">
              <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
            </EndProperty>
            <EndProperty Name="Orders">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
            </EndProperty>
            <Condition ColumnName="CustomerID" IsNull="false" />
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_InternationalOrders_OrderID_OrderID" TypeName="northwindEFModel.FK_InternationalOrders_OrderID_OrderID" StoreEntitySet="InternationalOrders">
            <EndProperty Name="Orders">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
            </EndProperty>
            <EndProperty Name="InternationalOrders">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
            </EndProperty>
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_OrderDetails_OrderID_OrderID" TypeName="northwindEFModel.FK_OrderDetails_OrderID_OrderID" StoreEntitySet="OrderDetails">
            <EndProperty Name="Orders">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
            </EndProperty>
            <EndProperty Name="OrderDetails">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_OrderDetails_ProductID_ProductID" TypeName="northwindEFModel.FK_OrderDetails_ProductID_ProductID" StoreEntitySet="OrderDetails">
            <EndProperty Name="Products">
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
            <EndProperty Name="OrderDetails">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_Products_SupplierID_SupplierID" TypeName="northwindEFModel.FK_Products_SupplierID_SupplierID" StoreEntitySet="Products">
            <EndProperty Name="Suppliers">
              <ScalarProperty Name="SupplierID" ColumnName="SupplierID" />
            </EndProperty>
            <EndProperty Name="Products">
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
            <Condition ColumnName="SupplierID" IsNull="false" />
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_Territories_RegionID_RegionID" TypeName="northwindEFModel.FK_Territories_RegionID_RegionID" StoreEntitySet="Territories">
            <EndProperty Name="Regions">
              <ScalarProperty Name="RegionID" ColumnName="RegionID" />
            </EndProperty>
            <EndProperty Name="Territories">
              <ScalarProperty Name="TerritoryID" ColumnName="TerritoryID" />
            </EndProperty>
          </AssociationSetMapping>
          <AssociationSetMapping Name="EmployeesTerritories" TypeName="northwindEFModel.EmployeesTerritories" StoreEntitySet="EmployeesTerritories">
            <EndProperty Name="Employees">
              <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
            </EndProperty>
            <EndProperty Name="Territories">
              <ScalarProperty Name="TerritoryID" ColumnName="TerritoryID" />
            </EndProperty>
          </AssociationSetMapping>
          </EntityContainerMapping>
      </Mapping>
    </edmx:Mappings>
  </edmx:Runtime>
  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
  <edmx:Designer xmlns="http://schemas.microsoft.com/ado/2007/06/edmx">
    <edmx:Connection>
      <DesignerInfoPropertySet>
        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
      </DesignerInfoPropertySet>
    </edmx:Connection>
    <edmx:Options>
      <DesignerInfoPropertySet>
        <DesignerProperty Name="ValidateOnBuild" Value="true" />
      </DesignerInfoPropertySet>
    </edmx:Options>
    <!-- Diagram content (shape and connector positions) -->
    <edmx:Diagrams>
      <Diagram Name="NorthwindModel">
        <EntityTypeShape EntityType="northwindEFModel.Categories" Width="1.5" PointX="0.75" PointY="1.625" Height="1.9802864583333335" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Customers" Width="1.5" PointX="0.75" PointY="9.625" Height="3.3263964843749996" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Employees" Width="1.5" PointX="2.75" PointY="14.625" Height="4.4802050781250014" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.InternationalOrders" Width="1.5" PointX="5.25" PointY="10.375" Height="1.7879850260416674" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.OrderDetails" Width="1.5" PointX="5.25" PointY="1.5" Height="2.3648893229166656" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Orders" Width="1.5" PointX="3" PointY="9.25" Height="3.9033007812499996" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.PreviousEmployees" Width="1.5" PointX="7.75" PointY="0.75" Height="4.2879036458333317" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Products" Width="1.5" PointX="3" PointY="1" Height="3.3263964843749996" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Regions" Width="1.5" PointX="2.75" PointY="6" Height="1.5956835937499996" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Suppliers" Width="1.5" PointX="0.75" PointY="4.875" Height="3.5186979166666656" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Territories" Width="1.5" PointX="5" PointY="5.875" Height="1.7879850260416674" IsExpanded="true" />
        <AssociationConnector Association="northwindEFModel.FK_Products_CategoryID_CategoryID" ManuallyRouted="false">
          <ConnectorPoint PointX="2.25" PointY="2.6151432291666667" />
          <ConnectorPoint PointX="3" PointY="2.6151432291666667" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_Orders_CustomerID_CustomerID" ManuallyRouted="false">
          <ConnectorPoint PointX="2.25" PointY="11.2881982421875" />
          <ConnectorPoint PointX="3" PointY="11.2881982421875" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_InternationalOrders_OrderID_OrderID" ManuallyRouted="false">
          <ConnectorPoint PointX="4.5" PointY="11.268992513020834" />
          <ConnectorPoint PointX="5.010416666666667" PointY="11.268992513020834" />
          <ConnectorPoint PointX="5.177083333333333" PointY="11.268992513020834" />
          <ConnectorPoint PointX="5.25" PointY="11.268992513020834" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_OrderDetails_OrderID_OrderID" ManuallyRouted="false">
          <ConnectorPoint PointX="3.75" PointY="9.25" />
          <ConnectorPoint PointX="3.75" PointY="7.84568359375" />
          <ConnectorPoint PointX="4.75" PointY="7.84568359375" />
          <ConnectorPoint PointX="4.75" PointY="2.6824446614583328" />
          <ConnectorPoint PointX="5.25" PointY="2.6824446614583328" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_OrderDetails_ProductID_ProductID" ManuallyRouted="false">
          <ConnectorPoint PointX="4.5" PointY="2.0287223307291664" />
          <ConnectorPoint PointX="5.25" PointY="2.0287223307291664" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_Products_SupplierID_SupplierID" ManuallyRouted="false">
          <ConnectorPoint PointX="2.25" PointY="5.40625" />
          <ConnectorPoint PointX="4.40625" PointY="5.40625" />
          <ConnectorPoint PointX="4.40625" PointY="4.326396484375" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_Territories_RegionID_RegionID" ManuallyRouted="false">
          <ConnectorPoint PointX="4.25" PointY="6.797841796875" />
          <ConnectorPoint PointX="4.666666666666667" PointY="6.7978417968749989" />
          <ConnectorPoint PointX="4.833333333333333" PointY="6.797841796875" />
          <ConnectorPoint PointX="5" PointY="6.797841796875" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.EmployeesTerritories" ManuallyRouted="false">
          <ConnectorPoint PointX="4.25" PointY="16.8651025390625" />
          <ConnectorPoint PointX="5.09375" PointY="16.8651025390625" />
          <ConnectorPoint PointX="5.09375" PointY="7.6629850260416674" /></AssociationConnector>
        </Diagram></edmx:Diagrams>
  </edmx:Designer>
</edmx:Edmx>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted testlinq/NorthwindModel2010.Designer.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
/********************************************************
 * 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!
 ********************************************************/

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behavior in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Data.EntityClient;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Runtime.Serialization;

[assembly: EdmSchemaAttribute()]
#region EDM Relationship Metadata

[assembly: EdmRelationshipAttribute("northwindEFModel", "FK_Products_CategoryID_CategoryID", "Categories", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(testlinq.Categories), "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Products))]
[assembly: EdmRelationshipAttribute("northwindEFModel", "FK_Orders_CustomerID_CustomerID", "Customers", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(testlinq.Customers), "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Orders))]
[assembly: EdmRelationshipAttribute("northwindEFModel", "FK_InternationalOrders_OrderID_OrderID", "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(testlinq.Orders), "InternationalOrders", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(testlinq.InternationalOrders), true)]
[assembly: EdmRelationshipAttribute("northwindEFModel", "FK_OrderDetails_OrderID_OrderID", "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(testlinq.Orders), "OrderDetails", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.OrderDetails), true)]
[assembly: EdmRelationshipAttribute("northwindEFModel", "FK_OrderDetails_ProductID_ProductID", "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(testlinq.Products), "OrderDetails", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.OrderDetails), true)]
[assembly: EdmRelationshipAttribute("northwindEFModel", "FK_Products_SupplierID_SupplierID", "Suppliers", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(testlinq.Suppliers), "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Products))]
[assembly: EdmRelationshipAttribute("northwindEFModel", "FK_Territories_RegionID_RegionID", "Regions", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(testlinq.Regions), "Territories", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Territories))]
[assembly: EdmRelationshipAttribute("northwindEFModel", "EmployeesTerritories", "Employees", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Employees), "Territories", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(testlinq.Territories))]

#endregion

namespace testlinq
{
    #region Contexts
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    public partial class northwindEFEntities : ObjectContext
    {
        #region Constructors
    
        /// <summary>
        /// Initializes a new northwindEFEntities object using the connection string found in the 'northwindEFEntities' section of the application configuration file.
        /// </summary>
        public northwindEFEntities() : base("name=northwindEFEntities", "northwindEFEntities")
        {
            OnContextCreated();
        }
    
        /// <summary>
        /// Initialize a new northwindEFEntities object.
        /// </summary>
        public northwindEFEntities(string connectionString) : base(connectionString, "northwindEFEntities")
        {
            OnContextCreated();
        }
    
        /// <summary>
        /// Initialize a new northwindEFEntities object.
        /// </summary>
        public northwindEFEntities(EntityConnection connection) : base(connection, "northwindEFEntities")
        {
            OnContextCreated();
        }
    
        #endregion
    
        #region Partial Methods
    
        partial void OnContextCreated();
    
        #endregion
    
        #region ObjectSet Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Categories> Categories
        {
            get
            {
                if ((_Categories == null))
                {
                    _Categories = base.CreateObjectSet<Categories>("Categories");
                }
                return _Categories;
            }
        }
        private ObjectSet<Categories> _Categories;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Customers> Customers
        {
            get
            {
                if ((_Customers == null))
                {
                    _Customers = base.CreateObjectSet<Customers>("Customers");
                }
                return _Customers;
            }
        }
        private ObjectSet<Customers> _Customers;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Employees> Employees
        {
            get
            {
                if ((_Employees == null))
                {
                    _Employees = base.CreateObjectSet<Employees>("Employees");
                }
                return _Employees;
            }
        }
        private ObjectSet<Employees> _Employees;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<InternationalOrders> InternationalOrders
        {
            get
            {
                if ((_InternationalOrders == null))
                {
                    _InternationalOrders = base.CreateObjectSet<InternationalOrders>("InternationalOrders");
                }
                return _InternationalOrders;
            }
        }
        private ObjectSet<InternationalOrders> _InternationalOrders;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<OrderDetails> OrderDetails
        {
            get
            {
                if ((_OrderDetails == null))
                {
                    _OrderDetails = base.CreateObjectSet<OrderDetails>("OrderDetails");
                }
                return _OrderDetails;
            }
        }
        private ObjectSet<OrderDetails> _OrderDetails;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Orders> Orders
        {
            get
            {
                if ((_Orders == null))
                {
                    _Orders = base.CreateObjectSet<Orders>("Orders");
                }
                return _Orders;
            }
        }
        private ObjectSet<Orders> _Orders;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<PreviousEmployees> PreviousEmployees
        {
            get
            {
                if ((_PreviousEmployees == null))
                {
                    _PreviousEmployees = base.CreateObjectSet<PreviousEmployees>("PreviousEmployees");
                }
                return _PreviousEmployees;
            }
        }
        private ObjectSet<PreviousEmployees> _PreviousEmployees;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Products> Products
        {
            get
            {
                if ((_Products == null))
                {
                    _Products = base.CreateObjectSet<Products>("Products");
                }
                return _Products;
            }
        }
        private ObjectSet<Products> _Products;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Regions> Regions
        {
            get
            {
                if ((_Regions == null))
                {
                    _Regions = base.CreateObjectSet<Regions>("Regions");
                }
                return _Regions;
            }
        }
        private ObjectSet<Regions> _Regions;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Suppliers> Suppliers
        {
            get
            {
                if ((_Suppliers == null))
                {
                    _Suppliers = base.CreateObjectSet<Suppliers>("Suppliers");
                }
                return _Suppliers;
            }
        }
        private ObjectSet<Suppliers> _Suppliers;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Territories> Territories
        {
            get
            {
                if ((_Territories == null))
                {
                    _Territories = base.CreateObjectSet<Territories>("Territories");
                }
                return _Territories;
            }
        }
        private ObjectSet<Territories> _Territories;

        #endregion
        #region AddTo Methods
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Categories EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToCategories(Categories categories)
        {
            base.AddObject("Categories", categories);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Customers EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToCustomers(Customers customers)
        {
            base.AddObject("Customers", customers);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Employees EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToEmployees(Employees employees)
        {
            base.AddObject("Employees", employees);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the InternationalOrders EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToInternationalOrders(InternationalOrders internationalOrders)
        {
            base.AddObject("InternationalOrders", internationalOrders);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the OrderDetails EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToOrderDetails(OrderDetails orderDetails)
        {
            base.AddObject("OrderDetails", orderDetails);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Orders EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToOrders(Orders orders)
        {
            base.AddObject("Orders", orders);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the PreviousEmployees EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToPreviousEmployees(PreviousEmployees previousEmployees)
        {
            base.AddObject("PreviousEmployees", previousEmployees);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Products EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToProducts(Products products)
        {
            base.AddObject("Products", products);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Regions EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToRegions(Regions regions)
        {
            base.AddObject("Regions", regions);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Suppliers EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToSuppliers(Suppliers suppliers)
        {
            base.AddObject("Suppliers", suppliers);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Territories EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToTerritories(Territories territories)
        {
            base.AddObject("Territories", territories);
        }

        #endregion
    }
    

    #endregion
    
    #region Entities
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Categories")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Categories : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new Categories object.
        /// </summary>
        /// <param name="categoryID">Initial value of the CategoryID property.</param>
        /// <param name="categoryName">Initial value of the CategoryName property.</param>
        public static Categories CreateCategories(global::System.Int64 categoryID, global::System.String categoryName)
        {
            Categories categories = new Categories();
            categories.CategoryID = categoryID;
            categories.CategoryName = categoryName;
            return categories;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 CategoryID
        {
            get
            {
                return _CategoryID;
            }
            set
            {
                if (_CategoryID != value)
                {
                    OnCategoryIDChanging(value);
                    ReportPropertyChanging("CategoryID");
                    _CategoryID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("CategoryID");
                    OnCategoryIDChanged();
                }
            }
        }
        private global::System.Int64 _CategoryID;
        partial void OnCategoryIDChanging(global::System.Int64 value);
        partial void OnCategoryIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String CategoryName
        {
            get
            {
                return _CategoryName;
            }
            set
            {
                OnCategoryNameChanging(value);
                ReportPropertyChanging("CategoryName");
                _CategoryName = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("CategoryName");
                OnCategoryNameChanged();
            }
        }
        private global::System.String _CategoryName;
        partial void OnCategoryNameChanging(global::System.String value);
        partial void OnCategoryNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Description
        {
            get
            {
                return _Description;
            }
            set
            {
                OnDescriptionChanging(value);
                ReportPropertyChanging("Description");
                _Description = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Description");
                OnDescriptionChanged();
            }
        }
        private global::System.String _Description;
        partial void OnDescriptionChanging(global::System.String value);
        partial void OnDescriptionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.Byte[] Picture
        {
            get
            {
                return StructuralObject.GetValidValue(_Picture);
            }
            set
            {
                OnPictureChanging(value);
                ReportPropertyChanging("Picture");
                _Picture = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Picture");
                OnPictureChanged();
            }
        }
        private global::System.Byte[] _Picture;
        partial void OnPictureChanging(global::System.Byte[] value);
        partial void OnPictureChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Products_CategoryID_CategoryID", "Products")]
        public EntityCollection<Products> Products
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Products>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Products");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Products>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Products", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Customers")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Customers : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new Customers object.
        /// </summary>
        /// <param name="customerID">Initial value of the CustomerID property.</param>
        /// <param name="companyName">Initial value of the CompanyName property.</param>
        public static Customers CreateCustomers(global::System.String customerID, global::System.String companyName)
        {
            Customers customers = new Customers();
            customers.CustomerID = customerID;
            customers.CompanyName = companyName;
            return customers;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String CustomerID
        {
            get
            {
                return _CustomerID;
            }
            set
            {
                if (_CustomerID != value)
                {
                    OnCustomerIDChanging(value);
                    ReportPropertyChanging("CustomerID");
                    _CustomerID = StructuralObject.SetValidValue(value, false);
                    ReportPropertyChanged("CustomerID");
                    OnCustomerIDChanged();
                }
            }
        }
        private global::System.String _CustomerID;
        partial void OnCustomerIDChanging(global::System.String value);
        partial void OnCustomerIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String CompanyName
        {
            get
            {
                return _CompanyName;
            }
            set
            {
                OnCompanyNameChanging(value);
                ReportPropertyChanging("CompanyName");
                _CompanyName = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("CompanyName");
                OnCompanyNameChanged();
            }
        }
        private global::System.String _CompanyName;
        partial void OnCompanyNameChanging(global::System.String value);
        partial void OnCompanyNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ContactName
        {
            get
            {
                return _ContactName;
            }
            set
            {
                OnContactNameChanging(value);
                ReportPropertyChanging("ContactName");
                _ContactName = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ContactName");
                OnContactNameChanged();
            }
        }
        private global::System.String _ContactName;
        partial void OnContactNameChanging(global::System.String value);
        partial void OnContactNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ContactTitle
        {
            get
            {
                return _ContactTitle;
            }
            set
            {
                OnContactTitleChanging(value);
                ReportPropertyChanging("ContactTitle");
                _ContactTitle = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ContactTitle");
                OnContactTitleChanged();
            }
        }
        private global::System.String _ContactTitle;
        partial void OnContactTitleChanging(global::System.String value);
        partial void OnContactTitleChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Address
        {
            get
            {
                return _Address;
            }
            set
            {
                OnAddressChanging(value);
                ReportPropertyChanging("Address");
                _Address = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Address");
                OnAddressChanged();
            }
        }
        private global::System.String _Address;
        partial void OnAddressChanging(global::System.String value);
        partial void OnAddressChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String City
        {
            get
            {
                return _City;
            }
            set
            {
                OnCityChanging(value);
                ReportPropertyChanging("City");
                _City = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("City");
                OnCityChanged();
            }
        }
        private global::System.String _City;
        partial void OnCityChanging(global::System.String value);
        partial void OnCityChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Region
        {
            get
            {
                return _Region;
            }
            set
            {
                OnRegionChanging(value);
                ReportPropertyChanging("Region");
                _Region = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Region");
                OnRegionChanged();
            }
        }
        private global::System.String _Region;
        partial void OnRegionChanging(global::System.String value);
        partial void OnRegionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String PostalCode
        {
            get
            {
                return _PostalCode;
            }
            set
            {
                OnPostalCodeChanging(value);
                ReportPropertyChanging("PostalCode");
                _PostalCode = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("PostalCode");
                OnPostalCodeChanged();
            }
        }
        private global::System.String _PostalCode;
        partial void OnPostalCodeChanging(global::System.String value);
        partial void OnPostalCodeChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Country
        {
            get
            {
                return _Country;
            }
            set
            {
                OnCountryChanging(value);
                ReportPropertyChanging("Country");
                _Country = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Country");
                OnCountryChanged();
            }
        }
        private global::System.String _Country;
        partial void OnCountryChanging(global::System.String value);
        partial void OnCountryChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Phone
        {
            get
            {
                return _Phone;
            }
            set
            {
                OnPhoneChanging(value);
                ReportPropertyChanging("Phone");
                _Phone = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Phone");
                OnPhoneChanged();
            }
        }
        private global::System.String _Phone;
        partial void OnPhoneChanging(global::System.String value);
        partial void OnPhoneChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Fax
        {
            get
            {
                return _Fax;
            }
            set
            {
                OnFaxChanging(value);
                ReportPropertyChanging("Fax");
                _Fax = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Fax");
                OnFaxChanged();
            }
        }
        private global::System.String _Fax;
        partial void OnFaxChanging(global::System.String value);
        partial void OnFaxChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Orders_CustomerID_CustomerID", "Orders")]
        public EntityCollection<Orders> Orders
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Orders>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Orders");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Orders>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Orders", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Employees")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Employees : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new Employees object.
        /// </summary>
        /// <param name="employeeID">Initial value of the EmployeeID property.</param>
        /// <param name="lastName">Initial value of the LastName property.</param>
        /// <param name="firstName">Initial value of the FirstName property.</param>
        public static Employees CreateEmployees(global::System.Int64 employeeID, global::System.String lastName, global::System.String firstName)
        {
            Employees employees = new Employees();
            employees.EmployeeID = employeeID;
            employees.LastName = lastName;
            employees.FirstName = firstName;
            return employees;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 EmployeeID
        {
            get
            {
                return _EmployeeID;
            }
            set
            {
                if (_EmployeeID != value)
                {
                    OnEmployeeIDChanging(value);
                    ReportPropertyChanging("EmployeeID");
                    _EmployeeID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("EmployeeID");
                    OnEmployeeIDChanged();
                }
            }
        }
        private global::System.Int64 _EmployeeID;
        partial void OnEmployeeIDChanging(global::System.Int64 value);
        partial void OnEmployeeIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String LastName
        {
            get
            {
                return _LastName;
            }
            set
            {
                OnLastNameChanging(value);
                ReportPropertyChanging("LastName");
                _LastName = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("LastName");
                OnLastNameChanged();
            }
        }
        private global::System.String _LastName;
        partial void OnLastNameChanging(global::System.String value);
        partial void OnLastNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String FirstName
        {
            get
            {
                return _FirstName;
            }
            set
            {
                OnFirstNameChanging(value);
                ReportPropertyChanging("FirstName");
                _FirstName = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("FirstName");
                OnFirstNameChanged();
            }
        }
        private global::System.String _FirstName;
        partial void OnFirstNameChanging(global::System.String value);
        partial void OnFirstNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Title
        {
            get
            {
                return _Title;
            }
            set
            {
                OnTitleChanging(value);
                ReportPropertyChanging("Title");
                _Title = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Title");
                OnTitleChanged();
            }
        }
        private global::System.String _Title;
        partial void OnTitleChanging(global::System.String value);
        partial void OnTitleChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String TitleOfCourtesy
        {
            get
            {
                return _TitleOfCourtesy;
            }
            set
            {
                OnTitleOfCourtesyChanging(value);
                ReportPropertyChanging("TitleOfCourtesy");
                _TitleOfCourtesy = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("TitleOfCourtesy");
                OnTitleOfCourtesyChanged();
            }
        }
        private global::System.String _TitleOfCourtesy;
        partial void OnTitleOfCourtesyChanging(global::System.String value);
        partial void OnTitleOfCourtesyChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.DateTime> BirthDate
        {
            get
            {
                return _BirthDate;
            }
            set
            {
                OnBirthDateChanging(value);
                ReportPropertyChanging("BirthDate");
                _BirthDate = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("BirthDate");
                OnBirthDateChanged();
            }
        }
        private Nullable<global::System.DateTime> _BirthDate;
        partial void OnBirthDateChanging(Nullable<global::System.DateTime> value);
        partial void OnBirthDateChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.DateTime> HireDate
        {
            get
            {
                return _HireDate;
            }
            set
            {
                OnHireDateChanging(value);
                ReportPropertyChanging("HireDate");
                _HireDate = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("HireDate");
                OnHireDateChanged();
            }
        }
        private Nullable<global::System.DateTime> _HireDate;
        partial void OnHireDateChanging(Nullable<global::System.DateTime> value);
        partial void OnHireDateChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Address
        {
            get
            {
                return _Address;
            }
            set
            {
                OnAddressChanging(value);
                ReportPropertyChanging("Address");
                _Address = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Address");
                OnAddressChanged();
            }
        }
        private global::System.String _Address;
        partial void OnAddressChanging(global::System.String value);
        partial void OnAddressChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String City
        {
            get
            {
                return _City;
            }
            set
            {
                OnCityChanging(value);
                ReportPropertyChanging("City");
                _City = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("City");
                OnCityChanged();
            }
        }
        private global::System.String _City;
        partial void OnCityChanging(global::System.String value);
        partial void OnCityChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Region
        {
            get
            {
                return _Region;
            }
            set
            {
                OnRegionChanging(value);
                ReportPropertyChanging("Region");
                _Region = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Region");
                OnRegionChanged();
            }
        }
        private global::System.String _Region;
        partial void OnRegionChanging(global::System.String value);
        partial void OnRegionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String PostalCode
        {
            get
            {
                return _PostalCode;
            }
            set
            {
                OnPostalCodeChanging(value);
                ReportPropertyChanging("PostalCode");
                _PostalCode = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("PostalCode");
                OnPostalCodeChanged();
            }
        }
        private global::System.String _PostalCode;
        partial void OnPostalCodeChanging(global::System.String value);
        partial void OnPostalCodeChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Country
        {
            get
            {
                return _Country;
            }
            set
            {
                OnCountryChanging(value);
                ReportPropertyChanging("Country");
                _Country = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Country");
                OnCountryChanged();
            }
        }
        private global::System.String _Country;
        partial void OnCountryChanging(global::System.String value);
        partial void OnCountryChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String HomePhone
        {
            get
            {
                return _HomePhone;
            }
            set
            {
                OnHomePhoneChanging(value);
                ReportPropertyChanging("HomePhone");
                _HomePhone = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("HomePhone");
                OnHomePhoneChanged();
            }
        }
        private global::System.String _HomePhone;
        partial void OnHomePhoneChanging(global::System.String value);
        partial void OnHomePhoneChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Extension
        {
            get
            {
                return _Extension;
            }
            set
            {
                OnExtensionChanging(value);
                ReportPropertyChanging("Extension");
                _Extension = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Extension");
                OnExtensionChanged();
            }
        }
        private global::System.String _Extension;
        partial void OnExtensionChanging(global::System.String value);
        partial void OnExtensionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.Byte[] Photo
        {
            get
            {
                return StructuralObject.GetValidValue(_Photo);
            }
            set
            {
                OnPhotoChanging(value);
                ReportPropertyChanging("Photo");
                _Photo = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Photo");
                OnPhotoChanged();
            }
        }
        private global::System.Byte[] _Photo;
        partial void OnPhotoChanging(global::System.Byte[] value);
        partial void OnPhotoChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Notes
        {
            get
            {
                return _Notes;
            }
            set
            {
                OnNotesChanging(value);
                ReportPropertyChanging("Notes");
                _Notes = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Notes");
                OnNotesChanged();
            }
        }
        private global::System.String _Notes;
        partial void OnNotesChanging(global::System.String value);
        partial void OnNotesChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String PhotoPath
        {
            get
            {
                return _PhotoPath;
            }
            set
            {
                OnPhotoPathChanging(value);
                ReportPropertyChanging("PhotoPath");
                _PhotoPath = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("PhotoPath");
                OnPhotoPathChanged();
            }
        }
        private global::System.String _PhotoPath;
        partial void OnPhotoPathChanging(global::System.String value);
        partial void OnPhotoPathChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "EmployeesTerritories", "Territories")]
        public EntityCollection<Territories> Territories
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Territories>("northwindEFModel.EmployeesTerritories", "Territories");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Territories>("northwindEFModel.EmployeesTerritories", "Territories", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="InternationalOrders")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class InternationalOrders : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new InternationalOrders object.
        /// </summary>
        /// <param name="orderID">Initial value of the OrderID property.</param>
        /// <param name="customsDescription">Initial value of the CustomsDescription property.</param>
        /// <param name="exciseTax">Initial value of the ExciseTax property.</param>
        public static InternationalOrders CreateInternationalOrders(global::System.Int64 orderID, global::System.String customsDescription, global::System.Decimal exciseTax)
        {
            InternationalOrders internationalOrders = new InternationalOrders();
            internationalOrders.OrderID = orderID;
            internationalOrders.CustomsDescription = customsDescription;
            internationalOrders.ExciseTax = exciseTax;
            return internationalOrders;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 OrderID
        {
            get
            {
                return _OrderID;
            }
            set
            {
                if (_OrderID != value)
                {
                    OnOrderIDChanging(value);
                    ReportPropertyChanging("OrderID");
                    _OrderID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("OrderID");
                    OnOrderIDChanged();
                }
            }
        }
        private global::System.Int64 _OrderID;
        partial void OnOrderIDChanging(global::System.Int64 value);
        partial void OnOrderIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String CustomsDescription
        {
            get
            {
                return _CustomsDescription;
            }
            set
            {
                OnCustomsDescriptionChanging(value);
                ReportPropertyChanging("CustomsDescription");
                _CustomsDescription = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("CustomsDescription");
                OnCustomsDescriptionChanged();
            }
        }
        private global::System.String _CustomsDescription;
        partial void OnCustomsDescriptionChanging(global::System.String value);
        partial void OnCustomsDescriptionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Decimal ExciseTax
        {
            get
            {
                return _ExciseTax;
            }
            set
            {
                OnExciseTaxChanging(value);
                ReportPropertyChanging("ExciseTax");
                _ExciseTax = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("ExciseTax");
                OnExciseTaxChanged();
            }
        }
        private global::System.Decimal _ExciseTax;
        partial void OnExciseTaxChanging(global::System.Decimal value);
        partial void OnExciseTaxChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_InternationalOrders_OrderID_OrderID", "Orders")]
        public Orders Orders
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "Orders").Value;
            }
            set
            {
                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "Orders").Value = value;
            }
        }
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [BrowsableAttribute(false)]
        [DataMemberAttribute()]
        public EntityReference<Orders> OrdersReference
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "Orders");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Orders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "Orders", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="OrderDetails")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class OrderDetails : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new OrderDetails object.
        /// </summary>
        /// <param name="orderID">Initial value of the OrderID property.</param>
        /// <param name="productID">Initial value of the ProductID property.</param>
        /// <param name="unitPrice">Initial value of the UnitPrice property.</param>
        /// <param name="quantity">Initial value of the Quantity property.</param>
        /// <param name="discount">Initial value of the Discount property.</param>
        public static OrderDetails CreateOrderDetails(global::System.Int64 orderID, global::System.Int64 productID, global::System.Decimal unitPrice, global::System.Int16 quantity, global::System.Single discount)
        {
            OrderDetails orderDetails = new OrderDetails();
            orderDetails.OrderID = orderID;
            orderDetails.ProductID = productID;
            orderDetails.UnitPrice = unitPrice;
            orderDetails.Quantity = quantity;
            orderDetails.Discount = discount;
            return orderDetails;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 OrderID
        {
            get
            {
                return _OrderID;
            }
            set
            {
                if (_OrderID != value)
                {
                    OnOrderIDChanging(value);
                    ReportPropertyChanging("OrderID");
                    _OrderID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("OrderID");
                    OnOrderIDChanged();
                }
            }
        }
        private global::System.Int64 _OrderID;
        partial void OnOrderIDChanging(global::System.Int64 value);
        partial void OnOrderIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 ProductID
        {
            get
            {
                return _ProductID;
            }
            set
            {
                if (_ProductID != value)
                {
                    OnProductIDChanging(value);
                    ReportPropertyChanging("ProductID");
                    _ProductID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("ProductID");
                    OnProductIDChanged();
                }
            }
        }
        private global::System.Int64 _ProductID;
        partial void OnProductIDChanging(global::System.Int64 value);
        partial void OnProductIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Decimal UnitPrice
        {
            get
            {
                return _UnitPrice;
            }
            set
            {
                OnUnitPriceChanging(value);
                ReportPropertyChanging("UnitPrice");
                _UnitPrice = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("UnitPrice");
                OnUnitPriceChanged();
            }
        }
        private global::System.Decimal _UnitPrice;
        partial void OnUnitPriceChanging(global::System.Decimal value);
        partial void OnUnitPriceChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int16 Quantity
        {
            get
            {
                return _Quantity;
            }
            set
            {
                OnQuantityChanging(value);
                ReportPropertyChanging("Quantity");
                _Quantity = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("Quantity");
                OnQuantityChanged();
            }
        }
        private global::System.Int16 _Quantity;
        partial void OnQuantityChanging(global::System.Int16 value);
        partial void OnQuantityChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Single Discount
        {
            get
            {
                return _Discount;
            }
            set
            {
                OnDiscountChanging(value);
                ReportPropertyChanging("Discount");
                _Discount = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("Discount");
                OnDiscountChanged();
            }
        }
        private global::System.Single _Discount;
        partial void OnDiscountChanging(global::System.Single value);
        partial void OnDiscountChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_OrderDetails_OrderID_OrderID", "Orders")]
        public Orders Orders
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "Orders").Value;
            }
            set
            {
                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "Orders").Value = value;
            }
        }
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [BrowsableAttribute(false)]
        [DataMemberAttribute()]
        public EntityReference<Orders> OrdersReference
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Orders>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "Orders");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Orders>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "Orders", value);
                }
            }
        }
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_OrderDetails_ProductID_ProductID", "Products")]
        public Products Products
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Products>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "Products").Value;
            }
            set
            {
                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Products>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "Products").Value = value;
            }
        }
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [BrowsableAttribute(false)]
        [DataMemberAttribute()]
        public EntityReference<Products> ProductsReference
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Products>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "Products");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Products>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "Products", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Orders")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Orders : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new Orders object.
        /// </summary>
        /// <param name="orderID">Initial value of the OrderID property.</param>
        public static Orders CreateOrders(global::System.Int64 orderID)
        {
            Orders orders = new Orders();
            orders.OrderID = orderID;
            return orders;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 OrderID
        {
            get
            {
                return _OrderID;
            }
            set
            {
                if (_OrderID != value)
                {
                    OnOrderIDChanging(value);
                    ReportPropertyChanging("OrderID");
                    _OrderID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("OrderID");
                    OnOrderIDChanged();
                }
            }
        }
        private global::System.Int64 _OrderID;
        partial void OnOrderIDChanging(global::System.Int64 value);
        partial void OnOrderIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.Int64> EmployeeID
        {
            get
            {
                return _EmployeeID;
            }
            set
            {
                OnEmployeeIDChanging(value);
                ReportPropertyChanging("EmployeeID");
                _EmployeeID = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("EmployeeID");
                OnEmployeeIDChanged();
            }
        }
        private Nullable<global::System.Int64> _EmployeeID;
        partial void OnEmployeeIDChanging(Nullable<global::System.Int64> value);
        partial void OnEmployeeIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.DateTime> OrderDate
        {
            get
            {
                return _OrderDate;
            }
            set
            {
                OnOrderDateChanging(value);
                ReportPropertyChanging("OrderDate");
                _OrderDate = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("OrderDate");
                OnOrderDateChanged();
            }
        }
        private Nullable<global::System.DateTime> _OrderDate;
        partial void OnOrderDateChanging(Nullable<global::System.DateTime> value);
        partial void OnOrderDateChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.DateTime> RequiredDate
        {
            get
            {
                return _RequiredDate;
            }
            set
            {
                OnRequiredDateChanging(value);
                ReportPropertyChanging("RequiredDate");
                _RequiredDate = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("RequiredDate");
                OnRequiredDateChanged();
            }
        }
        private Nullable<global::System.DateTime> _RequiredDate;
        partial void OnRequiredDateChanging(Nullable<global::System.DateTime> value);
        partial void OnRequiredDateChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.DateTime> ShippedDate
        {
            get
            {
                return _ShippedDate;
            }
            set
            {
                OnShippedDateChanging(value);
                ReportPropertyChanging("ShippedDate");
                _ShippedDate = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("ShippedDate");
                OnShippedDateChanged();
            }
        }
        private Nullable<global::System.DateTime> _ShippedDate;
        partial void OnShippedDateChanging(Nullable<global::System.DateTime> value);
        partial void OnShippedDateChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.Decimal> Freight
        {
            get
            {
                return _Freight;
            }
            set
            {
                OnFreightChanging(value);
                ReportPropertyChanging("Freight");
                _Freight = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("Freight");
                OnFreightChanged();
            }
        }
        private Nullable<global::System.Decimal> _Freight;
        partial void OnFreightChanging(Nullable<global::System.Decimal> value);
        partial void OnFreightChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ShipName
        {
            get
            {
                return _ShipName;
            }
            set
            {
                OnShipNameChanging(value);
                ReportPropertyChanging("ShipName");
                _ShipName = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ShipName");
                OnShipNameChanged();
            }
        }
        private global::System.String _ShipName;
        partial void OnShipNameChanging(global::System.String value);
        partial void OnShipNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ShipAddress
        {
            get
            {
                return _ShipAddress;
            }
            set
            {
                OnShipAddressChanging(value);
                ReportPropertyChanging("ShipAddress");
                _ShipAddress = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ShipAddress");
                OnShipAddressChanged();
            }
        }
        private global::System.String _ShipAddress;
        partial void OnShipAddressChanging(global::System.String value);
        partial void OnShipAddressChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ShipCity
        {
            get
            {
                return _ShipCity;
            }
            set
            {
                OnShipCityChanging(value);
                ReportPropertyChanging("ShipCity");
                _ShipCity = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ShipCity");
                OnShipCityChanged();
            }
        }
        private global::System.String _ShipCity;
        partial void OnShipCityChanging(global::System.String value);
        partial void OnShipCityChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ShipRegion
        {
            get
            {
                return _ShipRegion;
            }
            set
            {
                OnShipRegionChanging(value);
                ReportPropertyChanging("ShipRegion");
                _ShipRegion = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ShipRegion");
                OnShipRegionChanged();
            }
        }
        private global::System.String _ShipRegion;
        partial void OnShipRegionChanging(global::System.String value);
        partial void OnShipRegionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ShipPostalCode
        {
            get
            {
                return _ShipPostalCode;
            }
            set
            {
                OnShipPostalCodeChanging(value);
                ReportPropertyChanging("ShipPostalCode");
                _ShipPostalCode = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ShipPostalCode");
                OnShipPostalCodeChanged();
            }
        }
        private global::System.String _ShipPostalCode;
        partial void OnShipPostalCodeChanging(global::System.String value);
        partial void OnShipPostalCodeChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ShipCountry
        {
            get
            {
                return _ShipCountry;
            }
            set
            {
                OnShipCountryChanging(value);
                ReportPropertyChanging("ShipCountry");
                _ShipCountry = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ShipCountry");
                OnShipCountryChanged();
            }
        }
        private global::System.String _ShipCountry;
        partial void OnShipCountryChanging(global::System.String value);
        partial void OnShipCountryChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Orders_CustomerID_CustomerID", "Customers")]
        public Customers Customers
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Customers>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Customers").Value;
            }
            set
            {
                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Customers>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Customers").Value = value;
            }
        }
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [BrowsableAttribute(false)]
        [DataMemberAttribute()]
        public EntityReference<Customers> CustomersReference
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Customers>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Customers");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Customers>("northwindEFModel.FK_Orders_CustomerID_CustomerID", "Customers", value);
                }
            }
        }
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_InternationalOrders_OrderID_OrderID", "InternationalOrders")]
        public InternationalOrders InternationalOrders
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<InternationalOrders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "InternationalOrders").Value;
            }
            set
            {
                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<InternationalOrders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "InternationalOrders").Value = value;
            }
        }
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [BrowsableAttribute(false)]
        [DataMemberAttribute()]
        public EntityReference<InternationalOrders> InternationalOrdersReference
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<InternationalOrders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "InternationalOrders");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<InternationalOrders>("northwindEFModel.FK_InternationalOrders_OrderID_OrderID", "InternationalOrders", value);
                }
            }
        }
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_OrderDetails_OrderID_OrderID", "OrderDetails")]
        public EntityCollection<OrderDetails> OrderDetails
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<OrderDetails>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "OrderDetails");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<OrderDetails>("northwindEFModel.FK_OrderDetails_OrderID_OrderID", "OrderDetails", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="PreviousEmployees")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class PreviousEmployees : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new PreviousEmployees object.
        /// </summary>
        /// <param name="employeeID">Initial value of the EmployeeID property.</param>
        /// <param name="lastName">Initial value of the LastName property.</param>
        /// <param name="firstName">Initial value of the FirstName property.</param>
        public static PreviousEmployees CreatePreviousEmployees(global::System.Int64 employeeID, global::System.String lastName, global::System.String firstName)
        {
            PreviousEmployees previousEmployees = new PreviousEmployees();
            previousEmployees.EmployeeID = employeeID;
            previousEmployees.LastName = lastName;
            previousEmployees.FirstName = firstName;
            return previousEmployees;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 EmployeeID
        {
            get
            {
                return _EmployeeID;
            }
            set
            {
                if (_EmployeeID != value)
                {
                    OnEmployeeIDChanging(value);
                    ReportPropertyChanging("EmployeeID");
                    _EmployeeID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("EmployeeID");
                    OnEmployeeIDChanged();
                }
            }
        }
        private global::System.Int64 _EmployeeID;
        partial void OnEmployeeIDChanging(global::System.Int64 value);
        partial void OnEmployeeIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String LastName
        {
            get
            {
                return _LastName;
            }
            set
            {
                OnLastNameChanging(value);
                ReportPropertyChanging("LastName");
                _LastName = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("LastName");
                OnLastNameChanged();
            }
        }
        private global::System.String _LastName;
        partial void OnLastNameChanging(global::System.String value);
        partial void OnLastNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String FirstName
        {
            get
            {
                return _FirstName;
            }
            set
            {
                OnFirstNameChanging(value);
                ReportPropertyChanging("FirstName");
                _FirstName = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("FirstName");
                OnFirstNameChanged();
            }
        }
        private global::System.String _FirstName;
        partial void OnFirstNameChanging(global::System.String value);
        partial void OnFirstNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Title
        {
            get
            {
                return _Title;
            }
            set
            {
                OnTitleChanging(value);
                ReportPropertyChanging("Title");
                _Title = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Title");
                OnTitleChanged();
            }
        }
        private global::System.String _Title;
        partial void OnTitleChanging(global::System.String value);
        partial void OnTitleChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String TitleOfCourtesy
        {
            get
            {
                return _TitleOfCourtesy;
            }
            set
            {
                OnTitleOfCourtesyChanging(value);
                ReportPropertyChanging("TitleOfCourtesy");
                _TitleOfCourtesy = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("TitleOfCourtesy");
                OnTitleOfCourtesyChanged();
            }
        }
        private global::System.String _TitleOfCourtesy;
        partial void OnTitleOfCourtesyChanging(global::System.String value);
        partial void OnTitleOfCourtesyChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.DateTime> BirthDate
        {
            get
            {
                return _BirthDate;
            }
            set
            {
                OnBirthDateChanging(value);
                ReportPropertyChanging("BirthDate");
                _BirthDate = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("BirthDate");
                OnBirthDateChanged();
            }
        }
        private Nullable<global::System.DateTime> _BirthDate;
        partial void OnBirthDateChanging(Nullable<global::System.DateTime> value);
        partial void OnBirthDateChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.DateTime> HireDate
        {
            get
            {
                return _HireDate;
            }
            set
            {
                OnHireDateChanging(value);
                ReportPropertyChanging("HireDate");
                _HireDate = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("HireDate");
                OnHireDateChanged();
            }
        }
        private Nullable<global::System.DateTime> _HireDate;
        partial void OnHireDateChanging(Nullable<global::System.DateTime> value);
        partial void OnHireDateChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Address
        {
            get
            {
                return _Address;
            }
            set
            {
                OnAddressChanging(value);
                ReportPropertyChanging("Address");
                _Address = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Address");
                OnAddressChanged();
            }
        }
        private global::System.String _Address;
        partial void OnAddressChanging(global::System.String value);
        partial void OnAddressChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String City
        {
            get
            {
                return _City;
            }
            set
            {
                OnCityChanging(value);
                ReportPropertyChanging("City");
                _City = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("City");
                OnCityChanged();
            }
        }
        private global::System.String _City;
        partial void OnCityChanging(global::System.String value);
        partial void OnCityChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Region
        {
            get
            {
                return _Region;
            }
            set
            {
                OnRegionChanging(value);
                ReportPropertyChanging("Region");
                _Region = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Region");
                OnRegionChanged();
            }
        }
        private global::System.String _Region;
        partial void OnRegionChanging(global::System.String value);
        partial void OnRegionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String PostalCode
        {
            get
            {
                return _PostalCode;
            }
            set
            {
                OnPostalCodeChanging(value);
                ReportPropertyChanging("PostalCode");
                _PostalCode = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("PostalCode");
                OnPostalCodeChanged();
            }
        }
        private global::System.String _PostalCode;
        partial void OnPostalCodeChanging(global::System.String value);
        partial void OnPostalCodeChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Country
        {
            get
            {
                return _Country;
            }
            set
            {
                OnCountryChanging(value);
                ReportPropertyChanging("Country");
                _Country = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Country");
                OnCountryChanged();
            }
        }
        private global::System.String _Country;
        partial void OnCountryChanging(global::System.String value);
        partial void OnCountryChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String HomePhone
        {
            get
            {
                return _HomePhone;
            }
            set
            {
                OnHomePhoneChanging(value);
                ReportPropertyChanging("HomePhone");
                _HomePhone = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("HomePhone");
                OnHomePhoneChanged();
            }
        }
        private global::System.String _HomePhone;
        partial void OnHomePhoneChanging(global::System.String value);
        partial void OnHomePhoneChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Extension
        {
            get
            {
                return _Extension;
            }
            set
            {
                OnExtensionChanging(value);
                ReportPropertyChanging("Extension");
                _Extension = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Extension");
                OnExtensionChanged();
            }
        }
        private global::System.String _Extension;
        partial void OnExtensionChanging(global::System.String value);
        partial void OnExtensionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.Byte[] Photo
        {
            get
            {
                return StructuralObject.GetValidValue(_Photo);
            }
            set
            {
                OnPhotoChanging(value);
                ReportPropertyChanging("Photo");
                _Photo = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Photo");
                OnPhotoChanged();
            }
        }
        private global::System.Byte[] _Photo;
        partial void OnPhotoChanging(global::System.Byte[] value);
        partial void OnPhotoChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Notes
        {
            get
            {
                return _Notes;
            }
            set
            {
                OnNotesChanging(value);
                ReportPropertyChanging("Notes");
                _Notes = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Notes");
                OnNotesChanged();
            }
        }
        private global::System.String _Notes;
        partial void OnNotesChanging(global::System.String value);
        partial void OnNotesChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String PhotoPath
        {
            get
            {
                return _PhotoPath;
            }
            set
            {
                OnPhotoPathChanging(value);
                ReportPropertyChanging("PhotoPath");
                _PhotoPath = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("PhotoPath");
                OnPhotoPathChanged();
            }
        }
        private global::System.String _PhotoPath;
        partial void OnPhotoPathChanging(global::System.String value);
        partial void OnPhotoPathChanged();

        #endregion
    
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Products")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Products : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new Products object.
        /// </summary>
        /// <param name="productID">Initial value of the ProductID property.</param>
        /// <param name="productName">Initial value of the ProductName property.</param>
        /// <param name="discontinued">Initial value of the Discontinued property.</param>
        public static Products CreateProducts(global::System.Int64 productID, global::System.String productName, global::System.Boolean discontinued)
        {
            Products products = new Products();
            products.ProductID = productID;
            products.ProductName = productName;
            products.Discontinued = discontinued;
            return products;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 ProductID
        {
            get
            {
                return _ProductID;
            }
            set
            {
                if (_ProductID != value)
                {
                    OnProductIDChanging(value);
                    ReportPropertyChanging("ProductID");
                    _ProductID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("ProductID");
                    OnProductIDChanged();
                }
            }
        }
        private global::System.Int64 _ProductID;
        partial void OnProductIDChanging(global::System.Int64 value);
        partial void OnProductIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String ProductName
        {
            get
            {
                return _ProductName;
            }
            set
            {
                OnProductNameChanging(value);
                ReportPropertyChanging("ProductName");
                _ProductName = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("ProductName");
                OnProductNameChanged();
            }
        }
        private global::System.String _ProductName;
        partial void OnProductNameChanging(global::System.String value);
        partial void OnProductNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String QuantityPerUnit
        {
            get
            {
                return _QuantityPerUnit;
            }
            set
            {
                OnQuantityPerUnitChanging(value);
                ReportPropertyChanging("QuantityPerUnit");
                _QuantityPerUnit = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("QuantityPerUnit");
                OnQuantityPerUnitChanged();
            }
        }
        private global::System.String _QuantityPerUnit;
        partial void OnQuantityPerUnitChanging(global::System.String value);
        partial void OnQuantityPerUnitChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.Decimal> UnitPrice
        {
            get
            {
                return _UnitPrice;
            }
            set
            {
                OnUnitPriceChanging(value);
                ReportPropertyChanging("UnitPrice");
                _UnitPrice = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("UnitPrice");
                OnUnitPriceChanged();
            }
        }
        private Nullable<global::System.Decimal> _UnitPrice;
        partial void OnUnitPriceChanging(Nullable<global::System.Decimal> value);
        partial void OnUnitPriceChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.Int16> UnitsInStock
        {
            get
            {
                return _UnitsInStock;
            }
            set
            {
                OnUnitsInStockChanging(value);
                ReportPropertyChanging("UnitsInStock");
                _UnitsInStock = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("UnitsInStock");
                OnUnitsInStockChanged();
            }
        }
        private Nullable<global::System.Int16> _UnitsInStock;
        partial void OnUnitsInStockChanging(Nullable<global::System.Int16> value);
        partial void OnUnitsInStockChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.Int16> UnitsOnOrder
        {
            get
            {
                return _UnitsOnOrder;
            }
            set
            {
                OnUnitsOnOrderChanging(value);
                ReportPropertyChanging("UnitsOnOrder");
                _UnitsOnOrder = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("UnitsOnOrder");
                OnUnitsOnOrderChanged();
            }
        }
        private Nullable<global::System.Int16> _UnitsOnOrder;
        partial void OnUnitsOnOrderChanging(Nullable<global::System.Int16> value);
        partial void OnUnitsOnOrderChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.Int16> ReorderLevel
        {
            get
            {
                return _ReorderLevel;
            }
            set
            {
                OnReorderLevelChanging(value);
                ReportPropertyChanging("ReorderLevel");
                _ReorderLevel = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("ReorderLevel");
                OnReorderLevelChanged();
            }
        }
        private Nullable<global::System.Int16> _ReorderLevel;
        partial void OnReorderLevelChanging(Nullable<global::System.Int16> value);
        partial void OnReorderLevelChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Boolean Discontinued
        {
            get
            {
                return _Discontinued;
            }
            set
            {
                OnDiscontinuedChanging(value);
                ReportPropertyChanging("Discontinued");
                _Discontinued = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("Discontinued");
                OnDiscontinuedChanged();
            }
        }
        private global::System.Boolean _Discontinued;
        partial void OnDiscontinuedChanging(global::System.Boolean value);
        partial void OnDiscontinuedChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public Nullable<global::System.DateTime> DiscontinuedDate
        {
            get
            {
                return _DiscontinuedDate;
            }
            set
            {
                OnDiscontinuedDateChanging(value);
                ReportPropertyChanging("DiscontinuedDate");
                _DiscontinuedDate = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("DiscontinuedDate");
                OnDiscontinuedDateChanged();
            }
        }
        private Nullable<global::System.DateTime> _DiscontinuedDate;
        partial void OnDiscontinuedDateChanging(Nullable<global::System.DateTime> value);
        partial void OnDiscontinuedDateChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Products_CategoryID_CategoryID", "Categories")]
        public Categories Categories
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Categories>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Categories").Value;
            }
            set
            {
                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Categories>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Categories").Value = value;
            }
        }
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [BrowsableAttribute(false)]
        [DataMemberAttribute()]
        public EntityReference<Categories> CategoriesReference
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Categories>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Categories");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Categories>("northwindEFModel.FK_Products_CategoryID_CategoryID", "Categories", value);
                }
            }
        }
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_OrderDetails_ProductID_ProductID", "OrderDetails")]
        public EntityCollection<OrderDetails> OrderDetails
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<OrderDetails>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "OrderDetails");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<OrderDetails>("northwindEFModel.FK_OrderDetails_ProductID_ProductID", "OrderDetails", value);
                }
            }
        }
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Products_SupplierID_SupplierID", "Suppliers")]
        public Suppliers Suppliers
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Suppliers>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Suppliers").Value;
            }
            set
            {
                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Suppliers>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Suppliers").Value = value;
            }
        }
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [BrowsableAttribute(false)]
        [DataMemberAttribute()]
        public EntityReference<Suppliers> SuppliersReference
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Suppliers>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Suppliers");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Suppliers>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Suppliers", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Regions")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Regions : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new Regions object.
        /// </summary>
        /// <param name="regionID">Initial value of the RegionID property.</param>
        /// <param name="regionDescription">Initial value of the RegionDescription property.</param>
        public static Regions CreateRegions(global::System.Int64 regionID, global::System.String regionDescription)
        {
            Regions regions = new Regions();
            regions.RegionID = regionID;
            regions.RegionDescription = regionDescription;
            return regions;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 RegionID
        {
            get
            {
                return _RegionID;
            }
            set
            {
                if (_RegionID != value)
                {
                    OnRegionIDChanging(value);
                    ReportPropertyChanging("RegionID");
                    _RegionID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("RegionID");
                    OnRegionIDChanged();
                }
            }
        }
        private global::System.Int64 _RegionID;
        partial void OnRegionIDChanging(global::System.Int64 value);
        partial void OnRegionIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String RegionDescription
        {
            get
            {
                return _RegionDescription;
            }
            set
            {
                OnRegionDescriptionChanging(value);
                ReportPropertyChanging("RegionDescription");
                _RegionDescription = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("RegionDescription");
                OnRegionDescriptionChanged();
            }
        }
        private global::System.String _RegionDescription;
        partial void OnRegionDescriptionChanging(global::System.String value);
        partial void OnRegionDescriptionChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Territories_RegionID_RegionID", "Territories")]
        public EntityCollection<Territories> Territories
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Territories>("northwindEFModel.FK_Territories_RegionID_RegionID", "Territories");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Territories>("northwindEFModel.FK_Territories_RegionID_RegionID", "Territories", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Suppliers")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Suppliers : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new Suppliers object.
        /// </summary>
        /// <param name="supplierID">Initial value of the SupplierID property.</param>
        /// <param name="companyName">Initial value of the CompanyName property.</param>
        public static Suppliers CreateSuppliers(global::System.Int64 supplierID, global::System.String companyName)
        {
            Suppliers suppliers = new Suppliers();
            suppliers.SupplierID = supplierID;
            suppliers.CompanyName = companyName;
            return suppliers;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 SupplierID
        {
            get
            {
                return _SupplierID;
            }
            set
            {
                if (_SupplierID != value)
                {
                    OnSupplierIDChanging(value);
                    ReportPropertyChanging("SupplierID");
                    _SupplierID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("SupplierID");
                    OnSupplierIDChanged();
                }
            }
        }
        private global::System.Int64 _SupplierID;
        partial void OnSupplierIDChanging(global::System.Int64 value);
        partial void OnSupplierIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String CompanyName
        {
            get
            {
                return _CompanyName;
            }
            set
            {
                OnCompanyNameChanging(value);
                ReportPropertyChanging("CompanyName");
                _CompanyName = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("CompanyName");
                OnCompanyNameChanged();
            }
        }
        private global::System.String _CompanyName;
        partial void OnCompanyNameChanging(global::System.String value);
        partial void OnCompanyNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ContactName
        {
            get
            {
                return _ContactName;
            }
            set
            {
                OnContactNameChanging(value);
                ReportPropertyChanging("ContactName");
                _ContactName = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ContactName");
                OnContactNameChanged();
            }
        }
        private global::System.String _ContactName;
        partial void OnContactNameChanging(global::System.String value);
        partial void OnContactNameChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String ContactTitle
        {
            get
            {
                return _ContactTitle;
            }
            set
            {
                OnContactTitleChanging(value);
                ReportPropertyChanging("ContactTitle");
                _ContactTitle = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("ContactTitle");
                OnContactTitleChanged();
            }
        }
        private global::System.String _ContactTitle;
        partial void OnContactTitleChanging(global::System.String value);
        partial void OnContactTitleChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Address
        {
            get
            {
                return _Address;
            }
            set
            {
                OnAddressChanging(value);
                ReportPropertyChanging("Address");
                _Address = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Address");
                OnAddressChanged();
            }
        }
        private global::System.String _Address;
        partial void OnAddressChanging(global::System.String value);
        partial void OnAddressChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String City
        {
            get
            {
                return _City;
            }
            set
            {
                OnCityChanging(value);
                ReportPropertyChanging("City");
                _City = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("City");
                OnCityChanged();
            }
        }
        private global::System.String _City;
        partial void OnCityChanging(global::System.String value);
        partial void OnCityChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Region
        {
            get
            {
                return _Region;
            }
            set
            {
                OnRegionChanging(value);
                ReportPropertyChanging("Region");
                _Region = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Region");
                OnRegionChanged();
            }
        }
        private global::System.String _Region;
        partial void OnRegionChanging(global::System.String value);
        partial void OnRegionChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String PostalCode
        {
            get
            {
                return _PostalCode;
            }
            set
            {
                OnPostalCodeChanging(value);
                ReportPropertyChanging("PostalCode");
                _PostalCode = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("PostalCode");
                OnPostalCodeChanged();
            }
        }
        private global::System.String _PostalCode;
        partial void OnPostalCodeChanging(global::System.String value);
        partial void OnPostalCodeChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Country
        {
            get
            {
                return _Country;
            }
            set
            {
                OnCountryChanging(value);
                ReportPropertyChanging("Country");
                _Country = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Country");
                OnCountryChanged();
            }
        }
        private global::System.String _Country;
        partial void OnCountryChanging(global::System.String value);
        partial void OnCountryChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Phone
        {
            get
            {
                return _Phone;
            }
            set
            {
                OnPhoneChanging(value);
                ReportPropertyChanging("Phone");
                _Phone = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Phone");
                OnPhoneChanged();
            }
        }
        private global::System.String _Phone;
        partial void OnPhoneChanging(global::System.String value);
        partial void OnPhoneChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String Fax
        {
            get
            {
                return _Fax;
            }
            set
            {
                OnFaxChanging(value);
                ReportPropertyChanging("Fax");
                _Fax = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("Fax");
                OnFaxChanged();
            }
        }
        private global::System.String _Fax;
        partial void OnFaxChanging(global::System.String value);
        partial void OnFaxChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
        [DataMemberAttribute()]
        public global::System.String HomePage
        {
            get
            {
                return _HomePage;
            }
            set
            {
                OnHomePageChanging(value);
                ReportPropertyChanging("HomePage");
                _HomePage = StructuralObject.SetValidValue(value, true);
                ReportPropertyChanged("HomePage");
                OnHomePageChanged();
            }
        }
        private global::System.String _HomePage;
        partial void OnHomePageChanging(global::System.String value);
        partial void OnHomePageChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Products_SupplierID_SupplierID", "Products")]
        public EntityCollection<Products> Products
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Products>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Products");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Products>("northwindEFModel.FK_Products_SupplierID_SupplierID", "Products", value);
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="northwindEFModel", Name="Territories")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Territories : EntityObject
    {
        #region Factory Method
    
        /// <summary>
        /// Create a new Territories object.
        /// </summary>
        /// <param name="territoryID">Initial value of the TerritoryID property.</param>
        /// <param name="territoryDescription">Initial value of the TerritoryDescription property.</param>
        public static Territories CreateTerritories(global::System.Int64 territoryID, global::System.String territoryDescription)
        {
            Territories territories = new Territories();
            territories.TerritoryID = territoryID;
            territories.TerritoryDescription = territoryDescription;
            return territories;
        }

        #endregion
        #region Primitive Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int64 TerritoryID
        {
            get
            {
                return _TerritoryID;
            }
            set
            {
                if (_TerritoryID != value)
                {
                    OnTerritoryIDChanging(value);
                    ReportPropertyChanging("TerritoryID");
                    _TerritoryID = StructuralObject.SetValidValue(value);
                    ReportPropertyChanged("TerritoryID");
                    OnTerritoryIDChanged();
                }
            }
        }
        private global::System.Int64 _TerritoryID;
        partial void OnTerritoryIDChanging(global::System.Int64 value);
        partial void OnTerritoryIDChanged();
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String TerritoryDescription
        {
            get
            {
                return _TerritoryDescription;
            }
            set
            {
                OnTerritoryDescriptionChanging(value);
                ReportPropertyChanging("TerritoryDescription");
                _TerritoryDescription = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("TerritoryDescription");
                OnTerritoryDescriptionChanged();
            }
        }
        private global::System.String _TerritoryDescription;
        partial void OnTerritoryDescriptionChanging(global::System.String value);
        partial void OnTerritoryDescriptionChanged();

        #endregion
    
        #region Navigation Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "FK_Territories_RegionID_RegionID", "Regions")]
        public Regions Regions
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Regions>("northwindEFModel.FK_Territories_RegionID_RegionID", "Regions").Value;
            }
            set
            {
                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Regions>("northwindEFModel.FK_Territories_RegionID_RegionID", "Regions").Value = value;
            }
        }
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [BrowsableAttribute(false)]
        [DataMemberAttribute()]
        public EntityReference<Regions> RegionsReference
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Regions>("northwindEFModel.FK_Territories_RegionID_RegionID", "Regions");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Regions>("northwindEFModel.FK_Territories_RegionID_RegionID", "Regions", value);
                }
            }
        }
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        [XmlIgnoreAttribute()]
        [SoapIgnoreAttribute()]
        [DataMemberAttribute()]
        [EdmRelationshipNavigationPropertyAttribute("northwindEFModel", "EmployeesTerritories", "Employees")]
        public EntityCollection<Employees> Employees
        {
            get
            {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Employees>("northwindEFModel.EmployeesTerritories", "Employees");
            }
            set
            {
                if ((value != null))
                {
                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Employees>("northwindEFModel.EmployeesTerritories", "Employees", value);
                }
            }
        }

        #endregion
    }

    #endregion
    
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted testlinq/NorthwindModel2010.edmx.
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
<?xml version="1.0" encoding="utf-8"?>

<!--
/********************************************************
 * 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!
 ********************************************************/
-->

<edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
  <!-- EF Runtime content -->
  <edmx:Runtime>
    <!-- SSDL content -->
    <edmx:StorageModels>
    <Schema Namespace="northwindEFModel.Store" Alias="Self" Provider="System.Data.SQLite" ProviderManifestToken="ISO8601" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
        <EntityContainer Name="northwindEFModelStoreContainer">
          <EntitySet Name="Categories" EntityType="northwindEFModel.Store.Categories" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="Customers" EntityType="northwindEFModel.Store.Customers" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="Employees" EntityType="northwindEFModel.Store.Employees" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="EmployeesTerritories" EntityType="northwindEFModel.Store.EmployeesTerritories" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="InternationalOrders" EntityType="northwindEFModel.Store.InternationalOrders" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="OrderDetails" EntityType="northwindEFModel.Store.OrderDetails" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="Orders" EntityType="northwindEFModel.Store.Orders" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="PreviousEmployees" EntityType="northwindEFModel.Store.PreviousEmployees" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="Products" EntityType="northwindEFModel.Store.Products" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="Regions" EntityType="northwindEFModel.Store.Regions" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="Suppliers" EntityType="northwindEFModel.Store.Suppliers" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <EntitySet Name="Territories" EntityType="northwindEFModel.Store.Territories" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
          <AssociationSet Name="FK_EmployeesTerritories_EmployeeID_EmployeeID" Association="northwindEFModel.Store.FK_EmployeesTerritories_EmployeeID_EmployeeID">
            <End Role="Employees" EntitySet="Employees" />
            <End Role="EmployeesTerritories" EntitySet="EmployeesTerritories" />
          </AssociationSet>
          <AssociationSet Name="FK_EmployeesTerritories_TerritoryID_TerritoryID" Association="northwindEFModel.Store.FK_EmployeesTerritories_TerritoryID_TerritoryID">
            <End Role="Territories" EntitySet="Territories" />
            <End Role="EmployeesTerritories" EntitySet="EmployeesTerritories" />
          </AssociationSet>
          <AssociationSet Name="FK_InternationalOrders_OrderID_OrderID" Association="northwindEFModel.Store.FK_InternationalOrders_OrderID_OrderID">
            <End Role="Orders" EntitySet="Orders" />
            <End Role="InternationalOrders" EntitySet="InternationalOrders" />
          </AssociationSet>
          <AssociationSet Name="FK_OrderDetails_OrderID_OrderID" Association="northwindEFModel.Store.FK_OrderDetails_OrderID_OrderID">
            <End Role="Orders" EntitySet="Orders" />
            <End Role="OrderDetails" EntitySet="OrderDetails" />
          </AssociationSet>
          <AssociationSet Name="FK_OrderDetails_ProductID_ProductID" Association="northwindEFModel.Store.FK_OrderDetails_ProductID_ProductID">
            <End Role="Products" EntitySet="Products" />
            <End Role="OrderDetails" EntitySet="OrderDetails" />
          </AssociationSet>
          <AssociationSet Name="FK_Orders_CustomerID_CustomerID" Association="northwindEFModel.Store.FK_Orders_CustomerID_CustomerID">
            <End Role="Customers" EntitySet="Customers" />
            <End Role="Orders" EntitySet="Orders" />
          </AssociationSet>
          <AssociationSet Name="FK_Products_CategoryID_CategoryID" Association="northwindEFModel.Store.FK_Products_CategoryID_CategoryID">
            <End Role="Categories" EntitySet="Categories" />
            <End Role="Products" EntitySet="Products" />
          </AssociationSet>
          <AssociationSet Name="FK_Products_SupplierID_SupplierID" Association="northwindEFModel.Store.FK_Products_SupplierID_SupplierID">
            <End Role="Suppliers" EntitySet="Suppliers" />
            <End Role="Products" EntitySet="Products" />
          </AssociationSet>
          <AssociationSet Name="FK_Territories_RegionID_RegionID" Association="northwindEFModel.Store.FK_Territories_RegionID_RegionID">
            <End Role="Regions" EntitySet="Regions" />
            <End Role="Territories" EntitySet="Territories" />
          </AssociationSet>
        </EntityContainer>
        <EntityType Name="Categories">
          <Key>
            <PropertyRef Name="CategoryID" />
          </Key>
          <Property Name="CategoryID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="CategoryName" Type="nvarchar" Nullable="false" MaxLength="15" />
          <Property Name="Description" Type="nvarchar" />
          <Property Name="Picture" Type="blob" />
        </EntityType>
        <EntityType Name="Customers">
          <Key>
            <PropertyRef Name="CustomerID" />
          </Key>
          <Property Name="CustomerID" Type="nvarchar" Nullable="false" MaxLength="5" />
          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
          <Property Name="ContactName" Type="nvarchar" MaxLength="30" />
          <Property Name="ContactTitle" Type="nvarchar" MaxLength="30" />
          <Property Name="Address" Type="nvarchar" MaxLength="60" />
          <Property Name="City" Type="nvarchar" MaxLength="15" />
          <Property Name="Region" Type="nvarchar" MaxLength="15" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="Country" Type="nvarchar" MaxLength="15" />
          <Property Name="Phone" Type="nvarchar" MaxLength="24" />
          <Property Name="Fax" Type="nvarchar" MaxLength="24" />
        </EntityType>
        <EntityType Name="Employees">
          <Key>
            <PropertyRef Name="EmployeeID" />
          </Key>
          <Property Name="EmployeeID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="20" />
          <Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="10" />
          <Property Name="Title" Type="nvarchar" MaxLength="30" />
          <Property Name="TitleOfCourtesy" Type="nvarchar" MaxLength="25" />
          <Property Name="BirthDate" Type="datetime" />
          <Property Name="HireDate" Type="datetime" />
          <Property Name="Address" Type="nvarchar" MaxLength="60" />
          <Property Name="City" Type="nvarchar" MaxLength="15" />
          <Property Name="Region" Type="nvarchar" MaxLength="15" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="Country" Type="nvarchar" MaxLength="15" />
          <Property Name="HomePhone" Type="nvarchar" MaxLength="24" />
          <Property Name="Extension" Type="nvarchar" MaxLength="4" />
          <Property Name="Photo" Type="blob" />
          <Property Name="Notes" Type="nvarchar" />
          <Property Name="PhotoPath" Type="nvarchar" MaxLength="255" />
        </EntityType>
        <EntityType Name="EmployeesTerritories">
          <Key>
            <PropertyRef Name="EmployeeID" />
            <PropertyRef Name="TerritoryID" />
          </Key>
          <Property Name="EmployeeID" Type="integer" Nullable="false" />
          <Property Name="TerritoryID" Type="integer" Nullable="false" />
        </EntityType>
        <EntityType Name="InternationalOrders">
          <Key>
            <PropertyRef Name="OrderID" />
          </Key>
          <Property Name="OrderID" Type="integer" Nullable="false" />
          <Property Name="CustomsDescription" Type="nvarchar" Nullable="false" MaxLength="100" />
          <Property Name="ExciseTax" Type="decimal" Nullable="false" Precision="53" />
        </EntityType>
        <EntityType Name="OrderDetails">
          <Key>
            <PropertyRef Name="OrderID" />
            <PropertyRef Name="ProductID" />
          </Key>
          <Property Name="OrderID" Type="integer" Nullable="false" />
          <Property Name="ProductID" Type="integer" Nullable="false" />
          <Property Name="UnitPrice" Type="decimal" Nullable="false" Precision="53" />
          <Property Name="Quantity" Type="smallint" Nullable="false" />
          <Property Name="Discount" Type="real" Nullable="false" />
        </EntityType>
        <EntityType Name="Orders">
          <Key>
            <PropertyRef Name="OrderID" />
          </Key>
          <Property Name="OrderID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="CustomerID" Type="nvarchar" MaxLength="5" />
          <Property Name="EmployeeID" Type="integer" />
          <Property Name="OrderDate" Type="datetime" />
          <Property Name="RequiredDate" Type="datetime" />
          <Property Name="ShippedDate" Type="datetime" />
          <Property Name="Freight" Type="decimal" Precision="53" />
          <Property Name="ShipName" Type="nvarchar" MaxLength="40" />
          <Property Name="ShipAddress" Type="nvarchar" MaxLength="60" />
          <Property Name="ShipCity" Type="nvarchar" MaxLength="15" />
          <Property Name="ShipRegion" Type="nvarchar" MaxLength="15" />
          <Property Name="ShipPostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="ShipCountry" Type="nvarchar" MaxLength="15" />
        </EntityType>
        <EntityType Name="PreviousEmployees">
          <Key>
            <PropertyRef Name="EmployeeID" />
          </Key>
          <Property Name="EmployeeID" Type="integer" Nullable="false" />
          <Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="20" />
          <Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="10" />
          <Property Name="Title" Type="nvarchar" MaxLength="30" />
          <Property Name="TitleOfCourtesy" Type="nvarchar" MaxLength="25" />
          <Property Name="BirthDate" Type="datetime" />
          <Property Name="HireDate" Type="datetime" />
          <Property Name="Address" Type="nvarchar" MaxLength="60" />
          <Property Name="City" Type="nvarchar" MaxLength="15" />
          <Property Name="Region" Type="nvarchar" MaxLength="15" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="Country" Type="nvarchar" MaxLength="15" />
          <Property Name="HomePhone" Type="nvarchar" MaxLength="24" />
          <Property Name="Extension" Type="nvarchar" MaxLength="4" />
          <Property Name="Photo" Type="blob" />
          <Property Name="Notes" Type="nvarchar" />
          <Property Name="PhotoPath" Type="nvarchar" MaxLength="255" />
        </EntityType>
        <EntityType Name="Products">
          <Key>
            <PropertyRef Name="ProductID" />
          </Key>
          <Property Name="ProductID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
          <Property Name="SupplierID" Type="integer" />
          <Property Name="CategoryID" Type="integer" />
          <Property Name="QuantityPerUnit" Type="nvarchar" MaxLength="20" />
          <Property Name="UnitPrice" Type="decimal" Precision="53" />
          <Property Name="UnitsInStock" Type="smallint" />
          <Property Name="UnitsOnOrder" Type="smallint" />
          <Property Name="ReorderLevel" Type="smallint" />
          <Property Name="Discontinued" Type="bit" Nullable="false" />
          <Property Name="DiscontinuedDate" Type="datetime" />
        </EntityType>
        <EntityType Name="Regions">
          <Key>
            <PropertyRef Name="RegionID" />
          </Key>
          <Property Name="RegionID" Type="integer" Nullable="false" />
          <Property Name="RegionDescription" Type="nvarchar" Nullable="false" MaxLength="50" />
        </EntityType>
        <EntityType Name="Suppliers">
          <Key>
            <PropertyRef Name="SupplierID" />
          </Key>
          <Property Name="SupplierID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
          <Property Name="ContactName" Type="nvarchar" MaxLength="30" />
          <Property Name="ContactTitle" Type="nvarchar" MaxLength="30" />
          <Property Name="Address" Type="nvarchar" MaxLength="60" />
          <Property Name="City" Type="nvarchar" MaxLength="15" />
          <Property Name="Region" Type="nvarchar" MaxLength="15" />
          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
          <Property Name="Country" Type="nvarchar" MaxLength="15" />
          <Property Name="Phone" Type="nvarchar" MaxLength="24" />
          <Property Name="Fax" Type="nvarchar" MaxLength="24" />
          <Property Name="HomePage" Type="nvarchar" />
        </EntityType>
        <EntityType Name="Territories">
          <Key>
            <PropertyRef Name="TerritoryID" />
          </Key>
          <Property Name="TerritoryID" Type="integer" Nullable="false" />
          <Property Name="TerritoryDescription" Type="nvarchar" Nullable="false" MaxLength="50" />
          <Property Name="RegionID" Type="integer" Nullable="false" />
        </EntityType>
        <Association Name="FK_EmployeesTerritories_EmployeeID_EmployeeID">
          <End Role="Employees" Type="northwindEFModel.Store.Employees" Multiplicity="1" />
          <End Role="EmployeesTerritories" Type="northwindEFModel.Store.EmployeesTerritories" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Employees">
              <PropertyRef Name="EmployeeID" />
            </Principal>
            <Dependent Role="EmployeesTerritories">
              <PropertyRef Name="EmployeeID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_EmployeesTerritories_TerritoryID_TerritoryID">
          <End Role="Territories" Type="northwindEFModel.Store.Territories" Multiplicity="1" />
          <End Role="EmployeesTerritories" Type="northwindEFModel.Store.EmployeesTerritories" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Territories">
              <PropertyRef Name="TerritoryID" />
            </Principal>
            <Dependent Role="EmployeesTerritories">
              <PropertyRef Name="TerritoryID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_InternationalOrders_OrderID_OrderID">
          <End Role="Orders" Type="northwindEFModel.Store.Orders" Multiplicity="1" />
          <End Role="InternationalOrders" Type="northwindEFModel.Store.InternationalOrders" Multiplicity="0..1" />
          <ReferentialConstraint>
            <Principal Role="Orders">
              <PropertyRef Name="OrderID" />
            </Principal>
            <Dependent Role="InternationalOrders">
              <PropertyRef Name="OrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_OrderDetails_OrderID_OrderID">
          <End Role="Orders" Type="northwindEFModel.Store.Orders" Multiplicity="1" />
          <End Role="OrderDetails" Type="northwindEFModel.Store.OrderDetails" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Orders">
              <PropertyRef Name="OrderID" />
            </Principal>
            <Dependent Role="OrderDetails">
              <PropertyRef Name="OrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_OrderDetails_ProductID_ProductID">
          <End Role="Products" Type="northwindEFModel.Store.Products" Multiplicity="1" />
          <End Role="OrderDetails" Type="northwindEFModel.Store.OrderDetails" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Products">
              <PropertyRef Name="ProductID" />
            </Principal>
            <Dependent Role="OrderDetails">
              <PropertyRef Name="ProductID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Orders_CustomerID_CustomerID">
          <End Role="Customers" Type="northwindEFModel.Store.Customers" Multiplicity="0..1" />
          <End Role="Orders" Type="northwindEFModel.Store.Orders" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Customers">
              <PropertyRef Name="CustomerID" />
            </Principal>
            <Dependent Role="Orders">
              <PropertyRef Name="CustomerID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Products_CategoryID_CategoryID">
          <End Role="Categories" Type="northwindEFModel.Store.Categories" Multiplicity="0..1" />
          <End Role="Products" Type="northwindEFModel.Store.Products" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Categories">
              <PropertyRef Name="CategoryID" />
            </Principal>
            <Dependent Role="Products">
              <PropertyRef Name="CategoryID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Products_SupplierID_SupplierID">
          <End Role="Suppliers" Type="northwindEFModel.Store.Suppliers" Multiplicity="0..1" />
          <End Role="Products" Type="northwindEFModel.Store.Products" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Suppliers">
              <PropertyRef Name="SupplierID" />
            </Principal>
            <Dependent Role="Products">
              <PropertyRef Name="SupplierID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Territories_RegionID_RegionID">
          <End Role="Regions" Type="northwindEFModel.Store.Regions" Multiplicity="1" />
          <End Role="Territories" Type="northwindEFModel.Store.Territories" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Regions">
              <PropertyRef Name="RegionID" />
            </Principal>
            <Dependent Role="Territories">
              <PropertyRef Name="RegionID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
      </Schema></edmx:StorageModels>
    <!-- CSDL content -->
    <edmx:ConceptualModels>
      <Schema Namespace="northwindEFModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
        <EntityContainer Name="northwindEFEntities">
          <EntitySet Name="Categories" EntityType="northwindEFModel.Categories" />
          <EntitySet Name="Customers" EntityType="northwindEFModel.Customers" />
          <EntitySet Name="Employees" EntityType="northwindEFModel.Employees" />
          <EntitySet Name="InternationalOrders" EntityType="northwindEFModel.InternationalOrders" />
          <EntitySet Name="OrderDetails" EntityType="northwindEFModel.OrderDetails" />
          <EntitySet Name="Orders" EntityType="northwindEFModel.Orders" />
          <EntitySet Name="PreviousEmployees" EntityType="northwindEFModel.PreviousEmployees" />
          <EntitySet Name="Products" EntityType="northwindEFModel.Products" />
          <EntitySet Name="Regions" EntityType="northwindEFModel.Regions" />
          <EntitySet Name="Suppliers" EntityType="northwindEFModel.Suppliers" />
          <EntitySet Name="Territories" EntityType="northwindEFModel.Territories" />
          <AssociationSet Name="FK_Products_CategoryID_CategoryID" Association="northwindEFModel.FK_Products_CategoryID_CategoryID">
            <End Role="Categories" EntitySet="Categories" />
            <End Role="Products" EntitySet="Products" />
          </AssociationSet>
          <AssociationSet Name="FK_Orders_CustomerID_CustomerID" Association="northwindEFModel.FK_Orders_CustomerID_CustomerID">
            <End Role="Customers" EntitySet="Customers" />
            <End Role="Orders" EntitySet="Orders" />
          </AssociationSet>
          <AssociationSet Name="FK_InternationalOrders_OrderID_OrderID" Association="northwindEFModel.FK_InternationalOrders_OrderID_OrderID">
            <End Role="Orders" EntitySet="Orders" />
            <End Role="InternationalOrders" EntitySet="InternationalOrders" />
          </AssociationSet>
          <AssociationSet Name="FK_OrderDetails_OrderID_OrderID" Association="northwindEFModel.FK_OrderDetails_OrderID_OrderID">
            <End Role="Orders" EntitySet="Orders" />
            <End Role="OrderDetails" EntitySet="OrderDetails" />
          </AssociationSet>
          <AssociationSet Name="FK_OrderDetails_ProductID_ProductID" Association="northwindEFModel.FK_OrderDetails_ProductID_ProductID">
            <End Role="Products" EntitySet="Products" />
            <End Role="OrderDetails" EntitySet="OrderDetails" />
          </AssociationSet>
          <AssociationSet Name="FK_Products_SupplierID_SupplierID" Association="northwindEFModel.FK_Products_SupplierID_SupplierID">
            <End Role="Suppliers" EntitySet="Suppliers" />
            <End Role="Products" EntitySet="Products" />
          </AssociationSet>
          <AssociationSet Name="FK_Territories_RegionID_RegionID" Association="northwindEFModel.FK_Territories_RegionID_RegionID">
            <End Role="Regions" EntitySet="Regions" />
            <End Role="Territories" EntitySet="Territories" />
          </AssociationSet>
          <AssociationSet Name="EmployeesTerritories" Association="northwindEFModel.EmployeesTerritories">
            <End Role="Employees" EntitySet="Employees" />
            <End Role="Territories" EntitySet="Territories" />
          </AssociationSet>
          </EntityContainer>
        <EntityType Name="Categories">
          <Key>
            <PropertyRef Name="CategoryID" />
          </Key>
          <Property Name="CategoryID" Type="Int64" Nullable="false" />
          <Property Name="CategoryName" Type="String" Nullable="false" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Description" Type="String" MaxLength="2147483647" Unicode="true" FixedLength="false" />
          <Property Name="Picture" Type="Binary" MaxLength="2147483647" FixedLength="false" />
          <NavigationProperty Name="Products" Relationship="northwindEFModel.FK_Products_CategoryID_CategoryID" FromRole="Categories" ToRole="Products" />
        </EntityType>
        <EntityType Name="Customers">
          <Key>
            <PropertyRef Name="CustomerID" />
          </Key>
          <Property Name="CustomerID" Type="String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="false" />
          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
          <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Orders" Relationship="northwindEFModel.FK_Orders_CustomerID_CustomerID" FromRole="Customers" ToRole="Orders" />
        </EntityType>
        <EntityType Name="Employees">
          <Key>
            <PropertyRef Name="EmployeeID" />
          </Key>
          <Property Name="EmployeeID" Type="Int64" Nullable="false" />
          <Property Name="LastName" Type="String" Nullable="false" MaxLength="20" Unicode="true" FixedLength="false" />
          <Property Name="FirstName" Type="String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Title" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="TitleOfCourtesy" Type="String" MaxLength="25" Unicode="true" FixedLength="false" />
          <Property Name="BirthDate" Type="DateTime" />
          <Property Name="HireDate" Type="DateTime" />
          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="HomePhone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="Extension" Type="String" MaxLength="4" Unicode="true" FixedLength="false" />
          <Property Name="Photo" Type="Binary" MaxLength="2147483647" FixedLength="false" />
          <Property Name="Notes" Type="String" MaxLength="2147483647" Unicode="true" FixedLength="false" />
          <Property Name="PhotoPath" Type="String" MaxLength="255" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Territories" Relationship="northwindEFModel.EmployeesTerritories" FromRole="Employees" ToRole="Territories" />
        </EntityType>
        <EntityType Name="InternationalOrders">
          <Key>
            <PropertyRef Name="OrderID" />
          </Key>
          <Property Name="OrderID" Type="Int64" Nullable="false" />
          <Property Name="CustomsDescription" Type="String" Nullable="false" MaxLength="100" Unicode="true" FixedLength="false" />
          <Property Name="ExciseTax" Type="Decimal" Nullable="false" Precision="53" Scale="0" />
          <NavigationProperty Name="Orders" Relationship="northwindEFModel.FK_InternationalOrders_OrderID_OrderID" FromRole="InternationalOrders" ToRole="Orders" />
        </EntityType>
        <EntityType Name="OrderDetails">
          <Key>
            <PropertyRef Name="OrderID" />
            <PropertyRef Name="ProductID" />
          </Key>
          <Property Name="OrderID" Type="Int64" Nullable="false" />
          <Property Name="ProductID" Type="Int64" Nullable="false" />
          <Property Name="UnitPrice" Type="Decimal" Nullable="false" Precision="53" Scale="0" />
          <Property Name="Quantity" Type="Int16" Nullable="false" />
          <Property Name="Discount" Type="Single" Nullable="false" />
          <NavigationProperty Name="Orders" Relationship="northwindEFModel.FK_OrderDetails_OrderID_OrderID" FromRole="OrderDetails" ToRole="Orders" />
          <NavigationProperty Name="Products" Relationship="northwindEFModel.FK_OrderDetails_ProductID_ProductID" FromRole="OrderDetails" ToRole="Products" />
        </EntityType>
        <EntityType Name="Orders">
          <Key>
            <PropertyRef Name="OrderID" />
          </Key>
          <Property Name="OrderID" Type="Int64" Nullable="false" />
          <Property Name="EmployeeID" Type="Int64" />
          <Property Name="OrderDate" Type="DateTime" />
          <Property Name="RequiredDate" Type="DateTime" />
          <Property Name="ShippedDate" Type="DateTime" />
          <Property Name="Freight" Type="Decimal" Precision="53" Scale="0" />
          <Property Name="ShipName" Type="String" MaxLength="40" Unicode="true" FixedLength="false" />
          <Property Name="ShipAddress" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="ShipCity" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="ShipRegion" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="ShipPostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="ShipCountry" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Customers" Relationship="northwindEFModel.FK_Orders_CustomerID_CustomerID" FromRole="Orders" ToRole="Customers" />
          <NavigationProperty Name="InternationalOrders" Relationship="northwindEFModel.FK_InternationalOrders_OrderID_OrderID" FromRole="Orders" ToRole="InternationalOrders" />
          <NavigationProperty Name="OrderDetails" Relationship="northwindEFModel.FK_OrderDetails_OrderID_OrderID" FromRole="Orders" ToRole="OrderDetails" />
        </EntityType>
        <EntityType Name="PreviousEmployees">
          <Key>
            <PropertyRef Name="EmployeeID" />
          </Key>
          <Property Name="EmployeeID" Type="Int64" Nullable="false" />
          <Property Name="LastName" Type="String" Nullable="false" MaxLength="20" Unicode="true" FixedLength="false" />
          <Property Name="FirstName" Type="String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Title" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="TitleOfCourtesy" Type="String" MaxLength="25" Unicode="true" FixedLength="false" />
          <Property Name="BirthDate" Type="DateTime" />
          <Property Name="HireDate" Type="DateTime" />
          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="HomePhone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="Extension" Type="String" MaxLength="4" Unicode="true" FixedLength="false" />
          <Property Name="Photo" Type="Binary" MaxLength="2147483647" FixedLength="false" />
          <Property Name="Notes" Type="String" MaxLength="2147483647" Unicode="true" FixedLength="false" />
          <Property Name="PhotoPath" Type="String" MaxLength="255" Unicode="true" FixedLength="false" />
        </EntityType>
        <EntityType Name="Products">
          <Key>
            <PropertyRef Name="ProductID" />
          </Key>
          <Property Name="ProductID" Type="Int64" Nullable="false" />
          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
          <Property Name="QuantityPerUnit" Type="String" MaxLength="20" Unicode="true" FixedLength="false" />
          <Property Name="UnitPrice" Type="Decimal" Precision="53" Scale="0" />
          <Property Name="UnitsInStock" Type="Int16" />
          <Property Name="UnitsOnOrder" Type="Int16" />
          <Property Name="ReorderLevel" Type="Int16" />
          <Property Name="Discontinued" Type="Boolean" Nullable="false" />
          <Property Name="DiscontinuedDate" Type="DateTime" />
          <NavigationProperty Name="Categories" Relationship="northwindEFModel.FK_Products_CategoryID_CategoryID" FromRole="Products" ToRole="Categories" />
          <NavigationProperty Name="OrderDetails" Relationship="northwindEFModel.FK_OrderDetails_ProductID_ProductID" FromRole="Products" ToRole="OrderDetails" />
          <NavigationProperty Name="Suppliers" Relationship="northwindEFModel.FK_Products_SupplierID_SupplierID" FromRole="Products" ToRole="Suppliers" />
        </EntityType>
        <EntityType Name="Regions">
          <Key>
            <PropertyRef Name="RegionID" />
          </Key>
          <Property Name="RegionID" Type="Int64" Nullable="false" />
          <Property Name="RegionDescription" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Territories" Relationship="northwindEFModel.FK_Territories_RegionID_RegionID" FromRole="Regions" ToRole="Territories" />
        </EntityType>
        <EntityType Name="Suppliers">
          <Key>
            <PropertyRef Name="SupplierID" />
          </Key>
          <Property Name="SupplierID" Type="Int64" Nullable="false" />
          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
          <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
          <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
          <Property Name="HomePage" Type="String" MaxLength="2147483647" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Products" Relationship="northwindEFModel.FK_Products_SupplierID_SupplierID" FromRole="Suppliers" ToRole="Products" />
        </EntityType>
        <EntityType Name="Territories">
          <Key>
            <PropertyRef Name="TerritoryID" />
          </Key>
          <Property Name="TerritoryID" Type="Int64" Nullable="false" />
          <Property Name="TerritoryDescription" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
          <NavigationProperty Name="Regions" Relationship="northwindEFModel.FK_Territories_RegionID_RegionID" FromRole="Territories" ToRole="Regions" />
          <NavigationProperty Name="Employees" Relationship="northwindEFModel.EmployeesTerritories" FromRole="Territories" ToRole="Employees" />
        </EntityType>
        <Association Name="FK_Products_CategoryID_CategoryID">
          <End Role="Categories" Type="northwindEFModel.Categories" Multiplicity="0..1" />
          <End Role="Products" Type="northwindEFModel.Products" Multiplicity="*" />
        </Association>
        <Association Name="FK_Orders_CustomerID_CustomerID">
          <End Role="Customers" Type="northwindEFModel.Customers" Multiplicity="0..1" />
          <End Role="Orders" Type="northwindEFModel.Orders" Multiplicity="*" />
        </Association>
        <Association Name="FK_InternationalOrders_OrderID_OrderID">
          <End Role="Orders" Type="northwindEFModel.Orders" Multiplicity="1" />
          <End Role="InternationalOrders" Type="northwindEFModel.InternationalOrders" Multiplicity="0..1" />
          <ReferentialConstraint>
            <Principal Role="Orders">
              <PropertyRef Name="OrderID" />
            </Principal>
            <Dependent Role="InternationalOrders">
              <PropertyRef Name="OrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_OrderDetails_OrderID_OrderID">
          <End Role="Orders" Type="northwindEFModel.Orders" Multiplicity="1" />
          <End Role="OrderDetails" Type="northwindEFModel.OrderDetails" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Orders">
              <PropertyRef Name="OrderID" />
            </Principal>
            <Dependent Role="OrderDetails">
              <PropertyRef Name="OrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_OrderDetails_ProductID_ProductID">
          <End Role="Products" Type="northwindEFModel.Products" Multiplicity="1" />
          <End Role="OrderDetails" Type="northwindEFModel.OrderDetails" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Products">
              <PropertyRef Name="ProductID" />
            </Principal>
            <Dependent Role="OrderDetails">
              <PropertyRef Name="ProductID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_Products_SupplierID_SupplierID">
          <End Role="Suppliers" Type="northwindEFModel.Suppliers" Multiplicity="0..1" />
          <End Role="Products" Type="northwindEFModel.Products" Multiplicity="*" />
        </Association>
        <Association Name="FK_Territories_RegionID_RegionID">
          <End Role="Regions" Type="northwindEFModel.Regions" Multiplicity="1" />
          <End Role="Territories" Type="northwindEFModel.Territories" Multiplicity="*" />
        </Association>
        <Association Name="EmployeesTerritories">
          <End Role="Employees" Type="northwindEFModel.Employees" Multiplicity="*" />
          <End Role="Territories" Type="northwindEFModel.Territories" Multiplicity="*" />
        </Association>
        </Schema>
    </edmx:ConceptualModels>
    <!-- C-S mapping content -->
    <edmx:Mappings>
      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
        <EntityContainerMapping StorageEntityContainer="northwindEFModelStoreContainer" CdmEntityContainer="northwindEFEntities">
          <EntitySetMapping Name="Categories">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Categories)">
              <MappingFragment StoreEntitySet="Categories">
                <ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
                <ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
                <ScalarProperty Name="Description" ColumnName="Description" />
                <ScalarProperty Name="Picture" ColumnName="Picture" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Customers">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Customers)">
              <MappingFragment StoreEntitySet="Customers">
                <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
                <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
                <ScalarProperty Name="ContactName" ColumnName="ContactName" />
                <ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
                <ScalarProperty Name="Address" ColumnName="Address" />
                <ScalarProperty Name="City" ColumnName="City" />
                <ScalarProperty Name="Region" ColumnName="Region" />
                <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
                <ScalarProperty Name="Country" ColumnName="Country" />
                <ScalarProperty Name="Phone" ColumnName="Phone" />
                <ScalarProperty Name="Fax" ColumnName="Fax" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Employees">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Employees)">
              <MappingFragment StoreEntitySet="Employees">
                <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
                <ScalarProperty Name="LastName" ColumnName="LastName" />
                <ScalarProperty Name="FirstName" ColumnName="FirstName" />
                <ScalarProperty Name="Title" ColumnName="Title" />
                <ScalarProperty Name="TitleOfCourtesy" ColumnName="TitleOfCourtesy" />
                <ScalarProperty Name="BirthDate" ColumnName="BirthDate" />
                <ScalarProperty Name="HireDate" ColumnName="HireDate" />
                <ScalarProperty Name="Address" ColumnName="Address" />
                <ScalarProperty Name="City" ColumnName="City" />
                <ScalarProperty Name="Region" ColumnName="Region" />
                <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
                <ScalarProperty Name="Country" ColumnName="Country" />
                <ScalarProperty Name="HomePhone" ColumnName="HomePhone" />
                <ScalarProperty Name="Extension" ColumnName="Extension" />
                <ScalarProperty Name="Photo" ColumnName="Photo" />
                <ScalarProperty Name="Notes" ColumnName="Notes" />
                <ScalarProperty Name="PhotoPath" ColumnName="PhotoPath" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="InternationalOrders">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.InternationalOrders)">
              <MappingFragment StoreEntitySet="InternationalOrders">
                <ScalarProperty Name="OrderID" ColumnName="OrderID" />
                <ScalarProperty Name="CustomsDescription" ColumnName="CustomsDescription" />
                <ScalarProperty Name="ExciseTax" ColumnName="ExciseTax" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="OrderDetails">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.OrderDetails)">
              <MappingFragment StoreEntitySet="OrderDetails">
                <ScalarProperty Name="OrderID" ColumnName="OrderID" />
                <ScalarProperty Name="ProductID" ColumnName="ProductID" />
                <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
                <ScalarProperty Name="Quantity" ColumnName="Quantity" />
                <ScalarProperty Name="Discount" ColumnName="Discount" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Orders">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Orders)">
              <MappingFragment StoreEntitySet="Orders">
                <ScalarProperty Name="OrderID" ColumnName="OrderID" />
                <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
                <ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
                <ScalarProperty Name="RequiredDate" ColumnName="RequiredDate" />
                <ScalarProperty Name="ShippedDate" ColumnName="ShippedDate" />
                <ScalarProperty Name="Freight" ColumnName="Freight" />
                <ScalarProperty Name="ShipName" ColumnName="ShipName" />
                <ScalarProperty Name="ShipAddress" ColumnName="ShipAddress" />
                <ScalarProperty Name="ShipCity" ColumnName="ShipCity" />
                <ScalarProperty Name="ShipRegion" ColumnName="ShipRegion" />
                <ScalarProperty Name="ShipPostalCode" ColumnName="ShipPostalCode" />
                <ScalarProperty Name="ShipCountry" ColumnName="ShipCountry" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="PreviousEmployees">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.PreviousEmployees)">
              <MappingFragment StoreEntitySet="PreviousEmployees">
                <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
                <ScalarProperty Name="LastName" ColumnName="LastName" />
                <ScalarProperty Name="FirstName" ColumnName="FirstName" />
                <ScalarProperty Name="Title" ColumnName="Title" />
                <ScalarProperty Name="TitleOfCourtesy" ColumnName="TitleOfCourtesy" />
                <ScalarProperty Name="BirthDate" ColumnName="BirthDate" />
                <ScalarProperty Name="HireDate" ColumnName="HireDate" />
                <ScalarProperty Name="Address" ColumnName="Address" />
                <ScalarProperty Name="City" ColumnName="City" />
                <ScalarProperty Name="Region" ColumnName="Region" />
                <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
                <ScalarProperty Name="Country" ColumnName="Country" />
                <ScalarProperty Name="HomePhone" ColumnName="HomePhone" />
                <ScalarProperty Name="Extension" ColumnName="Extension" />
                <ScalarProperty Name="Photo" ColumnName="Photo" />
                <ScalarProperty Name="Notes" ColumnName="Notes" />
                <ScalarProperty Name="PhotoPath" ColumnName="PhotoPath" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Products">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Products)">
              <MappingFragment StoreEntitySet="Products">
                <ScalarProperty Name="ProductID" ColumnName="ProductID" />
                <ScalarProperty Name="ProductName" ColumnName="ProductName" />
                <ScalarProperty Name="QuantityPerUnit" ColumnName="QuantityPerUnit" />
                <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
                <ScalarProperty Name="UnitsInStock" ColumnName="UnitsInStock" />
                <ScalarProperty Name="UnitsOnOrder" ColumnName="UnitsOnOrder" />
                <ScalarProperty Name="ReorderLevel" ColumnName="ReorderLevel" />
                <ScalarProperty Name="Discontinued" ColumnName="Discontinued" />
                <ScalarProperty Name="DiscontinuedDate" ColumnName="DiscontinuedDate" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Regions">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Regions)">
              <MappingFragment StoreEntitySet="Regions">
                <ScalarProperty Name="RegionID" ColumnName="RegionID" />
                <ScalarProperty Name="RegionDescription" ColumnName="RegionDescription" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Suppliers">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Suppliers)">
              <MappingFragment StoreEntitySet="Suppliers">
                <ScalarProperty Name="SupplierID" ColumnName="SupplierID" />
                <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
                <ScalarProperty Name="ContactName" ColumnName="ContactName" />
                <ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
                <ScalarProperty Name="Address" ColumnName="Address" />
                <ScalarProperty Name="City" ColumnName="City" />
                <ScalarProperty Name="Region" ColumnName="Region" />
                <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
                <ScalarProperty Name="Country" ColumnName="Country" />
                <ScalarProperty Name="Phone" ColumnName="Phone" />
                <ScalarProperty Name="Fax" ColumnName="Fax" />
                <ScalarProperty Name="HomePage" ColumnName="HomePage" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="Territories">
            <EntityTypeMapping TypeName="IsTypeOf(northwindEFModel.Territories)">
              <MappingFragment StoreEntitySet="Territories">
                <ScalarProperty Name="TerritoryID" ColumnName="TerritoryID" />
                <ScalarProperty Name="TerritoryDescription" ColumnName="TerritoryDescription" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <AssociationSetMapping Name="FK_Products_CategoryID_CategoryID" TypeName="northwindEFModel.FK_Products_CategoryID_CategoryID" StoreEntitySet="Products">
            <EndProperty Name="Categories">
              <ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
            </EndProperty>
            <EndProperty Name="Products">
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
            <Condition ColumnName="CategoryID" IsNull="false" />
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_Orders_CustomerID_CustomerID" TypeName="northwindEFModel.FK_Orders_CustomerID_CustomerID" StoreEntitySet="Orders">
            <EndProperty Name="Customers">
              <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
            </EndProperty>
            <EndProperty Name="Orders">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
            </EndProperty>
            <Condition ColumnName="CustomerID" IsNull="false" />
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_InternationalOrders_OrderID_OrderID" TypeName="northwindEFModel.FK_InternationalOrders_OrderID_OrderID" StoreEntitySet="InternationalOrders">
            <EndProperty Name="Orders">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
            </EndProperty>
            <EndProperty Name="InternationalOrders">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
            </EndProperty>
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_OrderDetails_OrderID_OrderID" TypeName="northwindEFModel.FK_OrderDetails_OrderID_OrderID" StoreEntitySet="OrderDetails">
            <EndProperty Name="Orders">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
            </EndProperty>
            <EndProperty Name="OrderDetails">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_OrderDetails_ProductID_ProductID" TypeName="northwindEFModel.FK_OrderDetails_ProductID_ProductID" StoreEntitySet="OrderDetails">
            <EndProperty Name="Products">
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
            <EndProperty Name="OrderDetails">
              <ScalarProperty Name="OrderID" ColumnName="OrderID" />
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_Products_SupplierID_SupplierID" TypeName="northwindEFModel.FK_Products_SupplierID_SupplierID" StoreEntitySet="Products">
            <EndProperty Name="Suppliers">
              <ScalarProperty Name="SupplierID" ColumnName="SupplierID" />
            </EndProperty>
            <EndProperty Name="Products">
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
            </EndProperty>
            <Condition ColumnName="SupplierID" IsNull="false" />
          </AssociationSetMapping>
          <AssociationSetMapping Name="FK_Territories_RegionID_RegionID" TypeName="northwindEFModel.FK_Territories_RegionID_RegionID" StoreEntitySet="Territories">
            <EndProperty Name="Regions">
              <ScalarProperty Name="RegionID" ColumnName="RegionID" />
            </EndProperty>
            <EndProperty Name="Territories">
              <ScalarProperty Name="TerritoryID" ColumnName="TerritoryID" />
            </EndProperty>
          </AssociationSetMapping>
          <AssociationSetMapping Name="EmployeesTerritories" TypeName="northwindEFModel.EmployeesTerritories" StoreEntitySet="EmployeesTerritories">
            <EndProperty Name="Employees">
              <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
            </EndProperty>
            <EndProperty Name="Territories">
              <ScalarProperty Name="TerritoryID" ColumnName="TerritoryID" />
            </EndProperty>
          </AssociationSetMapping>
          </EntityContainerMapping>
      </Mapping>
    </edmx:Mappings>
  </edmx:Runtime>
  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
  <edmx:Designer>
    <edmx:Connection>
      <DesignerInfoPropertySet xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
      </DesignerInfoPropertySet>
    </edmx:Connection>
    <edmx:Options>
      <DesignerInfoPropertySet xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
        <DesignerProperty Name="ValidateOnBuild" Value="true" />
      </DesignerInfoPropertySet>
    </edmx:Options>
    <!-- Diagram content (shape and connector positions) -->
    <edmx:Diagrams>
      <Diagram Name="NorthwindModel" xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
        <EntityTypeShape EntityType="northwindEFModel.Categories" Width="1.5" PointX="0.75" PointY="1.625" Height="1.9802864583333335" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Customers" Width="1.5" PointX="0.75" PointY="9.625" Height="3.3263964843749996" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Employees" Width="1.5" PointX="2.75" PointY="14.625" Height="4.4802050781250014" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.InternationalOrders" Width="1.5" PointX="5.25" PointY="10.375" Height="1.7879850260416674" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.OrderDetails" Width="1.5" PointX="5.25" PointY="1.5" Height="2.3648893229166656" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Orders" Width="1.5" PointX="3" PointY="9.25" Height="3.9033007812499996" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.PreviousEmployees" Width="1.5" PointX="7.75" PointY="0.75" Height="4.2879036458333317" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Products" Width="1.5" PointX="3" PointY="1" Height="3.3263964843749996" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Regions" Width="1.5" PointX="2.75" PointY="6" Height="1.5956835937499996" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Suppliers" Width="1.5" PointX="0.75" PointY="4.875" Height="3.5186979166666656" IsExpanded="true" />
        <EntityTypeShape EntityType="northwindEFModel.Territories" Width="1.5" PointX="5" PointY="5.875" Height="1.7879850260416674" IsExpanded="true" />
        <AssociationConnector Association="northwindEFModel.FK_Products_CategoryID_CategoryID" ManuallyRouted="false">
          <ConnectorPoint PointX="2.25" PointY="2.6151432291666667" />
          <ConnectorPoint PointX="3" PointY="2.6151432291666667" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_Orders_CustomerID_CustomerID" ManuallyRouted="false">
          <ConnectorPoint PointX="2.25" PointY="11.2881982421875" />
          <ConnectorPoint PointX="3" PointY="11.2881982421875" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_InternationalOrders_OrderID_OrderID" ManuallyRouted="false">
          <ConnectorPoint PointX="4.5" PointY="11.268992513020834" />
          <ConnectorPoint PointX="5.010416666666667" PointY="11.268992513020834" />
          <ConnectorPoint PointX="5.177083333333333" PointY="11.268992513020834" />
          <ConnectorPoint PointX="5.25" PointY="11.268992513020834" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_OrderDetails_OrderID_OrderID" ManuallyRouted="false">
          <ConnectorPoint PointX="3.75" PointY="9.25" />
          <ConnectorPoint PointX="3.75" PointY="7.84568359375" />
          <ConnectorPoint PointX="4.75" PointY="7.84568359375" />
          <ConnectorPoint PointX="4.75" PointY="2.6824446614583328" />
          <ConnectorPoint PointX="5.25" PointY="2.6824446614583328" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_OrderDetails_ProductID_ProductID" ManuallyRouted="false">
          <ConnectorPoint PointX="4.5" PointY="2.0287223307291664" />
          <ConnectorPoint PointX="5.25" PointY="2.0287223307291664" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_Products_SupplierID_SupplierID" ManuallyRouted="false">
          <ConnectorPoint PointX="2.25" PointY="5.40625" />
          <ConnectorPoint PointX="4.40625" PointY="5.40625" />
          <ConnectorPoint PointX="4.40625" PointY="4.326396484375" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.FK_Territories_RegionID_RegionID" ManuallyRouted="false">
          <ConnectorPoint PointX="4.25" PointY="6.797841796875" />
          <ConnectorPoint PointX="4.666666666666667" PointY="6.7978417968749989" />
          <ConnectorPoint PointX="4.833333333333333" PointY="6.797841796875" />
          <ConnectorPoint PointX="5" PointY="6.797841796875" /></AssociationConnector>
        <AssociationConnector Association="northwindEFModel.EmployeesTerritories" ManuallyRouted="false">
          <ConnectorPoint PointX="4.25" PointY="16.8651025390625" />
          <ConnectorPoint PointX="5.09375" PointY="16.8651025390625" />
          <ConnectorPoint PointX="5.09375" PointY="7.6629850260416674" /></AssociationConnector>
        </Diagram></edmx:Diagrams>
  </edmx:Designer>
</edmx:Edmx>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted testlinq/Program.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
/********************************************************
 * 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.Diagnostics;
using System.Linq;
using System.Data.Objects;
using System.Text;
using System.Transactions;

namespace testlinq
{
  class Program
  {
      private static int Main(string[] args)
      {
          if (Environment.GetEnvironmentVariable("BREAK") != null)
          {
              Console.WriteLine(
                  "Attach a debugger to process {0} and press any key to continue.",
                  Process.GetCurrentProcess().Id);

              try
              {
                  Console.ReadKey(true); /* throw */
              }
              catch (InvalidOperationException) // Console.ReadKey
              {
                  // do nothing.
              }

              Debugger.Break();
          }

          string arg = null;

          if ((args != null) && (args.Length > 0))
              arg = args[0];

          if (arg == null)
              arg = "";

          arg = arg.Trim().TrimStart('-', '/').ToLowerInvariant();

          switch (arg)
          {
              case "": // String.Empty
              case "old":
                  {
                      return OldTests();
                  }
              case "skip":
                  {
                      int pageSize = 0;

                      if (args.Length > 1)
                      {
                          arg = args[1];

                          if (arg != null)
                              pageSize = int.Parse(arg.Trim());
                      }

                      return SkipTest(pageSize);
                  }
              case "endswith":
                  {
                      string value = null;

                      if (args.Length > 1)
                      {
                          value = args[1];

                          if (value != null)
                              value = value.Trim();
                      }

                      return EndsWithTest(value);
                  }
              case "startswith":
                  {
                      string value = null;

                      if (args.Length > 1)
                      {
                          value = args[1];

                          if (value != null)
                              value = value.Trim();
                      }

                      return StartsWithTest(value);
                  }
              case "eftransaction":
                  {
                      bool value = false;

                      if (args.Length > 1)
                      {
                          if (!bool.TryParse(args[1], out value))
                          {
                              Console.WriteLine(
                                  "cannot parse \"{0}\" as boolean",
                                  args[1]);

                              return 1;
                          }
                      }

                      return EFTransactionTest(value);
                  }
              default:
                  {
                      Console.WriteLine("unknown test \"{0}\"", arg);
                      return 1;
                  }
          }
      }

      //
      // NOTE: Used to test the fix for ticket [8b7d179c3c].
      //
      private static int SkipTest(int pageSize)
      {
          using (northwindEFEntities db = new northwindEFEntities())
          {
              bool once = false;
              int count = db.Customers.Count();

              int PageCount = (pageSize != 0) ?
                  (count / pageSize) + ((count % pageSize) == 0 ? 0 : 1) : 1;

              for (int pageIndex = 0; pageIndex < PageCount; pageIndex++)
              {
                  var query = db.Customers.OrderBy(p => p.City).
                      Skip(pageSize * pageIndex).Take(pageSize);

                  foreach (Customers customers in query)
                  {
                      if (once)
                          Console.Write(' ');

                      Console.Write(customers.CustomerID);

                      once = true;
                  }
              }
          }

          return 0;
      }

      //
      // NOTE: Used to test the fix for ticket [59edc1018b].
      //
      private static int EndsWithTest(string value)
      {
          using (northwindEFEntities db = new northwindEFEntities())
          {
              bool once = false;
              var query = from c in db.Customers
                          where c.City.EndsWith(value)
                          orderby c.CustomerID
                          select c;

              foreach (Customers customers in query)
              {
                  if (once)
                      Console.Write(' ');

                  Console.Write(customers.CustomerID);

                  once = true;
              }
          }

          return 0;
      }

      //
      // NOTE: Used to verify the behavior from ticket [00f86f9739].
      //
      private static int StartsWithTest(string value)
      {
          using (northwindEFEntities db = new northwindEFEntities())
          {
              bool once = false;
              var query = from c in db.Customers
                          where c.City.StartsWith(value)
                          orderby c.CustomerID
                          select c;

              foreach (Customers customers in query)
              {
                  if (once)
                      Console.Write(' ');

                  Console.Write(customers.CustomerID);

                  once = true;
              }
          }

          return 0;
      }

      //
      // NOTE: Used to test the fix for ticket [ccfa69fc32].
      //
      private static int EFTransactionTest(bool add)
      {
          //
          // NOTE: Some of these territories already exist and should cause
          //       an exception to be thrown when we try to INSERT them.
          //
          long[] territoryIds = new long[] {
                 1,    2,    3,    4,    5, // NOTE: Success
                 6,    7,    8,    9,   10, // NOTE: Success
              1576, 1577, 1578, 1579, 1580, // NOTE: Success
              1581, 1730, 1833, 2116, 2139, // NOTE: Fail (1581)
              2140, 2141                    // NOTE: Skipped
          };

          if (add)
          {
              using (northwindEFEntities db = new northwindEFEntities())
              {
                  using (TransactionScope scope = new TransactionScope())
                  {
                      //
                      // NOTE: *REQUIRED* This is required so that the
                      //       Entity Framework is prevented from opening
                      //       multiple connections to the underlying SQLite
                      //       database (i.e. which would result in multiple
                      //       IMMEDIATE transactions, thereby failing [later
                      //       on] with locking errors).
                      //
                      db.Connection.Open();

                      foreach (int id in territoryIds)
                      {
                          Territories territories = new Territories();

                          territories.TerritoryID = id;
                          territories.TerritoryDescription = String.Format(
                              "Test Territory #{0}", id);
                          territories.Regions = db.Regions.First();

                          db.AddObject("Territories", territories);
                      }

                      try
                      {
#if NET_20
                          db.SaveChanges(false);
#else
                          db.SaveChanges(SaveOptions.None);
#endif
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine(e);
                      }
                      finally
                      {
                          scope.Complete();
                          db.AcceptAllChanges();
                      }
                  }
              }
          }
          else
          {
              using (northwindEFEntities db = new northwindEFEntities())
              {
                  bool once = false;
#if NET_20
                  //
                  // HACK: We cannot use the Contains extension method within a
                  //       LINQ query with the .NET Framework 3.5.
                  //
                  var query = from t in db.Territories
                    orderby t.TerritoryID
                    select t;

                  foreach (Territories territories in query)
                  {
                      if (Array.IndexOf(territoryIds, territories.TerritoryID) == -1)
                          continue;

                      if (once)
                          Console.Write(' ');

                      Console.Write(territories.TerritoryID);

                      once = true;
                  }
#else
                  var query = from t in db.Territories
                    where territoryIds.AsQueryable<long>().Contains<long>(t.TerritoryID)
                    orderby t.TerritoryID
                    select t;

                  foreach (Territories territories in query)
                  {
                      if (once)
                          Console.Write(' ');

                      Console.Write(territories.TerritoryID);

                      once = true;
                  }
#endif
              }
          }

          return 0;
      }

    private static int OldTests()
    {
      using (northwindEFEntities db = new northwindEFEntities())
      {
        {
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE SQLite.DatePart('yyyy', o.OrderDate) = 1997;";
          ObjectQuery<Orders> query = db.CreateQuery<Orders>(entitySQL);

          foreach (Orders o in query)
          {
            Console.WriteLine(o.ShipPostalCode);
          }
        }

        {
          var query = from c in db.Customers
                      where c.City == "London"
                      orderby c.CompanyName
                      select c;

          int cc = query.Count();

          foreach (Customers c in query)
          {
            Console.WriteLine(c.CompanyName);
          }
        }

        {
          string scity = "London";
          Customers c = db.Customers.FirstOrDefault(cd => cd.City == scity);
          Console.WriteLine(c.CompanyName);
        }

        {
          DateTime dt = new DateTime(1997, 1, 1);
          var query = from order in db.Orders
                      where order.OrderDate < dt
                      select order;

          foreach (Orders o in query)
          {
            Console.WriteLine(o.OrderDate.ToString());
          }
        }

        {
          Categories c = new Categories();
          c.CategoryName = "Test Category";
          c.Description = "My Description";
          db.AddToCategories(c);
          db.SaveChanges();

          Console.WriteLine(c.CategoryID);

          c.Description = "My modified description";
          db.SaveChanges();

          db.DeleteObject(c);
          db.SaveChanges();
        }

        {
          Customers cust = new Customers();
          cust.CustomerID = "MTMTM";
          cust.ContactName = "My Name";
          cust.CompanyName = "SQLite Company";
          cust.Country = "Netherlands";
          cust.City = "Amsterdam";
          cust.Phone = "012345677";
          db.AddToCustomers(cust);
          db.SaveChanges();

          db.DeleteObject(cust);
          db.SaveChanges();
        }

        {
          var query = db.Customers.Where(cust => cust.Country == "Denmark")
                          .SelectMany(cust => cust.Orders.Where(o => o.Freight > 5));

          foreach (Orders c in query)
          {
            Console.WriteLine(c.Freight);
          }
        }

        {
          var query = from c in db.Customers
                      where c.Orders.Any(o => o.OrderDate.HasValue == true && o.OrderDate.Value.Year == 1997)
                      select c;

          foreach (Customers c in query)
          {
            Console.WriteLine(c.CompanyName);
          }
        }

        {
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE o.Customers.Country <> 'UK' AND o.Customers.Country <> 'Mexico' AND Year(o.OrderDate) = 1997;";
          ObjectQuery<Orders> query = db.CreateQuery<Orders>(entitySQL);

          foreach (Orders o in query)
          {
            Console.WriteLine(o.ShipPostalCode);
          }
        }

        {
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE NewGuid() <> NewGuid();";
          ObjectQuery<Orders> query = db.CreateQuery<Orders>(entitySQL);

          foreach (Orders o in query)
          {
            Console.WriteLine(o.ShipPostalCode);
          }
        }

        // This query requires SQLite 3.6.2 to function correctly
        {
          var query = from p in db.Products
                      where p.OrderDetails.Count(od => od.Orders.Customers.Country == p.Suppliers.Country) > 2
                      select p;

          foreach (Products p in query)
          {
            Console.WriteLine(p.ProductName);
          }
        }
      }

      //
      // NOTE: (JJM) Removed on 2011/07/06, makes it harder to run this EXE via
      //       the new unit test suite.
      //
      // Console.ReadKey();

      return 0;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted testlinq/Properties/AssemblyInfo.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
/********************************************************
 * 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.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite Tester for LINQ")]
[assembly: AssemblyDescription("ADO.NET Data Provider for SQLite")]
[assembly: AssemblyCompany("http://system.data.sqlite.org/")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("8fd19c43-2fa6-487c-9201-47dd59eed056")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      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.77.0")]
[assembly: AssemblyFileVersion("1.0.77.0")]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































Deleted testlinq/northwindEF.db.

cannot compute difference between binary files

Deleted testlinq/testlinq.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * testlinq.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}</ProjectGuid>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <OutputType>Exe</OutputType>
    <RootNamespace>testlinq</RootNamespace>
    <AssemblyName>testlinq</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <OldToolsVersion>2.0</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Data.Entity" />
    <Reference Include="System.Runtime.Serialization" />
    <Reference Include="System.Transactions" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Data" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="NorthwindModel2008.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>NorthwindModel2008.edmx</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="2008\App.Config" />
    <None Include="northwindEF.db">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <EntityDeploy Include="NorthwindModel2008.edmx">
      <Generator>EntityModelCodeGenerator</Generator>
      <LastGenOutput>NorthwindModel2008.Designer.cs</LastGenOutput>
    </EntityDeploy>
  </ItemGroup>
  <ItemGroup>
    <Service Include="{C8F2D6AC-F9F4-4E40-A399-22F9A9A5CBD2}" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































Deleted testlinq/testlinq.2010.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * testlinq.2010.csproj -
 *
 * 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>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.30319</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{9D3CF7A6-092A-4B05-B0E4-BEF6944525B3}</ProjectGuid>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <OutputType>Exe</OutputType>
    <RootNamespace>testlinq</RootNamespace>
    <AssemblyName>testlinq</AssemblyName>
    <OldToolsVersion>3.5</OldToolsVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
    <ConfigurationYear>2010</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data.Entity" />
    <Reference Include="System.Runtime.Serialization" />
    <Reference Include="System.Transactions" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Data" />
  </ItemGroup>
  <ItemGroup>
    <Compile Condition="'$(TargetFrameworkVersion)' == 'v3.5'"
             Include="NorthwindModel2008.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>NorthwindModel2008.edmx</DependentUpon>
    </Compile>
    <Compile Condition="'$(TargetFrameworkVersion)' == 'v4.0'"
             Include="NorthwindModel2010.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>NorthwindModel2010.edmx</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Condition="'$(TargetFrameworkVersion)' == 'v3.5'"
          Include="2008\App.Config" />
    <None Condition="'$(TargetFrameworkVersion)' == 'v4.0'"
          Include="2010\App.Config" />
    <None Include="northwindEF.db">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <EntityDeploy Condition="'$(TargetFrameworkVersion)' == 'v3.5'"
                  Include="NorthwindModel2008.edmx">
      <Generator>EntityModelCodeGenerator</Generator>
      <LastGenOutput>NorthwindModel2008.Designer.cs</LastGenOutput>
    </EntityDeploy>
    <EntityDeploy Condition="'$(TargetFrameworkVersion)' == 'v4.0'"
                  Include="NorthwindModel2010.edmx">
      <Generator>EntityModelCodeGenerator</Generator>
      <LastGenOutput>NorthwindModel2010.Designer.cs</LastGenOutput>
    </EntityDeploy>
  </ItemGroup>
  <ItemGroup>
    <Service Include="{C8F2D6AC-F9F4-4E40-A399-22F9A9A5CBD2}" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted tools/install/Installer.2008.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * Installer.2008.csproj -
 *
 * 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="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{A41FE2A5-07AD-4CE7-B836-1544634816F5}</ProjectGuid>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <OutputType>Exe</OutputType>
    <RootNamespace>Installer</RootNamespace>
    <AssemblyName>Installer</AssemblyName>
    <OldToolsVersion>2.0</OldToolsVersion>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..\..</SQLiteNetDir>
    <NetFx20>true</NetFx20>
    <ConfigurationYear>2008</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.EnterpriseServices" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Installer.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































Deleted tools/install/Installer.2010.csproj.
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
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * Installer.2010.csproj -
 *
 * 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>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.30319</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{A41FE2A5-07AD-4CE7-B836-1544634816F5}</ProjectGuid>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <OutputType>Exe</OutputType>
    <RootNamespace>Installer</RootNamespace>
    <AssemblyName>Installer</AssemblyName>
    <OldToolsVersion>3.5</OldToolsVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..\..</SQLiteNetDir>
    <ConfigurationYear>2010</ConfigurationYear>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <PropertyGroup Condition="'$(BinaryOutputPath)' != ''">
    <OutputPath>$(BinaryOutputPath)</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.EnterpriseServices" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Installer.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































Deleted tools/install/Installer.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
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
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
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
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
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
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
1870
1871
1872
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
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
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
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
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
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
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
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
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
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
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
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
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
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
2435
2436
2437
2438
2439
2440
2441
2442
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
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
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
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
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
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
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
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
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
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
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
/*
 * Installer.cs --
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 */

using System.Collections.Generic;
using System.Diagnostics;
using System.EnterpriseServices.Internal;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using Microsoft.Win32;

namespace System.Data.SQLite
{
    #region Public Delegates
    internal delegate void TraceCallback(
        string message,
        string category
    );

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

    internal delegate bool FrameworkConfigCallback(
        string fileName,
        string invariant,
        string name,
        string description,
        string typeName,
        AssemblyName assemblyName,
        object clientData,
        bool whatIf,
        bool verbose,
        ref bool saved,
        ref string error
    );

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

    internal delegate bool FrameworkRegistryCallback(
        RegistryKey rootKey,
        string frameworkName,
        Version frameworkVersion,
        string platformName,
        object clientData,
        bool whatIf,
        bool verbose,
        ref string error
    );

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

    internal delegate bool VisualStudioRegistryCallback(
        RegistryKey rootKey,
        Version vsVersion,
        Installer.Package package,
        object clientData,
        bool whatIf,
        bool verbose,
        ref string error
    );
    #endregion

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

    #region Public Enumerations
    [Flags()]
    public enum InstallFlags
    {
        None = 0x0,
        GAC = 0x1,
        AssemblyFolders = 0x2,
        DbProviderFactory = 0x4,
        VsPackage = 0x8,
        VsDataSource = 0x10,
        VsDataProvider = 0x20,
        Framework = GAC | AssemblyFolders | DbProviderFactory,
        Vs = VsPackage | VsDataSource | VsDataProvider,
        All = Framework | Vs,
        AllNoGAC = All & ~GAC,
        Default = All
    }

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

    [Flags()]
    public enum TracePriority
    {
        None = 0x0,
        Lowest = 0x1,
        Lower = 0x2,
        Low = 0x4,
        Medium = 0x8,
        High = 0x10,
        Higher = 0x20,
        Highest = 0x40,
        Debug = Medium, /* NOTE: Default for debug messages. */
        Trace = Medium  /* NOTE: Default for trace messages. */
    }
    #endregion

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

    #region Installer Class
    internal static class Installer
    {
        #region Private Helper Classes
        #region AnyPair Class
        private sealed class AnyPair<T1, T2>
        {
            #region Public Constructors
            //
            // WARNING: This constructor produces an immutable "empty" pair
            //          object.
            //
            public AnyPair()
                : base()
            {
                // do nothing.
            }

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

            public AnyPair(T1 x)
                : this()
            {
                this.x = x;
            }

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

            public AnyPair(T1 x, T2 y)
                : this(x)
            {
                this.y = y;
            }
            #endregion

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

            #region Public Properties
            private T1 x;
            public T1 X
            {
                get { return x; }
            }

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

            private T2 y;
            public T2 Y
            {
                get { return y; }
            }
            #endregion
        }
        #endregion

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

        #region TraceOps Class
        private static class TraceOps
        {
            #region Private Constants
            private const string DefaultDebugFormat = "#{0} @ {1}: {2}";
            private const string DefaultTraceFormat = "#{0} @ {1}: {2}";

            private const string Iso8601DateTimeOutputFormat =
                "yyyy.MM.ddTHH:mm:ss.fffffff";
            #endregion

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

            #region Private Static Data
            private static object syncRoot = new object();
            private static long nextDebugId;
            private static long nextTraceId;
            private static TracePriority debugPriority = TracePriority.Debug;
            private static TracePriority tracePriority = TracePriority.Trace;
            private static string debugFormat = DefaultDebugFormat;
            private static string traceFormat = DefaultTraceFormat;
            #endregion

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

            #region Public Static Properties
            public static TracePriority DebugPriority
            {
                get { lock (syncRoot) { return debugPriority; } }
                set { lock (syncRoot) { debugPriority = value; } }
            }

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

            public static TracePriority TracePriority
            {
                get { lock (syncRoot) { return tracePriority; } }
                set { lock (syncRoot) { tracePriority = value; } }
            }

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

            public static string DebugFormat
            {
                get { lock (syncRoot) { return debugFormat; } }
                set { lock (syncRoot) { debugFormat = value; } }
            }

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

            public static string TraceFormat
            {
                get { lock (syncRoot) { return traceFormat; } }
                set { lock (syncRoot) { traceFormat = value; } }
            }
            #endregion

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

            #region Interactive Support Methods
            public static string GetAssemblyTitle(
                Assembly assembly
                )
            {
                if (assembly != null)
                {
                    try
                    {
                        if (assembly.IsDefined(
                                typeof(AssemblyTitleAttribute), false))
                        {
                            AssemblyTitleAttribute title =
                                (AssemblyTitleAttribute)
                                assembly.GetCustomAttributes(
                                    typeof(AssemblyTitleAttribute), false)[0];

                            return title.Title;
                        }
                    }
                    catch
                    {
                        // do nothing.
                    }
                }

                return null;
            }

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

            public static DialogResult ShowMessage(
                TracePriority tracePriority,
                TraceCallback debugCallback,
                TraceCallback traceCallback,
                Assembly assembly,
                string message,
                string category,
                MessageBoxButtons buttons,
                MessageBoxIcon icon
                )
            {
                DialogResult result = DialogResult.OK;

                DebugAndTrace(tracePriority,
                    debugCallback, traceCallback, message, category);

                if (SystemInformation.UserInteractive)
                {
                    string title = GetAssemblyTitle(assembly);

                    if (title == null)
                        title = Application.ProductName;

                    result = MessageBox.Show(message, title, buttons, icon);

                    DebugAndTrace(tracePriority,
                        debugCallback, traceCallback, String.Format(
                        "User choice of {0}.", ForDisplay(result)),
                        category);

                    return result;
                }

                DebugAndTrace(tracePriority,
                    debugCallback, traceCallback, String.Format(
                    "Default choice of {0}.", ForDisplay(result)),
                    category);

                return result;
            }
            #endregion

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

            #region Tracing Support Methods
            public static long NextDebugId()
            {
                return Interlocked.Increment(ref nextDebugId);
            }

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

            public static long NextTraceId()
            {
                return Interlocked.Increment(ref nextTraceId);
            }

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

            public static string TimeStamp(DateTime dateTime)
            {
                return dateTime.ToString(Iso8601DateTimeOutputFormat);
            }

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

            [MethodImpl(MethodImplOptions.NoInlining)]
            private static string GetMethodName(
                StackTrace stackTrace,
                int level
                )
            {
                try
                {
                    //
                    // NOTE: If a valid stack trace was not supplied by the
                    //       caller, create one now based on the current
                    //       execution stack.
                    //
                    if (stackTrace == null)
                    {
                        //
                        // NOTE: Grab the current execution stack.
                        //
                        stackTrace = new StackTrace();

                        //
                        // NOTE: Always skip this call frame when we capture
                        //       the stack trace.
                        //
                        level++;
                    }

                    //
                    // NOTE: Get the specified stack frame (always add one to
                    //       skip this method).
                    //
                    StackFrame stackFrame = stackTrace.GetFrame(level);

                    //
                    // NOTE: Get the method for the stack frame.
                    //
                    MethodBase methodBase = stackFrame.GetMethod();

                    //
                    // NOTE: Get the type for the method.
                    //
                    Type type = methodBase.DeclaringType;

                    //
                    // NOTE: Get the name of the method.
                    //
                    string name = methodBase.Name;

                    //
                    // NOTE: Return the properly formatted result.
                    //
                    return String.Format(
                        "{0}{1}{2}", type.Name, Type.Delimiter, name);
                }
                catch
                {
                    // do nothing.
                }

                return null;
            }

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

            public static void DebugCore(
                string message,
                string category
                )
            {
                lock (syncRoot)
                {
#if DEBUG
                    //
                    // NOTE: Write the message to all the active debug
                    //       listeners.
                    //
                    Debug.WriteLine(message, category);
                    Debug.Flush();
#else
                    //
                    // NOTE: For a build without "DEBUG" defined, we cannot
                    //       simply use the Debug class (i.e. it will do
                    //       nothing); therefore, use the console directly
                    //       instead.
                    //
                    Console.WriteLine(String.Format("{1}: {0}", message,
                        category));
#endif
                }
            }

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

            public static void TraceCore(
                string message,
                string category
                )
            {
                lock (syncRoot)
                {
                    //
                    // NOTE: Write the message to all the active trace
                    //       listeners.
                    //
                    Trace.WriteLine(message, category);
                    Trace.Flush();
                }
            }

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

            [MethodImpl(MethodImplOptions.NoInlining)]
            public static string DebugAndTrace(
                TracePriority tracePriority,
                TraceCallback debugCallback,
                TraceCallback traceCallback,
                Exception exception,
                string category
                )
            {
                if (exception != null)
                    return DebugAndTrace(tracePriority, debugCallback,
                        traceCallback, new StackTrace(exception, true), 0,
                        exception.ToString(), category);

                return null;
            }

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

            [MethodImpl(MethodImplOptions.NoInlining)]
            public static string DebugAndTrace(
                TracePriority tracePriority,
                TraceCallback debugCallback,
                TraceCallback traceCallback,
                string message,
                string category
                )
            {
                return DebugAndTrace(
                    tracePriority, debugCallback, traceCallback, null, 1,
                    message, category);
            }

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

            [MethodImpl(MethodImplOptions.NoInlining)]
            private static string DebugAndTrace(
                TracePriority tracePriority,
                TraceCallback debugCallback,
                TraceCallback traceCallback,
                StackTrace stackTrace,
                int level,
                string message,
                string category
                )
            {
                //
                // NOTE: Always skip this call frame if the stack trace is
                //       going to be captured by GetMethodName.
                //
                if (stackTrace == null)
                    level++;

                //
                // NOTE: Format the message for display (once).
                //
                string formatted = String.Format("{0}: {1}",
                    GetMethodName(stackTrace, level), message);

                //
                // NOTE: If the trace priority of this message is less than
                //       what we currently want to debug, skip it.
                //
                if (tracePriority >= DebugPriority)
                {
                    //
                    // NOTE: If not specified, use the default debug callback.
                    //
                    if (debugCallback == null)
                        debugCallback = DebugCore;

                    //
                    // NOTE: Invoke the debug callback with the formatted
                    //       message and the category specified by the
                    //       caller.
                    //
                    debugCallback(formatted, category);
                }

                //
                // NOTE: If the trace priority of this message is less than
                //       what we currently want to trace, skip it.
                //
                if (tracePriority >= TracePriority)
                {
                    //
                    // NOTE: If not specified, use the default trace callback.
                    //
                    if (traceCallback == null)
                        traceCallback = TraceCore;

                    //
                    // NOTE: Invoke the trace callback with the formatted
                    //       message and the category specified by the
                    //       caller.
                    //
                    traceCallback(formatted, category);
                }

                return message;
            }
            #endregion
        }
        #endregion

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

        #region MockRegistryKey Class
        private sealed class MockRegistryKey : IDisposable
        {
            #region Private Constructors
            private MockRegistryKey()
            {
                whatIf = true;
                readOnly = true;
                safe = true;
            }
            #endregion

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

            #region Public Constructors
            public MockRegistryKey(
                RegistryKey key
                )
                : this()
            {
                this.key = key;
            }

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

            public MockRegistryKey(
                RegistryKey key,
                string subKeyName
                )
                : this(key)
            {
                this.subKeyName = subKeyName;
            }

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

            public MockRegistryKey(
                RegistryKey key,
                string subKeyName,
                bool whatIf
                )
                : this(key, subKeyName)
            {
                this.whatIf = whatIf;
            }

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

            public MockRegistryKey(
                RegistryKey key,
                string subKeyName,
                bool whatIf,
                bool readOnly
                )
                : this(key, subKeyName, whatIf)
            {
                this.readOnly = readOnly;
            }

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

            public MockRegistryKey(
                RegistryKey key,
                string subKeyName,
                bool whatIf,
                bool readOnly,
                bool safe
                )
                : this(key, subKeyName, whatIf, readOnly)
            {
                this.safe = safe;
            }

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

            public MockRegistryKey(
                RegistryKey key,
                bool whatIf
                )
                : this(key, null, whatIf)
            {
                // do nothing.
            }

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

            public MockRegistryKey(
                RegistryKey key,
                bool whatIf,
                bool readOnly
                )
                : this(key, null, whatIf, readOnly)
            {
                // do nothing.
            }

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

            public MockRegistryKey(
                RegistryKey key,
                bool whatIf,
                bool readOnly,
                bool safe
                )
                : this(key, null, whatIf, readOnly, safe)
            {
                // do nothing.
            }
            #endregion

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

            #region Public Methods
            public void Close()
            {
                //
                // NOTE: No disposed check here because calling this method
                //       should be just like calling Dispose.
                //
                Dispose(true);
            }

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

            public MockRegistryKey CreateSubKey(
                string subKeyName
                )
            {
                CheckDisposed();
                CheckReadOnly();

                if (key == null)
                    return null;

                if (whatIf)
                {
                    //
                    // HACK: Attempt to open the specified sub-key.  If this
                    //       fails, we will simply return the wrapped root key
                    //       itself since no writes are allowed in 'what-if'
                    //       mode anyhow.
                    //
                    RegistryKey subKey = key.OpenSubKey(subKeyName);

                    return (subKey != null) ?
                        new MockRegistryKey(
                                subKey, whatIf, readOnly, safe) :
                        new MockRegistryKey(
                                key, subKeyName, whatIf, readOnly, safe);
                }
                else
                {
                    return new MockRegistryKey(
                        key.CreateSubKey(subKeyName), whatIf, readOnly, safe);
                }
            }

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

            public void DeleteSubKey(
                string subKeyName
                )
            {
                CheckDisposed();
                CheckReadOnly();

                if (key == null)
                    return;

                if (!whatIf)
                    key.DeleteSubKey(subKeyName);
            }

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

            public void DeleteSubKeyTree(
                string subKeyName
                )
            {
                CheckDisposed();
                CheckReadOnly();

                if (key == null)
                    return;

                if (!whatIf)
                    key.DeleteSubKeyTree(subKeyName);
            }

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

            public void DeleteValue(
                string name
                )
            {
                CheckDisposed();
                CheckReadOnly();

                if (key == null)
                    return;

                if (!whatIf)
                    key.DeleteValue(name);
            }

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

            public string[] GetSubKeyNames()
            {
                CheckDisposed();

                if (key == null)
                    return null;

                return key.GetSubKeyNames();
            }

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

            public object GetValue(
                string name,
                object defaultValue
                )
            {
                CheckDisposed();

                if (key == null)
                    return null;

                return key.GetValue(name, defaultValue);
            }

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

            public MockRegistryKey OpenSubKey(
                string subKeyName
                )
            {
                CheckDisposed();

                return OpenSubKey(subKeyName, false);
            }

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

            public MockRegistryKey OpenSubKey(
                string subKeyName,
                bool writable
                )
            {
                CheckDisposed();

                if (writable)
                    CheckReadOnly();

                if (key == null)
                    return null;

                RegistryKey subKey = key.OpenSubKey(
                    subKeyName, whatIf ? false : writable);

                return (subKey != null) ?
                    new MockRegistryKey(subKey, whatIf, readOnly, safe) : null;
            }

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

            public void SetValue(
                string name,
                object value
                )
            {
                CheckDisposed();
                CheckReadOnly();

                if (key == null)
                    return;

                if (!whatIf)
                    key.SetValue(name, value);
            }
            #endregion

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

            #region Public Properties
            public string Name
            {
                get
                {
                    CheckDisposed();

                    if (key == null)
                        return null;

                    return !String.IsNullOrEmpty(subKeyName) ?
                        String.Format("{0}\\{1}", key.Name, subKeyName) :
                        key.Name;
                }
            }

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

            private RegistryKey key;
            public RegistryKey Key
            {
                get { CheckDisposed(); CheckSafe(); return key; }
            }

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

            private string subKeyName;
            public string SubKeyName
            {
                get { CheckDisposed(); return subKeyName; }
            }

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

            private bool whatIf;
            public bool WhatIf
            {
                get { CheckDisposed(); return whatIf; }
            }

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

            private bool readOnly;
            public bool ReadOnly
            {
                get { CheckDisposed(); return readOnly; }
            }

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

            public bool safe;
            public bool Safe
            {
                get { CheckDisposed(); return safe; }
            }
            #endregion

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

            #region Private Methods
            private void CheckReadOnly()
            {
                //
                // NOTE: In "read-only" mode, we disallow all write access.
                //
                if (!readOnly)
                    return;

                throw new InvalidOperationException();
            }

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

            private void CheckSafe()
            {
                //
                // NOTE: In "safe" mode, we disallow all direct access to the
                //       contained registry key.
                //
                if (!safe)
                    return;

                throw new InvalidOperationException();
            }
            #endregion

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

            #region System.Object Overrides
            public override string ToString()
            {
                CheckDisposed();

                return this.Name;
            }
            #endregion

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

            #region Implicit Conversion Operators
            //
            // BUGBUG: The 'what-if' mode setting here should probably be based
            //         on some static property, not hard-coded to true?
            //
            public static implicit operator MockRegistryKey(
                RegistryKey key
                )
            {
                return new MockRegistryKey(key, null, true, false, false);
            }

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

            //
            // BUGBUG: Remove me?  This should be safe because in 'what-if'
            //         mode all keys are opened read-only.
            //
            public static implicit operator RegistryKey(
                MockRegistryKey key
                )
            {
                return (key != null) ? key.Key : null;
            }
            #endregion

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

            #region IDisposable "Pattern" Members
            private bool disposed;
            private void CheckDisposed() /* throw */
            {
                if (!disposed)
                    return;

                throw new ObjectDisposedException(
                    typeof(MockRegistryKey).Name);
            }

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

            private /* protected virtual */ void Dispose(
                bool disposing
                )
            {
                if (!disposed)
                {
                    if (disposing)
                    {
                        ////////////////////////////////////
                        // dispose managed resources here...
                        ////////////////////////////////////

                        if (key != null)
                        {
                            key.Close();
                            key = null;
                        }
                    }

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

                    //
                    // NOTE: This object is now disposed.
                    //
                    disposed = true;
                }
            }
            #endregion

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

            #region IDisposable Members
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
            #endregion

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

            #region Destructor
            ~MockRegistryKey()
            {
                Dispose(false);
            }
            #endregion
        }
        #endregion

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

        #region RegistryHelper Class
        private static class RegistryHelper
        {
            #region Public Static Properties
            private static int subKeysCreated;
            public static int SubKeysCreated
            {
                get { return subKeysCreated; }
            }

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

            private static int subKeysDeleted;
            public static int SubKeysDeleted
            {
                get { return subKeysDeleted; }
            }

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

            private static int keyValuesSet;
            public static int KeyValuesSet
            {
                get { return keyValuesSet; }
            }

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

            private static int keyValuesDeleted;
            public static int KeyValuesDeleted
            {
                get { return keyValuesDeleted; }
            }
            #endregion

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

            #region Public Static Methods
            public static RegistryKey GetRootKeyByName(
                string keyName
                )
            {
                if (String.IsNullOrEmpty(keyName))
                    return null;

                switch (keyName.ToUpperInvariant())
                {
                    case "HKCR":
                    case "HKEY_CLASSES_ROOT":
                        return Registry.ClassesRoot;
                    case "HKCC":
                    case "HKEY_CURRENT_CONFIG":
                        return Registry.CurrentConfig;
                    case "HKCU":
                    case "HKEY_CURRENT_USER":
                        return Registry.CurrentUser;
                    case "HKDD":
                    case "HKEY_DYN_DATA":
                        return Registry.DynData;
                    case "HKLM":
                    case "HKEY_LOCAL_MACHINE":
                        return Registry.LocalMachine;
                    case "HKPD":
                    case "HKEY_PERFORMANCE_DATA":
                        return Registry.PerformanceData;
                    case "HKU":
                    case "HKEY_USERS":
                        return Registry.Users;
                }

                return null;
            }

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

            public static MockRegistryKey OpenSubKey(
                MockRegistryKey rootKey,
                string subKeyName,
                bool writable,
                bool whatIf,
                bool verbose
                )
            {
                if (rootKey == null)
                    return null;

                if (verbose)
                    TraceOps.DebugAndTrace(writable ?
                        TracePriority.Highest : TracePriority.Higher,
                        debugCallback, traceCallback, String.Format(
                        "rootKey = {0}, subKeyName = {1}, writable = {2}",
                        ForDisplay(rootKey), ForDisplay(subKeyName),
                        ForDisplay(writable)), traceCategory);

                //
                // HACK: Always forbid writable access when operating in
                //       'what-if' mode.
                //
                MockRegistryKey key = rootKey.OpenSubKey(
                    subKeyName, whatIf ? false : writable);

                return (key != null) ?
                    new MockRegistryKey(key, whatIf, false, false) : null;
            }

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

            public static MockRegistryKey CreateSubKey(
                MockRegistryKey rootKey,
                string subKeyName,
                bool whatIf,
                bool verbose
                )
            {
                if (rootKey == null)
                    return null;

                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "rootKey = {0}, subKeyName = {1}",
                        ForDisplay(rootKey), ForDisplay(subKeyName)),
                        traceCategory);

                try
                {
                    //
                    // HACK: Always open a key, rather than creating one when
                    //       operating in 'what-if' mode.
                    //
                    if (whatIf)
                    {
                        //
                        // HACK: Attempt to open the specified sub-key.  If
                        //       this fails, we will simply return the root
                        //       key itself since no writes are allowed in
                        //       'what-if' mode anyhow.
                        //
                        MockRegistryKey key = rootKey.OpenSubKey(subKeyName);

                        return (key != null) ?
                            key : new MockRegistryKey(
                                rootKey, subKeyName, true, false, false);
                    }
                    else
                    {
                        return new MockRegistryKey(
                            rootKey.CreateSubKey(subKeyName), false, false,
                            false);
                    }
                }
                finally
                {
                    subKeysCreated++;
                }
            }

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

            public static void DeleteSubKey(
                MockRegistryKey rootKey,
                string subKeyName,
                bool whatIf,
                bool verbose
                )
            {
                if (rootKey == null)
                    return;

                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "rootKey = {0}, subKeyName = {1}",
                        ForDisplay(rootKey), ForDisplay(subKeyName)),
                        traceCategory);

                if (!whatIf)
                    rootKey.DeleteSubKey(subKeyName);

                subKeysDeleted++;
            }

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

            public static void DeleteSubKeyTree(
                MockRegistryKey rootKey,
                string subKeyName,
                bool whatIf,
                bool verbose
                )
            {
                if (rootKey == null)
                    return;

                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "rootKey = {0}, subKeyName = {1}",
                        ForDisplay(rootKey), ForDisplay(subKeyName)),
                        traceCategory);

                if (!whatIf)
                    rootKey.DeleteSubKeyTree(subKeyName);

                subKeysDeleted++;
            }

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

            public static string[] GetSubKeyNames(
                MockRegistryKey key,
                bool whatIf,
                bool verbose
                )
            {
                if (key == null)
                    return null;

                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.High,
                        debugCallback, traceCallback, String.Format(
                        "key = {0}", ForDisplay(key)), traceCategory);

                return key.GetSubKeyNames();
            }

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

            public static object GetValue(
                MockRegistryKey key,
                string name,
                object defaultValue,
                bool whatIf,
                bool verbose
                )
            {
                if (key == null)
                    return null;

                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.High,
                        debugCallback, traceCallback, String.Format(
                        "key = {0}, name = {1}, defaultValue = {2}",
                        ForDisplay(key), ForDisplay(name),
                        ForDisplay(defaultValue)), traceCategory);

                return key.GetValue(name, defaultValue);
            }

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

            public static void SetValue(
                MockRegistryKey key,
                string name,
                object value,
                bool whatIf,
                bool verbose
                )
            {
                if (key == null)
                    return;

                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "key = {0}, name = {1}, value = {2}",
                        ForDisplay(key), ForDisplay(name), ForDisplay(value)),
                        traceCategory);

                if (!whatIf)
                    key.SetValue(name, value);

                keyValuesSet++;
            }

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

            public static void DeleteValue(
                MockRegistryKey key,
                string name,
                bool whatIf,
                bool verbose
                )
            {
                if (key == null)
                    return;

                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "key = {0}, name = {1}", ForDisplay(key),
                        ForDisplay(name)), traceCategory);

                if (!whatIf)
                    key.DeleteValue(name);

                keyValuesDeleted++;
            }
            #endregion
        }
        #endregion

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

        #region StringList Class
        private sealed class StringList : List<string>
        {
            public StringList()
                : base()
            {
                // do nothing.
            }

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

            public StringList(IEnumerable<string> collection)
                : base(collection)
            {
                // do nothing.
            }
        }
        #endregion

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

        #region StringDictionary Class
        private sealed class StringDictionary : Dictionary<string, string>
        {
            public StringDictionary()
            {
                // do nothing.
            }
        }
        #endregion

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

        #region VersionList Class
        private sealed class VersionList : List<Version>
        {
            public VersionList()
                : base()
            {
                // do nothing.
            }

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

            public VersionList(IEnumerable<Version> collection)
                : base(collection)
            {
                // do nothing.
            }
        }
        #endregion

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

        #region VersionMap Class
        private sealed class VersionMap : Dictionary<string, VersionList>
        {
            public VersionMap()
            {
                // do nothing.
            }
        }
        #endregion

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

        #region VersionListMap Class
        private sealed class VersionListMap : Dictionary<Version, VersionList>
        {
            public VersionListMap()
            {
                // do nothing.
            }
        }
        #endregion

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

        #region Package Class
        internal sealed class Package
        {
            #region Public Constructors
            public Package()
            {
                // do nothing.
            }
            #endregion

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

            #region Public Properties
            private Guid packageId;
            public Guid PackageId
            {
                get { return packageId; }
                set { packageId = value; }
            }

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

            private Guid serviceId;
            public Guid ServiceId
            {
                get { return serviceId; }
                set { serviceId = value; }
            }

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

            private Guid dataSourceId;
            public Guid DataSourceId
            {
                get { return dataSourceId; }
                set { dataSourceId = value; }
            }

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

            private Guid dataProviderId;
            public Guid DataProviderId
            {
                get { return dataProviderId; }
                set { dataProviderId = value; }
            }

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

            private Guid adoNetTechnologyId;
            public Guid AdoNetTechnologyId
            {
                get { return adoNetTechnologyId; }
                set { adoNetTechnologyId = value; }
            }
            #endregion
        }
        #endregion

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

        #region Configuration Class
        private sealed class Configuration
        {
            #region Private Constants
            private const char Switch = '-';
            private const char AltSwitch = '/';

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

            private static readonly char[] SwitchChars = {
                Switch, AltSwitch
            };
            #endregion

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

            #region Private Constructors
            private Configuration(
                Assembly assembly,
                string logFileName,
                string directory,
                string coreFileName,
                string linqFileName,
                string designerFileName,
                string debugFormat,
                string traceFormat,
                InstallFlags installFlags,
                TracePriority debugPriority,
                TracePriority tracePriority,
                bool install,
                bool noRuntimeVersion,
                bool noDesktop,
                bool noCompact,
                bool noNetFx20,
                bool noNetFx40,
                bool noVs2008,
                bool noVs2010,
                bool noTrace,
                bool noConsole,
                bool noLog,
                bool whatIf,
                bool verbose,
                bool confirm
                )
            {
                this.assembly = assembly;
                this.logFileName = logFileName;
                this.directory = directory;
                this.coreFileName = coreFileName;
                this.linqFileName = linqFileName;
                this.designerFileName = designerFileName;
                this.debugFormat = debugFormat;
                this.traceFormat = traceFormat;
                this.installFlags = installFlags;
                this.debugPriority = debugPriority;
                this.tracePriority = tracePriority;
                this.install = install;
                this.noRuntimeVersion = noRuntimeVersion;
                this.noDesktop = noDesktop;
                this.noCompact = noCompact;
                this.noNetFx20 = noNetFx20;
                this.noNetFx40 = noNetFx40;
                this.noVs2008 = noVs2008;
                this.noVs2010 = noVs2010;
                this.noTrace = noTrace;
                this.noConsole = noConsole;
                this.noLog = noLog;
                this.whatIf = whatIf;
                this.verbose = verbose;
                this.confirm = confirm;
            }
            #endregion

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

            #region Private Static Methods
            private static void GetDefaultFileNames(
                ref string directory,
                ref string coreFileName,
                ref string linqFileName,
                ref string designerFileName
                )
            {
                if (thisAssembly == null)
                    return;

                directory = Path.GetDirectoryName(thisAssembly.Location);

                if (String.IsNullOrEmpty(directory))
                    return;

                coreFileName = Path.Combine(directory,
                    Installer.CoreFileName);

                linqFileName = Path.Combine(directory,
                    Installer.LinqFileName);

                designerFileName = Path.Combine(directory,
                    Installer.DesignerFileName);
            }

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

            private static bool CheckOption(
                ref string arg
                )
            {
                string result = arg;

                if (!String.IsNullOrEmpty(result))
                {
                    //
                    // NOTE: Remove all leading switch chars.
                    //
                    result = result.TrimStart(SwitchChars);

                    //
                    // NOTE: How many chars were removed?
                    //
                    int count = arg.Length - result.Length;

                    //
                    // NOTE: Was there at least one?
                    //
                    if (count > 0)
                    {
                        //
                        // NOTE: Ok, replace their original
                        //       argument.
                        //
                        arg = result;

                        //
                        // NOTE: Yes, this is a switch.
                        //
                        return true;
                    }
                }

                return false;
            }

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

            private static bool MatchOption(
                string arg,
                string option
                )
            {
                if ((arg == null) || (option == null))
                    return false;

                return String.Compare(arg, 0, option, 0,
                    arg.Length, StringComparison.OrdinalIgnoreCase) == 0;
            }

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

            private static bool? ParseBoolean(
                string text
                )
            {
                if (!String.IsNullOrEmpty(text))
                {
                    bool value;

                    if (bool.TryParse(text, out value))
                        return value;
                }

                return null;
            }

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

            private static object ParseEnum(
                Type enumType,
                string text,
                bool noCase
                )
            {
                if ((enumType == null) || !enumType.IsEnum)
                    return null;

                if (!String.IsNullOrEmpty(text))
                {
                    try
                    {
                        return Enum.Parse(enumType, text, noCase);
                    }
                    catch
                    {
                        // do nothing.
                    }
                }

                return null;
            }
            #endregion

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

            #region Public Static Methods
            public static Configuration CreateDefault()
            {
                string directory = null;
                string coreFileName = null;
                string linqFileName = null;
                string designerFileName = null;

                GetDefaultFileNames(
                    ref directory, ref coreFileName, ref linqFileName,
                    ref designerFileName);

                return new Configuration(thisAssembly, null, directory,
                    coreFileName, linqFileName, designerFileName,
                    TraceOps.DebugFormat, TraceOps.TraceFormat,
                    InstallFlags.Default, TracePriority.Debug,
                    TracePriority.Trace, true, false, false, false, false,
                    false, false, false, false, false, false, true, true,
                    false);
            }

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

            public static bool FromArgs(
                string[] args,
                bool strict,
                ref Configuration configuration,
                ref string error
                )
            {
                try
                {
                    if (args == null)
                        return true;

                    if (configuration == null)
                        configuration = Configuration.CreateDefault();

                    int length = args.Length;

                    for (int index = 0; index < length; index++)
                    {
                        string arg = args[index];

                        //
                        // NOTE: Skip any argument that is null (?) or an empty
                        //       string.
                        //
                        if (String.IsNullOrEmpty(arg))
                            continue;

                        //
                        // NOTE: We are going to modify the original argument
                        //       by removing any leading option characters;
                        //       therefore, we use a new string to hold the
                        //       modified argument.
                        //
                        string newArg = arg;

                        //
                        // NOTE: All the supported command line options must
                        //       begin with an option character (e.g. a minus
                        //       or forward slash); attempt to validate that
                        //       now.  If we fail in strict mode, we are done;
                        //       otherwise, just skip this argument and advance
                        //       to the next one.
                        //
                        if (!CheckOption(ref newArg))
                        {
                            error = TraceOps.DebugAndTrace(
                                TracePriority.Lowest, debugCallback,
                                traceCallback, String.Format(
                                "Unsupported command line argument: {0}",
                                ForDisplay(arg)), traceCategory);

                            if (strict)
                                return false;

                            continue;
                        }

                        //
                        // NOTE: All the supported command line options must
                        //       have a value; therefore, attempt to advance
                        //       to it now.  If we fail, we are done.
                        //
                        index++;

                        if (index >= length)
                        {
                            error = TraceOps.DebugAndTrace(
                                TracePriority.Lowest, debugCallback,
                                traceCallback, String.Format(
                                "Missing value for option: {0}",
                                ForDisplay(arg)), traceCategory);

                            if (strict)
                                return false;

                            break;
                        }

                        //
                        // NOTE: Grab the textual value of this command line
                        //       option.
                        //
                        string text = args[index];

                        //
                        // NOTE: Figure out which command line option this is
                        //       (based on a partial name match) and then try
                        //       to interpret the textual value as the correct
                        //       type.
                        //
                        if (MatchOption(newArg, "strict"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            //
                            // NOTE: Allow the command line arguments to
                            //       override the "strictness" setting
                            //       provided by our caller.
                            //
                            strict = (bool)value;
                        }
                        else if (MatchOption(newArg, "logFileName"))
                        {
                            configuration.logFileName = text;
                        }
                        else if (MatchOption(newArg, "directory"))
                        {
                            configuration.directory = text;

                            //
                            // NOTE: *SPECIAL* Must refresh the file names
                            //       here because the underlying directory
                            //       has changed.
                            //
                            string coreFileName = configuration.coreFileName;

                            if (!String.IsNullOrEmpty(coreFileName))
                                coreFileName = Path.GetFileName(coreFileName);

                            if (String.IsNullOrEmpty(coreFileName))
                                coreFileName = Installer.CoreFileName;

                            configuration.coreFileName = Path.Combine(
                                configuration.directory, coreFileName);

                            string linqFileName = configuration.linqFileName;

                            if (!String.IsNullOrEmpty(linqFileName))
                                linqFileName = Path.GetFileName(linqFileName);

                            if (String.IsNullOrEmpty(linqFileName))
                                linqFileName = Installer.LinqFileName;

                            configuration.linqFileName = Path.Combine(
                                configuration.directory, linqFileName);

                            string designerFileName = configuration.designerFileName;

                            if (!String.IsNullOrEmpty(designerFileName))
                                designerFileName = Path.GetFileName(designerFileName);

                            if (String.IsNullOrEmpty(designerFileName))
                                designerFileName = Installer.DesignerFileName;

                            configuration.designerFileName = Path.Combine(
                                configuration.directory, designerFileName);
                        }
                        else if (MatchOption(newArg, "coreFileName"))
                        {
                            configuration.coreFileName = text;
                        }
                        else if (MatchOption(newArg, "linqFileName"))
                        {
                            configuration.linqFileName = text;
                        }
                        else if (MatchOption(newArg, "designerFileName"))
                        {
                            configuration.designerFileName = text;
                        }
                        else if (MatchOption(newArg, "debugFormat"))
                        {
                            configuration.debugFormat = text;
                            TraceOps.DebugFormat = configuration.debugFormat;
                        }
                        else if (MatchOption(newArg, "traceFormat"))
                        {
                            configuration.traceFormat = text;
                            TraceOps.TraceFormat = configuration.traceFormat;
                        }
                        else if (MatchOption(newArg, "debugPriority"))
                        {
                            object value = ParseEnum(
                                typeof(TracePriority), text, true);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.debugPriority = (TracePriority)value;
                            TraceOps.DebugPriority = configuration.debugPriority;
                        }
                        else if (MatchOption(newArg, "tracePriority"))
                        {
                            object value = ParseEnum(
                                typeof(TracePriority), text, true);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.tracePriority = (TracePriority)value;
                            TraceOps.TracePriority = configuration.tracePriority;
                        }
                        else if (MatchOption(newArg, "install"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.install = (bool)value;
                        }
                        else if (MatchOption(newArg, "installFlags"))
                        {
                            object value = ParseEnum(
                                typeof(InstallFlags), text, true);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid install flags value: {0}",
                                    ForDisplay(text)), traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.installFlags = (InstallFlags)value;
                        }
                        else if (MatchOption(newArg, "noRuntimeVersion"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noRuntimeVersion = (bool)value;
                        }
                        else if (MatchOption(newArg, "whatIf"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.whatIf = (bool)value;
                        }
                        else if (MatchOption(newArg, "verbose"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.verbose = (bool)value;
                        }
                        else if (MatchOption(newArg, "confirm"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.confirm = (bool)value;
                        }
                        else if (MatchOption(newArg, "noDesktop"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noDesktop = (bool)value;
                        }
                        else if (MatchOption(newArg, "noCompact"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noCompact = (bool)value;
                        }
                        else if (MatchOption(newArg, "noNetFx20"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noNetFx20 = (bool)value;
                        }
                        else if (MatchOption(newArg, "noNetFx40"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noNetFx40 = (bool)value;
                        }
                        else if (MatchOption(newArg, "noVs2008"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noVs2008 = (bool)value;
                        }
                        else if (MatchOption(newArg, "noVs2010"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noVs2010 = (bool)value;
                        }
                        else if (MatchOption(newArg, "noTrace"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noTrace = (bool)value;
                        }
                        else if (MatchOption(newArg, "noConsole"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noConsole = (bool)value;
                        }
                        else if (MatchOption(newArg, "noLog"))
                        {
                            bool? value = ParseBoolean(text);

                            if (value == null)
                            {
                                error = TraceOps.DebugAndTrace(
                                    TracePriority.Lowest, debugCallback,
                                    traceCallback, String.Format(
                                    "Invalid {0} boolean value: {1}",
                                    ForDisplay(arg), ForDisplay(text)),
                                    traceCategory);

                                if (strict)
                                    return false;

                                continue;
                            }

                            configuration.noLog = (bool)value;
                        }
                        else
                        {
                            error = TraceOps.DebugAndTrace(
                                TracePriority.Lowest, debugCallback,
                                traceCallback, String.Format(
                                "Unsupported command line option: {0}",
                                ForDisplay(arg)), traceCategory);

                            if (strict)
                                return false;
                        }
                    }

                    return true;
                }
                catch (Exception e)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, e, traceCategory);

                    error = "Failed to modify configuration.";
                }

                return false;
            }

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

            public static bool Process(
                string[] args,
                Configuration configuration,
                bool strict,
                ref string error
                )
            {
                try
                {
                    if (configuration == null)
                    {
                        error = "Invalid configuration.";
                        return false;
                    }

                    Assembly assembly = configuration.assembly;

                    if (assembly == null)
                    {
                        error = "Invalid assembly.";
                        return false;
                    }

                    if (!configuration.noTrace)
                    {
                        if (!configuration.noLog &&
                            String.IsNullOrEmpty(configuration.logFileName))
                        {
                            configuration.logFileName = GetLogFileName();
                        }

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

                        if (!configuration.noConsole)
                        {
                            //
                            // NOTE: In verbose mode, debug output (that meets
                            //       the configured priority criteria) will be
                            //       displayed to the console; otherwise, trace
                            //       output (that meets the configured priority
                            //       criteria) will be displayed to the console.
                            //
                            if (!configuration.verbose)
                            {
                                Trace.Listeners.Add(new ConsoleTraceListener());
                            }
#if DEBUG
                            else
                            {
                                //
                                // NOTE: For a build with "DEBUG" defined, we
                                //       can simply use the Debug class;
                                //       otherwise, the console will be used
                                //       directly (by DebugCore).
                                //
                                Debug.Listeners.Add(new ConsoleTraceListener());
                            }
#endif
                        }

                        if (!configuration.noLog &&
                            !String.IsNullOrEmpty(configuration.logFileName))
                        {
                            Trace.Listeners.Add(new TextWriterTraceListener(
                                configuration.logFileName));
                        }
                    }

                    //
                    // NOTE: Dump the configuration now in case we need to
                    //       troubleshoot any issues.
                    //
                    if (configuration.debugPriority <= TracePriority.Medium)
                        configuration.Dump(debugCallback);

                    if (configuration.tracePriority <= TracePriority.Medium)
                        configuration.Dump(traceCallback);

                    //
                    // NOTE: Show where we are running from and how we were
                    //       invoked.
                    //
                    string location = assembly.Location;

                    TraceOps.DebugAndTrace(TracePriority.Medium,
                        debugCallback, traceCallback, String.Format(
                        "Running executable is: {0}", ForDisplay(location)),
                        traceCategory);

                    TraceOps.DebugAndTrace(TracePriority.Medium,
                        debugCallback, traceCallback, String.Format(
                        "Original command line is: {0}",
                        Environment.CommandLine), traceCategory);

                    if (!configuration.whatIf)
                    {
                        //
                        // NOTE: If the debugger is attached and What-If mode
                        //       is [now] disabled, issue a warning.
                        //
                        if (Debugger.IsAttached)
                            TraceOps.DebugAndTrace(TracePriority.Medium,
                                debugCallback, traceCallback,
                                "Forced to disable \"what-if\" mode with " +
                                "debugger attached.", traceCategory);
                    }
                    else
                    {
                        TraceOps.DebugAndTrace(TracePriority.Higher,
                            debugCallback, traceCallback,
                            "No actual changes will be made to this " +
                            "system because \"what-if\" mode is enabled.",
                            traceCategory);
                    }

                    //
                    // NOTE: If the command line has not been manually
                    //       confirmed (i.e. via the explicit command line
                    //       option), then stop processing now.  We enforce
                    //       this rule so that simply double-clicking the
                    //       executable will not result in any changes being
                    //       made to the system.
                    //
                    if (!configuration.confirm)
                    {
                        error = "Cannot continue, the \"confirm\" option is " +
                            "not enabled.";

                        return false;
                    }

                    return true;
                }
                catch (Exception e)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, e, traceCategory);

                    error = "Failed to process configuration.";
                }

                return false;
            }

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

            public static bool CheckRuntimeVersion(
                Configuration configuration,
                bool strict,
                ref string error
                )
            {
                try
                {
                    if (configuration == null)
                    {
                        error = "Invalid configuration.";
                        return false;
                    }

                    //
                    // NOTE: What version of the runtime was the core (primary)
                    //       assembly compiled against (e.g. "v2.0.50727" or
                    //       "v4.0.30319").
                    //
                    string coreImageRuntimeVersion = GetImageRuntimeVersion(
                        configuration.coreFileName);

                    //
                    // NOTE: We allow the actual image runtime checking to be
                    //       bypassed via the "-noRuntimeVersion" command line
                    //       option.  The command line option is intended for
                    //       expert use only.
                    //
                    if (configuration.noRuntimeVersion)
                    {
                        TraceOps.DebugAndTrace(TracePriority.Medium,
                            debugCallback, traceCallback, String.Format(
                            "Assembly is compiled for the .NET Framework {0}; " +
                            "however, installation restrictions based on this " +
                            "fact have been disabled via the command line.",
                            coreImageRuntimeVersion), traceCategory);

                        return true;
                    }

                    //
                    // TODO: Restrict the configuration based on which image
                    //       runtime versions (which more-or-less correspond
                    //       to .NET Framework versions) are supported by the
                    //       versions of Visual Studio that are installed.
                    //
                    if (String.IsNullOrEmpty(coreImageRuntimeVersion))
                    {
                        error = "invalid core file image runtime version";
                        return false;
                    }
                    else if (String.Equals(
                            coreImageRuntimeVersion, CLRv2ImageRuntimeVersion,
                            StringComparison.InvariantCulture))
                    {
                        //
                        // NOTE: For the CLR v2.0 runtime, make sure we disable
                        //       any attempt to use it for things that require
                        //       an assembly compiled for the CLR v4.0.  It is
                        //       uncertain if this is actually a problem in
                        //       practice as the CLR v4.0 can load and use an
                        //       assembly compiled with the CLR v2.0; however,
                        //       since this project offers both configurations,
                        //       we currently disallow this mismatch.
                        //
                        configuration.noNetFx40 = true;
                        configuration.noVs2010 = true;

                        TraceOps.DebugAndTrace(TracePriority.Medium,
                            debugCallback, traceCallback, String.Format(
                            "Assembly is compiled for the .NET Framework {0}, " +
                            "support for .NET Framework {1} is now disabled.",
                            CLRv2ImageRuntimeVersion, CLRv4ImageRuntimeVersion),
                            traceCategory);
                    }
                    else if (String.Equals(
                            coreImageRuntimeVersion, CLRv4ImageRuntimeVersion,
                            StringComparison.InvariantCulture))
                    {
                        //
                        // NOTE: For the CLR v4.0 runtime, make sure we disable
                        //       any attempt to use it for things that require
                        //       an assembly compiled for the CLR v2.0.
                        //
                        configuration.noNetFx20 = true;
                        configuration.noVs2008 = true;

                        TraceOps.DebugAndTrace(TracePriority.Medium,
                            debugCallback, traceCallback, String.Format(
                            "Assembly is compiled for the .NET Framework {0}, " +
                            "support for .NET Framework {1} is now disabled.",
                            ForDisplay(CLRv4ImageRuntimeVersion),
                            ForDisplay(CLRv2ImageRuntimeVersion)),
                            traceCategory);
                    }
                    else
                    {
                        error = String.Format(
                            "unsupported core file image runtime version " +
                            "{0}, must be {1} or {2}",
                            ForDisplay(coreImageRuntimeVersion),
                            ForDisplay(CLRv2ImageRuntimeVersion),
                            ForDisplay(CLRv4ImageRuntimeVersion));

                        return false;
                    }

                    return true;
                }
                catch (Exception e)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, e, traceCategory);

                    error = "Failed to check image runtime version.";
                }

                return false;
            }
            #endregion

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

            #region Public Methods
            public bool HasFlags(
                InstallFlags hasFlags,
                bool all
                )
            {
                if (all)
                    return ((installFlags & hasFlags) == hasFlags);
                else
                    return ((installFlags & hasFlags) != InstallFlags.None);
            }

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

            public void Dump(
                TraceCallback traceCallback
                )
            {
                if (traceCallback != null)
                {
                    traceCallback(String.Format(NameAndValueFormat,
                        "Assembly", ForDisplay(assembly)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "LogFileName", ForDisplay(logFileName)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "Directory", ForDisplay(directory)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "CoreFileName", ForDisplay(coreFileName)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "LinqFileName", ForDisplay(linqFileName)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "DesignerFileName", ForDisplay(designerFileName)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "DebugFormat", ForDisplay(debugFormat)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "TraceFormat", ForDisplay(traceFormat)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "InstallFlags", ForDisplay(installFlags)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "DebugPriority", ForDisplay(debugPriority)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "TracePriority", ForDisplay(tracePriority)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "Install", ForDisplay(install)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoRuntimeVersion", ForDisplay(noRuntimeVersion)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoDesktop", ForDisplay(noDesktop)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoCompact", ForDisplay(noCompact)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoNetFx20", ForDisplay(noNetFx20)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoNetFx40", ForDisplay(noNetFx40)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoVs2008", ForDisplay(noVs2008)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoVs2010", ForDisplay(noVs2010)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoTrace", ForDisplay(noTrace)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoConsole", ForDisplay(noConsole)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "NoLog", ForDisplay(noLog)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "WhatIf", ForDisplay(whatIf)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "Verbose", ForDisplay(verbose)),
                        traceCategory);

                    traceCallback(String.Format(NameAndValueFormat,
                        "Confirm", ForDisplay(confirm)),
                        traceCategory);
                }
            }
            #endregion

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

            #region Public Properties
            private Assembly assembly;
            public Assembly Assembly
            {
                get { return assembly; }
                set { assembly = value; }
            }

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

            private string logFileName;
            public string LogFileName
            {
                get { return logFileName; }
                set { logFileName = value; }
            }

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

            private string directory;
            public string Directory
            {
                get { return directory; }
                set { directory = value; }
            }

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

            private string coreFileName;
            public string CoreFileName
            {
                get { return coreFileName; }
                set { coreFileName = value; }
            }

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

            private string linqFileName;
            public string LinqFileName
            {
                get { return linqFileName; }
                set { linqFileName = value; }
            }

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

            private string designerFileName;
            public string DesignerFileName
            {
                get { return designerFileName; }
                set { designerFileName = value; }
            }

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

            private string debugFormat;
            public string DebugFormat
            {
                get { return debugFormat; }
                set { debugFormat = value; }
            }

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

            private string traceFormat;
            public string TraceFormat
            {
                get { return traceFormat; }
                set { traceFormat = value; }
            }

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

            private InstallFlags installFlags;
            public InstallFlags InstallFlags
            {
                get { return installFlags; }
                set { installFlags = value; }
            }

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

            private TracePriority debugPriority;
            public TracePriority DebugPriority
            {
                get { return debugPriority; }
                set { debugPriority = value; }
            }

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

            private TracePriority tracePriority;
            public TracePriority TracePriority
            {
                get { return tracePriority; }
                set { tracePriority = value; }
            }

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

            private bool install;
            public bool Install
            {
                get { return install; }
                set { install = value; }
            }

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

            private bool noRuntimeVersion;
            public bool NoRuntimeVersion
            {
                get { return noRuntimeVersion; }
                set { noRuntimeVersion = value; }
            }

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

            private bool noDesktop;
            public bool NoDesktop
            {
                get { return noDesktop; }
                set { noDesktop = value; }
            }

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

            private bool noCompact;
            public bool NoCompact
            {
                get { return noCompact; }
                set { noCompact = value; }
            }

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

            private bool noNetFx20;
            public bool NoNetFx20
            {
                get { return noNetFx20; }
                set { noNetFx20 = value; }
            }

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

            private bool noNetFx40;
            public bool NoNetFx40
            {
                get { return noNetFx40; }
                set { noNetFx40 = value; }
            }

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

            private bool noVs2008;
            public bool NoVs2008
            {
                get { return noVs2008; }
                set { noVs2008 = value; }
            }

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

            private bool noVs2010;
            public bool NoVs2010
            {
                get { return noVs2010; }
                set { noVs2010 = value; }
            }

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

            private bool noTrace;
            public bool NoTrace
            {
                get { return noTrace; }
                set { noTrace = value; }
            }

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

            private bool noConsole;
            public bool NoConsole
            {
                get { return noConsole; }
                set { noConsole = value; }
            }

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

            private bool noLog;
            public bool NoLog
            {
                get { return noLog; }
                set { noLog = value; }
            }

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

            private bool whatIf;
            public bool WhatIf
            {
                get { return whatIf; }
                set { whatIf = value; }
            }

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

            private bool verbose;
            public bool Verbose
            {
                get { return verbose; }
                set { verbose = value; }
            }

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

            private bool confirm;
            public bool Confirm
            {
                get { return confirm; }
                set { confirm = value; }
            }
            #endregion
        }
        #endregion

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

        #region FrameworkList Class
        private sealed class FrameworkList
        {
            #region Public Constructors
            public FrameworkList()
            {
                // do nothing.
            }
            #endregion

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

            #region Public Methods
            private RegistryKey rootKey;
            public RegistryKey RootKey
            {
                get { return rootKey; }
                set { rootKey = value; }
            }

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

            private StringList names;
            public StringList Names
            {
                get { return names; }
                set { names = value; }
            }

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

            private VersionMap versions;
            public VersionMap Versions
            {
                get { return versions; }
                set { versions = value; }
            }

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

            private StringList platformNames;
            public StringList PlatformNames
            {
                get { return platformNames; }
                set { platformNames = value; }
            }
            #endregion
        }
        #endregion

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

        #region VsList Class
        private sealed class VsList
        {
            #region Public Constructors
            public VsList()
            {
                // do nothing.
            }
            #endregion

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

            #region Public Properties
            private RegistryKey rootKey;
            public RegistryKey RootKey
            {
                get { return rootKey; }
                set { rootKey = value; }
            }

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

            private VersionList versions;
            public VersionList Versions
            {
                get { return versions; }
                set { versions = value; }
            }

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

            private VersionListMap frameworkVersions;
            public VersionListMap FrameworkVersions
            {
                get { return frameworkVersions; }
                set { frameworkVersions = value; }
            }

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

            private VersionList installedVersions;
            public VersionList InstalledVersions
            {
                get { return installedVersions; }
                set { installedVersions = value; }
            }
            #endregion
        }
        #endregion
        #endregion

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

        #region Private Constant Data
        private const string CoreFileName = "System.Data.SQLite.dll";
        private const string LinqFileName = "System.Data.SQLite.Linq.dll";
        private const string DesignerFileName = "SQLite.Designer.dll";
        private const string ProviderName = "SQLite Data Provider";
        private const string ProjectName = "System.Data.SQLite";
        private const string LegacyProjectName = "SQLite";
        private const string InvariantName = "System.Data.SQLite";
        private const string FactoryTypeName = "System.Data.SQLite.SQLiteFactory";
        private const string Description = ".NET Framework Data Provider for SQLite";

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

        private const string CLRv2ImageRuntimeVersion = "v2.0.50727";
        private const string CLRv4ImageRuntimeVersion = "v4.0.30319";

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

        private const string NameAndValueFormat = "{0}: {1}";
        private const string LogFileSuffix = ".log";

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

        private static readonly string VsIdFormat = "B";

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

        private static readonly string FrameworkKeyName =
            "Software\\Microsoft\\.NETFramework";

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

        private static readonly string FrameworkSdkKeyName =
            "Software\\Microsoft\\Microsoft SDKs\\.NETFramework";

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

        private static readonly string WindowsSdkKeyName =
            "Software\\Microsoft\\Microsoft SDKs\\Windows";

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

        private static readonly string XPathForAddElement =
            "configuration/system.data/DbProviderFactories/add[@invariant=\"{0}\"]";

        private static readonly string XPathForRemoveElement =
            "configuration/system.data/DbProviderFactories/remove[@invariant=\"{0}\"]";
        #endregion

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

        #region Private Static Data
        private static Assembly thisAssembly = Assembly.GetExecutingAssembly();

        private static string traceCategory = Path.GetFileName(
            thisAssembly.Location); /* NOTE: Same for debug and trace. */

        private static TraceCallback debugCallback = AppDebug;
        private static TraceCallback traceCallback = AppTrace;
        #endregion

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

        #region Trace Handling
        private static string GetLogFileName()
        {
            string result = Path.GetTempFileName(); /* throw */

            File.Move(result, result + LogFileSuffix); /* throw */
            result += LogFileSuffix;

            return result;
        }

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

        private static void AppDebug(
            string message,
            string category
            )
        {
            TraceOps.DebugCore(String.Format(
                TraceOps.DebugFormat, TraceOps.NextDebugId(),
                TraceOps.TimeStamp(DateTime.UtcNow), message), category);
        }

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

        private static void AppTrace(
            string message,
            string category
            )
        {
            TraceOps.TraceCore(String.Format(
                TraceOps.TraceFormat, TraceOps.NextTraceId(),
                TraceOps.TimeStamp(DateTime.UtcNow), message), category);
        }
        #endregion

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

        #region Generic String Handling
        private static string ForDisplay(
            object value
            )
        {
            if (value == null)
                return "<null>";

            string result;
            Type type = value.GetType();

            if (type == typeof(XmlElement))
            {
                XmlElement element = (XmlElement)value;

                result = element.OuterXml;
            }
            else if (type == typeof(Version))
            {
                Version version = (Version)value;

                result = String.Format("v{0}", version);
            }
            else
            {
                result = value.ToString();

                if (result.Length == 0)
                    return "<empty>";

                result = String.Format(
                    type.IsSubclassOf(typeof(ValueType)) ? "{0}" : "\"{0}\"",
                    result);
            }

            return result;
        }
        #endregion

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

        #region .NET Framework Handling
        private static string GetImageRuntimeVersion(
            string fileName
            )
        {
            try
            {
                Assembly assembly =
                    Assembly.ReflectionOnlyLoadFrom(fileName); /* throw */

                if (assembly != null)
                    return assembly.ImageRuntimeVersion;
            }
            catch
            {
                // do nothing.
            }

            return null;
        }

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

        private static string GetFrameworkDirectory(
            RegistryKey rootKey,
            Version frameworkVersion,
            bool whatIf,
            bool verbose
            )
        {
            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, FrameworkKeyName, false, whatIf, verbose))
            {
                if (key == null)
                    return null;

                object value = RegistryHelper.GetValue(
                    key, "InstallRoot", null, whatIf, verbose);

                if (!(value is string))
                    return null;

                return Path.Combine(
                    (string)value, String.Format("v{0}", frameworkVersion));
            }
        }

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

        private static string GetSdkBinaryFileName(
            RegistryKey rootKey,
            string fileName,
            bool whatIf,
            bool verbose
            )
        {
            StringDictionary results = new StringDictionary();

            string[] keyNames = {
                FrameworkKeyName,
                FrameworkSdkKeyName,
                WindowsSdkKeyName
            };

            string[] valueNames = {
                "sdkInstallRootv2.0",
                "InstallationFolder",
                "InstallationFolder"
            };

            bool[] useSubKeys = {
                false,
                true,
                true
            };

            for (int index = 0; index < keyNames.Length; index++)
            {
                using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                        rootKey, keyNames[index], false, whatIf, verbose))
                {
                    if (key == null)
                        continue;

                    if (useSubKeys[index])
                    {
                        foreach (string subKeyName in RegistryHelper.GetSubKeyNames(
                                key, whatIf, verbose))
                        {
                            using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                                    key, subKeyName, false, whatIf, verbose))
                            {
                                if (subKey == null)
                                    continue;

                                object value = RegistryHelper.GetValue(
                                    subKey, valueNames[index], null, whatIf,
                                    verbose);

                                if (!(value is string))
                                    continue;

                                string path = (string)value;

                                if (!Directory.Exists(path))
                                    continue;

                                path = Path.Combine(path, "bin");

                                if (!Directory.Exists(path))
                                    continue;

                                if (String.IsNullOrEmpty(fileName))
                                {
                                    results.Add(subKey.Name, path);
                                    continue;
                                }

                                path = Path.Combine(path, fileName);

                                if (File.Exists(path))
                                    results.Add(subKey.Name, path);
                            }
                        }
                    }
                    else
                    {
                        object value = RegistryHelper.GetValue(
                            key, valueNames[index], null, whatIf, verbose);

                        if (!(value is string))
                            continue;

                        string path = (string)value;

                        if (!Directory.Exists(path))
                            continue;

                        path = Path.Combine(path, "bin");

                        if (!Directory.Exists(path))
                            continue;

                        if (String.IsNullOrEmpty(fileName))
                        {
                            results.Add(key.Name, path);
                            continue;
                        }

                        path = Path.Combine(path, fileName);

                        if (File.Exists(path))
                            results.Add(key.Name, path);
                    }
                }
            }

            //
            // NOTE: If we found some results, return the last (latest) one.
            //
            if (results.Count > 0)
                return results[new StringList(results.Keys)[results.Count - 1]];

            return null;
        }
        #endregion

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

        #region Per-Framework/Platform Handling
        private static void InitializeFrameworkList(
            Configuration configuration,
            ref FrameworkList frameworkList
            )
        {
            if (frameworkList == null)
                frameworkList = new FrameworkList();

            if (frameworkList.RootKey == null)
                frameworkList.RootKey = Registry.LocalMachine;

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

            if (frameworkList.Names == null)
            {
                frameworkList.Names = new StringList();

                if ((configuration == null) || !configuration.NoDesktop)
                    frameworkList.Names.Add(".NETFramework");

                if ((configuration == null) || !configuration.NoCompact)
                {
                    frameworkList.Names.Add(".NETCompactFramework");
                    frameworkList.Names.Add(".NETCompactFramework");
                    frameworkList.Names.Add(".NETCompactFramework");
                }
            }

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

            if (frameworkList.Versions == null)
            {
                frameworkList.Versions = new VersionMap();

                if ((configuration == null) || !configuration.NoDesktop)
                {
                    VersionList desktopVersionList = new VersionList();

                    if ((configuration == null) || !configuration.NoNetFx20)
                        desktopVersionList.Add(new Version(2, 0, 50727));

                    if ((configuration == null) || !configuration.NoNetFx40)
                        desktopVersionList.Add(new Version(4, 0, 30319));

                    frameworkList.Versions.Add(".NETFramework",
                        desktopVersionList);
                }

                if ((configuration == null) || !configuration.NoCompact)
                {
                    frameworkList.Versions.Add(".NETCompactFramework",
                        new VersionList(new Version[] {
                        new Version(2, 0, 0, 0), new Version(3, 5, 0, 0)
                    }));
                }
            }

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

            if (frameworkList.PlatformNames == null)
            {
                frameworkList.PlatformNames = new StringList();

                if ((configuration == null) || !configuration.NoDesktop)
                    frameworkList.PlatformNames.Add(null);

                if ((configuration == null) || !configuration.NoCompact)
                {
                    frameworkList.PlatformNames.Add("PocketPC");
                    frameworkList.PlatformNames.Add("Smartphone");
                    frameworkList.PlatformNames.Add("WindowsCE");
                }
            }
        }

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

        private static bool HaveFramework(
            RegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            bool whatIf,
            bool verbose
            )
        {
            string format = !String.IsNullOrEmpty(platformName) ?
                "Software\\Microsoft\\{0}\\v{1}\\{2}" :
                "Software\\Microsoft\\{0}\\v{1}";

            string keyName = String.Format(
                format, frameworkName, frameworkVersion, platformName);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                    return false;

                if (platformName != null) // NOTE: Skip non-desktop.
                    return true;

                string directory = GetFrameworkDirectory(
                    rootKey, frameworkVersion, whatIf, verbose);

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

                if (!Directory.Exists(directory))
                    return false;

                return true;
            }
        }

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

        private static bool ForEachFrameworkConfig(
            FrameworkList frameworkList,
            FrameworkConfigCallback callback,
            string invariant,
            string name,
            string description,
            string typeName,
            AssemblyName assemblyName,
            object clientData,
            bool whatIf,
            bool verbose,
            ref bool saved,
            ref string error
            )
        {
            if (frameworkList == null)
            {
                error = "invalid framework list";
                return false;
            }

            RegistryKey rootKey = frameworkList.RootKey;

            if (rootKey == null)
            {
                error = "invalid root key";
                return false;
            }

            if (!Object.ReferenceEquals(rootKey, Registry.CurrentUser) &&
                !Object.ReferenceEquals(rootKey, Registry.LocalMachine))
            {
                error = "root key must be per-user or per-machine";
                return false;
            }

            if (frameworkList.Names == null)
            {
                error = "no framework names found";
                return false;
            }

            if (frameworkList.Versions == null)
            {
                error = "no framework versions found";
                return false;
            }

            if (frameworkList.PlatformNames == null)
            {
                error = "no platform names found";
                return false;
            }

            if (frameworkList.Names.Count != frameworkList.PlatformNames.Count)
            {
                error = String.Format("framework name count {0} does not " +
                    "match platform name count {1}", frameworkList.Names.Count,
                    frameworkList.PlatformNames.Count);

                return false;
            }

            for (int index = 0; index < frameworkList.Names.Count; index++)
            {
                //
                // NOTE: Grab the name of the framework (e.g. ".NETFramework")
                //       and the name of the platform (e.g. "WindowsCE").
                //
                string frameworkName = frameworkList.Names[index];
                string platformName = frameworkList.PlatformNames[index];

                //
                // NOTE: Skip all non-desktop frameworks (i.e. if the platform
                //       name is not null).
                //
                if (platformName != null)
                    continue;

                //
                // NOTE: Grab the supported versions of this particular
                //       framework.
                //
                VersionList frameworkVersionList;

                if (!frameworkList.Versions.TryGetValue(
                        frameworkName, out frameworkVersionList) ||
                    (frameworkVersionList == null))
                {
                    continue;
                }

                foreach (Version frameworkVersion in frameworkVersionList)
                {
                    TraceOps.DebugAndTrace(TracePriority.Lower,
                        debugCallback, traceCallback, String.Format(
                        "frameworkName = {0}, frameworkVersion = {1}, " +
                        "platformName = {2}", ForDisplay(frameworkName),
                        ForDisplay(frameworkVersion),
                        ForDisplay(platformName)), traceCategory);

                    if (!HaveFramework(
                            rootKey, frameworkName, frameworkVersion,
                            platformName, whatIf, verbose))
                    {
                        TraceOps.DebugAndTrace(TracePriority.Low,
                            debugCallback, traceCallback,
                            ".NET Framework not found, skipping...",
                            traceCategory);

                        continue;
                    }

                    if (callback == null)
                        continue;

                    string directory = GetFrameworkDirectory(
                        rootKey, frameworkVersion, whatIf, verbose);

                    if (String.IsNullOrEmpty(directory))
                    {
                        TraceOps.DebugAndTrace(TracePriority.Low,
                            debugCallback, traceCallback, String.Format(
                            ".NET Framework {0} directory is invalid, " +
                            "skipping...", ForDisplay(frameworkVersion)),
                            traceCategory);

                        continue;
                    }

                    directory = Path.Combine(directory, "Config");

                    if (!Directory.Exists(directory))
                    {
                        TraceOps.DebugAndTrace(TracePriority.Low,
                            debugCallback, traceCallback, String.Format(
                            ".NET Framework {0} directory {1} does not exist, " +
                            "skipping...", ForDisplay(frameworkVersion),
                            ForDisplay(directory)), traceCategory);

                        continue;
                    }

                    string fileName = Path.Combine(directory, "machine.config");

                    if (!File.Exists(fileName))
                    {
                        TraceOps.DebugAndTrace(TracePriority.Low,
                            debugCallback, traceCallback, String.Format(
                            ".NET Framework {0} file {1} does not exist, " +
                            "skipping...", ForDisplay(frameworkVersion),
                            ForDisplay(fileName)), traceCategory);

                        continue;
                    }

                    bool localSaved = false;

                    if (!callback(
                            fileName, invariant, name, description, typeName,
                            assemblyName, clientData, whatIf, verbose,
                            ref localSaved, ref error))
                    {
                        return false;
                    }
                    else
                    {
                        if (localSaved && !saved)
                            saved = true;

                        if (verbose)
                            TraceOps.DebugAndTrace(TracePriority.Lowest,
                                debugCallback, traceCallback, String.Format(
                                "localSaved = {0}, saved = {1}",
                                ForDisplay(localSaved), ForDisplay(saved)),
                                traceCategory);
                    }
                }
            }

            return true;
        }

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

        private static bool ForEachFrameworkRegistry(
            FrameworkList frameworkList,
            FrameworkRegistryCallback callback,
            object clientData,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (frameworkList == null)
            {
                error = "invalid framework list";
                return false;
            }

            RegistryKey rootKey = frameworkList.RootKey;

            if (rootKey == null)
            {
                error = "invalid root key";
                return false;
            }

            if (!Object.ReferenceEquals(rootKey, Registry.CurrentUser) &&
                !Object.ReferenceEquals(rootKey, Registry.LocalMachine))
            {
                error = "root key must be per-user or per-machine";
                return false;
            }

            if (frameworkList.Names == null)
            {
                error = "no framework names found";
                return false;
            }

            if (frameworkList.Versions == null)
            {
                error = "no framework versions found";
                return false;
            }

            if (frameworkList.PlatformNames == null)
            {
                error = "no platform names found";
                return false;
            }

            if (frameworkList.Names.Count != frameworkList.PlatformNames.Count)
            {
                error = String.Format("framework name count {0} does not " +
                    "match platform name count {1}", frameworkList.Names.Count,
                    frameworkList.PlatformNames.Count);

                return false;
            }

            for (int index = 0; index < frameworkList.Names.Count; index++)
            {
                //
                // NOTE: Grab the name of the framework (e.g. ".NETFramework")
                //       and the name of the platform (e.g. "WindowsCE").
                //
                string frameworkName = frameworkList.Names[index];
                string platformName = frameworkList.PlatformNames[index];

                //
                // NOTE: Grab the supported versions of this particular
                //       framework.
                //
                VersionList frameworkVersionList;

                if (!frameworkList.Versions.TryGetValue(
                        frameworkName, out frameworkVersionList) ||
                    (frameworkVersionList == null))
                {
                    continue;
                }

                foreach (Version frameworkVersion in frameworkVersionList)
                {
                    TraceOps.DebugAndTrace(TracePriority.Lower,
                        debugCallback, traceCallback, String.Format(
                        "frameworkName = {0}, frameworkVersion = {1}, " +
                        "platformName = {2}", ForDisplay(frameworkName),
                        ForDisplay(frameworkVersion),
                        ForDisplay(platformName)), traceCategory);

                    if (!HaveFramework(
                            rootKey, frameworkName, frameworkVersion,
                            platformName, whatIf, verbose))
                    {
                        TraceOps.DebugAndTrace(TracePriority.Low,
                            debugCallback, traceCallback,
                            ".NET Framework not found, skipping...",
                            traceCategory);

                        continue;
                    }

                    if (callback == null)
                        continue;

                    if (!callback(
                            rootKey, frameworkName, frameworkVersion,
                            platformName, clientData, whatIf, verbose,
                            ref error))
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        #endregion

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

        #region Per-Visual Studio Version Handling
        private static void InitializeVsList(
            Configuration configuration,
            ref VsList vsList
            )
        {
            if (vsList == null)
                vsList = new VsList();

            if (vsList.RootKey == null)
                vsList.RootKey = Registry.LocalMachine;

            if (vsList.Versions == null)
            {
                vsList.Versions = new VersionList();

                // vsList.Versions.Add(new Version(8, 0)); // Visual Studio 2005

                if ((configuration == null) || !configuration.NoVs2008)
                    vsList.Versions.Add(new Version(9, 0)); // Visual Studio 2008

                if ((configuration == null) || !configuration.NoVs2010)
                    vsList.Versions.Add(new Version(10, 0));// Visual Studio 2010
            }

            if (vsList.FrameworkVersions == null)
            {
                vsList.FrameworkVersions = new VersionListMap();

                // vsList.FrameworkVersions.Add(new Version(8, 0),
                //     new VersionList(new Version[] {
                //         new Version(2, 0, 50727) }));

                if ((configuration == null) || !configuration.NoVs2008)
                    vsList.FrameworkVersions.Add(new Version(9, 0),
                        new VersionList(new Version[] {
                            new Version(2, 0, 50727) }));

                if ((configuration == null) || !configuration.NoVs2010)
                    vsList.FrameworkVersions.Add(new Version(10, 0),
                        new VersionList(new Version[] {
                            new Version(2, 0, 50727),
                                new Version(4, 0, 30319) }));
            }
        }

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

        private static bool HaveVsVersion(
            RegistryKey rootKey,
            Version vsVersion,
            bool whatIf,
            bool verbose
            )
        {
            if (vsVersion == null)
                return false;

            string format = "Software\\Microsoft\\VisualStudio\\{0}";
            string keyName = String.Format(format, vsVersion);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                    return false;

                object value = RegistryHelper.GetValue(
                    key, "InstallDir", null, whatIf, verbose);

                if (!(value is string))
                    return false;

                string directory = (string)value;

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

                if (!Directory.Exists(directory))
                    return false;

                return true;
            }
        }

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

        private static bool ForEachVsVersionRegistry(
            VsList vsList,
            VisualStudioRegistryCallback callback,
            Package package,
            object clientData,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsList == null)
            {
                error = "invalid VS list";
                return false;
            }

            RegistryKey rootKey = vsList.RootKey;

            if (rootKey == null)
            {
                error = "invalid root key";
                return false;
            }

            if (!Object.ReferenceEquals(rootKey, Registry.CurrentUser) &&
                !Object.ReferenceEquals(rootKey, Registry.LocalMachine))
            {
                error = "root key must be per-user or per-machine";
                return false;
            }

            if (vsList.Versions == null)
            {
                error = "no VS versions found";
                return false;
            }

            foreach (Version vsVersion in vsList.Versions)
            {
                TraceOps.DebugAndTrace(TracePriority.Lower,
                    debugCallback, traceCallback, String.Format(
                    "vsVersion = {0}", ForDisplay(vsVersion)),
                    traceCategory);

                if (!HaveVsVersion(rootKey, vsVersion, whatIf, verbose))
                {
                    TraceOps.DebugAndTrace(TracePriority.Low,
                        debugCallback, traceCallback,
                        "Visual Studio version not found, skipping...",
                        traceCategory);

                    continue;
                }

                if (callback == null)
                    continue;

                if (!callback(
                        rootKey, vsVersion, package, clientData, whatIf,
                        verbose, ref error))
                {
                    return false;
                }
            }

            return true;
        }
        #endregion

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

        #region Configuration File Handling
        private static bool AddDbProviderFactory(
            string fileName,
            string invariant,
            string name,
            string description,
            string typeName,
            AssemblyName assemblyName,
            bool whatIf,
            bool verbose,
            ref bool saved,
            ref string error
            )
        {
            bool dirty = false;
            XmlDocument document = new XmlDocument();

            document.PreserveWhitespace = true;
            document.Load(fileName);

            XmlElement element = document.SelectSingleNode(String.Format(
                XPathForAddElement, invariant)) as XmlElement;

            if (element == null)
            {
                string[] elementNames = {
                        "system.data", "DbProviderFactories"
                    };

                XmlElement previousElement =
                    document.DocumentElement; /* configuration */

                foreach (string elementName in elementNames)
                {
                    element = previousElement.SelectSingleNode(
                        elementName) as XmlElement;

                    if (element == null)
                    {
                        element = document.CreateElement(
                            elementName, String.Empty);

                        previousElement.AppendChild(element);
                    }

                    previousElement = element;
                }

                element = document.CreateElement(
                    "add", String.Empty);

                previousElement.AppendChild(element);

                dirty = true;
            }

            if (!String.Equals(element.GetAttribute("name"),
                    name, StringComparison.InvariantCulture))
            {
                element.SetAttribute("name", name);
                dirty = true;
            }

            if (!String.Equals(element.GetAttribute("invariant"),
                    invariant, StringComparison.InvariantCulture))
            {
                element.SetAttribute("invariant", invariant);
                dirty = true;
            }

            if (!String.Equals(element.GetAttribute("description"),
                    description, StringComparison.InvariantCulture))
            {
                element.SetAttribute("description", description);
                dirty = true;
            }

            string fullTypeName = String.Format("{0}, {1}",
                typeName, assemblyName);

            if (!String.Equals(element.GetAttribute("type"),
                    fullTypeName, StringComparison.InvariantCulture))
            {
                element.SetAttribute("type", fullTypeName);
                dirty = true;
            }

            if (dirty || whatIf)
            {
                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "element = {0}", ForDisplay(element)),
                        traceCategory);

                if (!whatIf)
                    document.Save(fileName);

                saved = true;
            }

            return true;
        }

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

        private static bool RemoveDbProviderFactory(
            string fileName,
            string invariant,
            bool whatIf,
            bool verbose,
            ref bool saved,
            ref string error
            )
        {
            bool dirty = false;
            XmlDocument document = new XmlDocument();

            document.PreserveWhitespace = true;
            document.Load(fileName);

            XmlElement element = document.SelectSingleNode(String.Format(
                XPathForAddElement, invariant)) as XmlElement;

            if (element != null)
            {
                element.ParentNode.RemoveChild(element);
                dirty = true;
            }

            element = document.SelectSingleNode(String.Format(
                XPathForRemoveElement, invariant)) as XmlElement;

            if (element != null)
            {
                element.ParentNode.RemoveChild(element);
                dirty = true;
            }

            if (dirty || whatIf)
            {
                if (verbose)
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "element = {0}", ForDisplay(element)),
                        traceCategory);

                if (!whatIf)
                    document.Save(fileName);

                saved = true;
            }

            return true;
        }

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

        private static bool ProcessDbProviderFactory(
            string fileName,
            string invariant,
            string name,
            string description,
            string typeName,
            AssemblyName assemblyName,
            object clientData,
            bool whatIf,
            bool verbose,
            ref bool saved,
            ref string error
            )
        {
            AnyPair<string, bool> pair = clientData as AnyPair<string, bool>;

            if (pair == null)
            {
                error = "invalid framework config callback data";
                return false;
            }

            if (pair.Y)
            {
                return RemoveDbProviderFactory(
                    fileName, invariant, whatIf, verbose, ref saved,
                    ref error) &&
                AddDbProviderFactory(
                    fileName, invariant, name, description, typeName,
                    assemblyName, whatIf, verbose, ref saved, ref error);
            }
            else
            {
                return RemoveDbProviderFactory(
                    fileName, invariant, whatIf, verbose, ref saved,
                    ref error);
            }
        }
        #endregion

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

        #region Assembly Folders Handling
        private static string GetAssemblyFoldersKeyName(
            string frameworkName,
            Version frameworkVersion,
            string platformName
            )
        {
            string format = !String.IsNullOrEmpty(platformName) ?
                "Software\\Microsoft\\{0}\\v{1}\\{2}\\AssemblyFoldersEx" :
                "Software\\Microsoft\\{0}\\v{1}\\AssemblyFoldersEx";

            return String.Format(format, frameworkName, frameworkVersion,
                platformName);
        }

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

        private static bool AddToAssemblyFolders(
            RegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            string subKeyName,
            string directory,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            string keyName = GetAssemblyFoldersKeyName(
                frameworkName, frameworkVersion, platformName);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, true, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.CreateSubKey(
                        key, subKeyName, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not create registry key: {0}\\{1}",
                            key, subKeyName);

                        return false;
                    }

                    RegistryHelper.SetValue(
                        subKey, null, directory, whatIf, verbose);
                }
            }

            return true;
        }

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

        private static bool RemoveFromAssemblyFolders(
            RegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            string subKeyName,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            string keyName = GetAssemblyFoldersKeyName(
                frameworkName, frameworkVersion, platformName);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);

                    return false;
                }

                RegistryHelper.DeleteSubKey(
                    key, subKeyName, whatIf, verbose);
            }

            return true;
        }

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

        private static bool ProcessAssemblyFolders(
            RegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            object clientData,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            AnyPair<string, bool> pair = clientData as AnyPair<string, bool>;

            if (pair == null)
            {
                error = "invalid framework callback data";
                return false;
            }

            if (pair.Y)
            {
                return RemoveFromAssemblyFolders(
                    rootKey, frameworkName, frameworkVersion, platformName,
                    LegacyProjectName, whatIf, verbose, ref error) &&
                AddToAssemblyFolders(
                    rootKey, frameworkName, frameworkVersion, platformName,
                    ProjectName, pair.X, whatIf, verbose, ref error);
            }
            else
            {
                return RemoveFromAssemblyFolders(
                    rootKey, frameworkName, frameworkVersion, platformName,
                    ProjectName, whatIf, verbose, ref error);
            }
        }
        #endregion

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

        #region Visual Studio Handling
        private static string GetVsKeyName(
            Version vsVersion
            )
        {
            if (vsVersion == null)
                return null;

            return String.Format("Software\\Microsoft\\VisualStudio\\{0}",
                vsVersion);
        }

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

        #region Visual Studio Version Handling
        private static bool AddVsVersion(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            object clientData,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion != null)
            {
                VsList vsList = clientData as VsList;

                if (vsList != null)
                {
                    if (vsList.InstalledVersions == null)
                        vsList.InstalledVersions = new VersionList();

                    if (!vsList.InstalledVersions.Contains(vsVersion))
                        vsList.InstalledVersions.Add(vsVersion);
                }
            }

            return true;
        }
        #endregion

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

        #region Visual Studio Data Source Handling
        private static bool AddVsDataSource(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "DataSources", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\DataSources",
                            key);

                        return false;
                    }

                    using (MockRegistryKey dataSourceKey =
                            RegistryHelper.CreateSubKey(subKey,
                            package.DataSourceId.ToString(VsIdFormat),
                            whatIf, verbose))
                    {
                        if (dataSourceKey == null)
                        {
                            error = String.Format(
                                "could not create registry key: {0}\\{1}", key,
                                package.DataSourceId.ToString(VsIdFormat));

                            return false;
                        }

                        RegistryHelper.SetValue(
                            dataSourceKey, null, String.Format(
                            "{0} Database File", ProjectName), whatIf,
                            verbose);

                        RegistryHelper.CreateSubKey(dataSourceKey,
                            String.Format("SupportingProviders\\{0}",
                            package.DataProviderId.ToString(VsIdFormat)),
                            whatIf, verbose);
                    }
                }
            }

            return true;
        }

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

        private static bool RemoveVsDataSource(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "DataSources", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\DataSources",
                            key);

                        return false;
                    }

                    RegistryHelper.DeleteSubKeyTree(
                        subKey, package.DataSourceId.ToString(VsIdFormat),
                        whatIf, verbose);
                }
            }

            return true;
        }

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

        private static bool ProcessVsDataSource(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            object clientData,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            AnyPair<string, bool> pair = clientData as AnyPair<string, bool>;

            if (pair == null)
            {
                error = "invalid VS callback data";
                return false;
            }

            if (pair.Y)
            {
                return AddVsDataSource(
                    rootKey, vsVersion, package, whatIf, verbose, ref error);
            }
            else
            {
                return RemoveVsDataSource(
                    rootKey, vsVersion, package, whatIf, verbose, ref error);
            }
        }
        #endregion

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

        #region Visual Studio Data Provider Handling
        private static bool AddVsDataProvider(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            string fileName,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "DataProviders", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\DataProviders",
                            key);

                        return false;
                    }

                    using (MockRegistryKey dataProviderKey =
                            RegistryHelper.CreateSubKey(subKey,
                            package.DataProviderId.ToString(VsIdFormat),
                            whatIf, verbose))
                    {
                        if (dataProviderKey == null)
                        {
                            error = String.Format(
                                "could not create registry key: {0}\\{1}", key,
                                package.DataProviderId.ToString(VsIdFormat));

                            return false;
                        }

                        RegistryHelper.SetValue(
                            dataProviderKey, null, Description, whatIf,
                            verbose);

                        RegistryHelper.SetValue(
                            dataProviderKey, "InvariantName", InvariantName,
                            whatIf, verbose);

                        RegistryHelper.SetValue(
                            dataProviderKey, "Technology",
                            package.AdoNetTechnologyId.ToString(VsIdFormat),
                            whatIf, verbose);

                        RegistryHelper.SetValue(
                            dataProviderKey, "CodeBase", fileName, whatIf,
                            verbose);

                        RegistryHelper.SetValue(
                            dataProviderKey, "FactoryService",
                            package.ServiceId.ToString(VsIdFormat), whatIf,
                            verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataConnectionUIControl",
                            whatIf, verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataConnectionProperties",
                            whatIf, verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataConnectionSupport", whatIf,
                            verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataObjectSupport", whatIf,
                            verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataViewSupport", whatIf,
                            verbose);
                    }
                }
            }

            return true;
        }

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

        private static bool RemoveVsDataProvider(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "DataProviders", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\DataProviders",
                            key);

                        return false;
                    }

                    RegistryHelper.DeleteSubKeyTree(
                        subKey, package.DataProviderId.ToString(VsIdFormat),
                        whatIf, verbose);
                }
            }

            return true;
        }

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

        private static bool ProcessVsDataProvider(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            object clientData,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            AnyPair<string, bool> pair = clientData as AnyPair<string, bool>;

            if (pair == null)
            {
                error = "invalid VS callback data";
                return false;
            }

            if (pair.Y)
            {
                return AddVsDataProvider(
                    rootKey, vsVersion, package, pair.X,
                    whatIf, verbose, ref error);
            }
            else
            {
                return RemoveVsDataProvider(
                    rootKey, vsVersion, package, whatIf,
                    verbose, ref error);
            }
        }
        #endregion

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

        #region Visual Studio Package Handling
        private static void InitializeVsPackage(
            ref Package package
            )
        {
            if (package == null)
            {
                package = new Package();

                package.AdoNetTechnologyId = new Guid(
                    "77AB9A9D-78B9-4BA7-91AC-873F5338F1D2");

                package.PackageId = new Guid(
                    "DCBE6C8D-0E57-4099-A183-98FF74C64D9C");

                package.ServiceId = new Guid(
                    "DCBE6C8D-0E57-4099-A183-98FF74C64D9D");

                package.DataSourceId = new Guid(
                    "0EBAAB6E-CA80-4B4A-8DDF-CBE6BF058C71");

                package.DataProviderId = new Guid(
                    "0EBAAB6E-CA80-4B4A-8DDF-CBE6BF058C70");
            }
        }

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

        private static bool AddVsPackage(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            string fileName,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Packages", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Packages",
                            key);

                        return false;
                    }

                    using (MockRegistryKey packageKey = RegistryHelper.CreateSubKey(
                            subKey, package.PackageId.ToString(VsIdFormat), whatIf,
                            verbose))
                    {
                        if (packageKey == null)
                        {
                            error = String.Format(
                                "could not create registry key: {0}\\{1}",
                                key, package.PackageId.ToString(VsIdFormat));

                            return false;
                        }

                        RegistryHelper.SetValue(packageKey, null, String.Format(
                            "{0} Designer Package", ProjectName), whatIf,
                            verbose);

                        RegistryHelper.SetValue(packageKey, "Class",
                            "SQLite.Designer.SQLitePackage", whatIf, verbose);

                        RegistryHelper.SetValue(packageKey, "CodeBase",
                            fileName, whatIf, verbose);

                        RegistryHelper.SetValue(packageKey, "ID", 400, whatIf,
                            verbose);

                        RegistryHelper.SetValue(packageKey, "InprocServer32",
                            Path.Combine(Environment.SystemDirectory,
                                "mscoree.dll"), whatIf, verbose);

                        RegistryHelper.SetValue(packageKey, "CompanyName",
                            "http://system.data.sqlite.org/", whatIf, verbose);

                        RegistryHelper.SetValue(packageKey, "MinEdition",
                            "standard", whatIf, verbose);

                        RegistryHelper.SetValue(packageKey, "ProductName",
                            String.Format("{0} Designer Package", ProjectName),
                            whatIf, verbose);

                        RegistryHelper.SetValue(packageKey, "ProductVersion",
                            "1.0", whatIf, verbose);

                        using (MockRegistryKey toolboxKey = RegistryHelper.CreateSubKey(
                                packageKey, "Toolbox", whatIf, verbose))
                        {
                            if (toolboxKey == null)
                            {
                                error = String.Format(
                                    "could not create registry key: {0}\\Toolbox",
                                    packageKey);

                                return false;
                            }

                            RegistryHelper.SetValue(
                                toolboxKey, "Default Items", 3, whatIf,
                                verbose);
                        }
                    }
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Menus", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Menus",
                            key);

                        return false;
                    }

                    RegistryHelper.SetValue(
                        subKey, package.PackageId.ToString(VsIdFormat),
                        ", 1000, 3", whatIf, verbose);
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Services", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Services",
                            key);

                        return false;
                    }

                    using (MockRegistryKey serviceKey = RegistryHelper.CreateSubKey(
                            subKey, package.ServiceId.ToString(VsIdFormat), whatIf,
                            verbose))
                    {
                        if (serviceKey == null)
                        {
                            error = String.Format(
                                "could not create registry key: {0}\\{1}",
                                key, package.ServiceId.ToString(VsIdFormat));

                            return false;
                        }

                        RegistryHelper.SetValue(serviceKey, null,
                            package.PackageId.ToString(VsIdFormat), whatIf,
                            verbose);

                        RegistryHelper.SetValue(serviceKey, "Name",
                            String.Format("{0} Designer Service", ProjectName),
                            whatIf, verbose);
                    }
                }
            }

            return true;
        }

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

        private static bool RemoveVsPackage(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Packages", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Packages",
                            key);

                        return false;
                    }

                    RegistryHelper.DeleteSubKeyTree(
                        key, package.PackageId.ToString(VsIdFormat), whatIf,
                        verbose);
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Menus", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Menus",
                            key);

                        return false;
                    }

                    RegistryHelper.DeleteValue(
                        subKey, package.PackageId.ToString(VsIdFormat), whatIf,
                        verbose);
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Services", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Services",
                            key);

                        return false;
                    }

                    RegistryHelper.DeleteSubKeyTree(
                        subKey, package.ServiceId.ToString(VsIdFormat), whatIf,
                        verbose);
                }
            }

            return true;
        }

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

        private static bool ProcessVsPackage(
            RegistryKey rootKey,
            Version vsVersion,
            Package package,
            object clientData,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            AnyPair<string, bool> pair = clientData as AnyPair<string, bool>;

            if (pair == null)
            {
                error = "invalid VS callback data";
                return false;
            }

            if (pair.Y)
            {
                return AddVsPackage(
                    rootKey, vsVersion, package, pair.X, whatIf,
                    verbose, ref error);
            }
            else
            {
                return RemoveVsPackage(
                    rootKey, vsVersion, package, whatIf, verbose,
                    ref error);
            }
        }
        #endregion
        #endregion

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

        #region Application Entry Point
        private static int Main(
            string[] args
            )
        {
            Configuration configuration = null;
            string error = null;

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

            #region Command Line Processing
            if (!Configuration.FromArgs(
                    args, true, ref configuration, ref error) ||
                !Configuration.Process(
                    args, configuration, true, ref error) ||
                !Configuration.CheckRuntimeVersion(
                    configuration, true, ref error))
            {
                TraceOps.ShowMessage(TracePriority.Highest,
                    debugCallback, traceCallback, thisAssembly,
                    error, traceCategory, MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                return 1; /* FAILURE */
            }
            #endregion

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

            #region .NET Framework / Visual Studio Data
            Package package = null;
            FrameworkList frameworkList = null;
            VsList vsList = null;

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

            InitializeVsPackage(ref package);
            InitializeFrameworkList(configuration, ref frameworkList);
            InitializeVsList(configuration, ref vsList);
            #endregion

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

            AssemblyName assemblyName = AssemblyName.GetAssemblyName(
                configuration.CoreFileName); /* throw */

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

            AnyPair<string, bool> directoryPair = new AnyPair<string, bool>(
                configuration.Directory, configuration.Install);

            AnyPair<string, bool> fileNamePair = new AnyPair<string, bool>(
                configuration.DesignerFileName, configuration.Install);

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

            #region .NET GAC Install/Remove
            if (configuration.HasFlags(InstallFlags.GAC, true))
            {
                Publish publish = null;

                if (!configuration.WhatIf)
                    publish = new Publish();

                if (configuration.Install)
                {
                    if (!configuration.WhatIf)
                        publish.GacInstall(configuration.CoreFileName); /* throw */

                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "GacInstall: assemblyPath = {0}",
                        ForDisplay(configuration.CoreFileName)),
                        traceCategory);

                    if (!configuration.WhatIf)
                        publish.GacInstall(configuration.LinqFileName); /* throw */

                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "GacInstall: assemblyPath = {0}",
                        ForDisplay(configuration.LinqFileName)),
                        traceCategory);
                }
                else
                {
                    if (!configuration.WhatIf)
                        publish.GacRemove(configuration.LinqFileName); /* throw */

                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "GacRemove: assemblyPath = {0}",
                        ForDisplay(configuration.LinqFileName)),
                        traceCategory);

                    if (!configuration.WhatIf)
                        publish.GacRemove(configuration.CoreFileName); /* throw */

                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "GacRemove: assemblyPath = {0}",
                        ForDisplay(configuration.CoreFileName)),
                        traceCategory);
                }
            }
            #endregion

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

            #region .NET AssemblyFolders
            if (configuration.HasFlags(InstallFlags.AssemblyFolders, true))
            {
                if (!ForEachFrameworkRegistry(
                        frameworkList, ProcessAssemblyFolders,
                        directoryPair, configuration.WhatIf,
                        configuration.Verbose, ref error))
                {
                    TraceOps.ShowMessage(TracePriority.Highest,
                        debugCallback, traceCallback, thisAssembly,
                        error, traceCategory, MessageBoxButtons.OK,
                        MessageBoxIcon.Error);

                    return 1; /* FAILURE */
                }
            }
            #endregion

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

            #region .NET DbProviderFactory
            if (configuration.HasFlags(InstallFlags.DbProviderFactory, true))
            {
                bool saved = false;

                if (!ForEachFrameworkConfig(
                        frameworkList, ProcessDbProviderFactory,
                        InvariantName, ProviderName, Description,
                        FactoryTypeName, assemblyName, directoryPair,
                        configuration.WhatIf, configuration.Verbose,
                        ref saved, ref error))
                {
                    TraceOps.ShowMessage(TracePriority.Highest,
                        debugCallback, traceCallback, thisAssembly,
                        error, traceCategory, MessageBoxButtons.OK,
                        MessageBoxIcon.Error);

                    return 1; /* FAILURE */
                }
            }
            #endregion

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

            #region VS Package
            if (configuration.HasFlags(InstallFlags.VsPackage, true))
            {
                if (!ForEachVsVersionRegistry(
                        vsList, ProcessVsPackage, package, fileNamePair,
                        configuration.WhatIf, configuration.Verbose,
                        ref error))
                {
                    TraceOps.ShowMessage(TracePriority.Highest,
                        debugCallback, traceCallback, thisAssembly,
                        error, traceCategory, MessageBoxButtons.OK,
                        MessageBoxIcon.Error);

                    return 1; /* FAILURE */
                }
            }
            #endregion

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

            #region VS DataSource
            if (configuration.HasFlags(InstallFlags.VsDataSource, true))
            {
                if (!ForEachVsVersionRegistry(
                        vsList, ProcessVsDataSource, package, fileNamePair,
                        configuration.WhatIf, configuration.Verbose,
                        ref error))
                {
                    TraceOps.ShowMessage(TracePriority.Highest,
                        debugCallback, traceCallback, thisAssembly,
                        error, traceCategory, MessageBoxButtons.OK,
                        MessageBoxIcon.Error);

                    return 1; /* FAILURE */
                }
            }
            #endregion

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

            #region VS DataProvider
            if (configuration.HasFlags(InstallFlags.VsDataProvider, true))
            {
                if (!ForEachVsVersionRegistry(
                        vsList, ProcessVsDataProvider, package, fileNamePair,
                        configuration.WhatIf, configuration.Verbose,
                        ref error))
                {
                    TraceOps.ShowMessage(TracePriority.Highest,
                        debugCallback, traceCallback, thisAssembly,
                        error, traceCategory, MessageBoxButtons.OK,
                        MessageBoxIcon.Error);

                    return 1; /* FAILURE */
                }
            }
            #endregion

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

            #region Log Summary
            TraceOps.DebugAndTrace(TracePriority.Higher,
                debugCallback, traceCallback, String.Format(
                "subKeysCreated = {0}, subKeysDeleted = {1}, " +
                "keyValuesSet = {2}, keyValuesDeleted = {3}",
                ForDisplay(RegistryHelper.SubKeysCreated),
                ForDisplay(RegistryHelper.SubKeysDeleted),
                ForDisplay(RegistryHelper.KeyValuesSet),
                ForDisplay(RegistryHelper.KeyValuesDeleted)),
                traceCategory);
            #endregion

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

            return 0; /* SUCCESS */
        }
        #endregion
    }
    #endregion
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted tools/install/Properties/AssemblyInfo.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
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite Designer Installer")]
[assembly: AssemblyDescription("ADO.NET Data Provider for SQLite")]
[assembly: AssemblyCompany("http://system.data.sqlite.org/")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.77.0")]
[assembly: AssemblyFileVersion("1.0.77.0")]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































Deleted www/art/sqlite100.png.

cannot compute difference between binary files

Deleted www/art/sqlite200.png.

cannot compute difference between binary files

Deleted www/art/sqlite32.png.

cannot compute difference between binary files

Deleted www/build.wiki.
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
<title>Build Procedures</title>

<a name="procedures"></a>
<h2>Build Procedures</h2>

<p>
  Follow these steps to build the System.Data.SQLite (SDS) binaries.
  Unless otherwise noted, all steps need to be done in the order specified.
</p>

<p>
  You will need a Visual Studio 2008, 2008 SP1, 2010, or 2010 SP1 development
  environment for this build.
</p>

<p>
  The new build system has been setup using modular solution, project, and
  property files.
</p>

<p>
  In general, files with 2008 in the name (e.g.
  &quot;SQLite.Interop.2008.vcproj&quot;) or files ending in
  &quot;.vsprops&quot; are project and property files for the Visual Studio 2008
  solution.  Files with 2010 in the name (e.g.
  &quot;SQLite.Interop.2010.vcxproj&quot;) or files ending in &quot;.props&quot;
  are project and property files for the Visual Studio 2010 solution.  When
  making changes, you should make changes to both to keep them in sync.
</p>

<p>
  You can either [./build.wiki#manual | manually build] the System.Data.SQLite
  binaries using one of the supplied Visual Studio solutions or follow the steps
  outlined in the [./build.wiki#automated | Automated Build] section below.
</p>

<a name="assumptions"></a>
<h2>Build Assumptions &amp; Prerequisites</h2>

<ol>
  <li>
    We want to ship managed binaries that rely on the .NET Framework 2.0 SP2 (or
    for the LINQ assembly, the .NET Framework 3.5 SP1).  The .NET Framework 2.0
    is very widely deployed and binaries produced for it can also be referenced
    and used successfully from projects using the .NET Framework 4.0.
  </li>

  <li>
    We want to ship native binaries that rely on the Visual C++ 2008 Runtime.
  </li>

  <li>
    We want to ship the separate managed-only &quot;System.Data.SQLite.dll&quot;
    assembly and the &quot;SQLite.Interop.dll&quot; native library.  This will
    make it easier to maintain and deploy the included core SQLite code (in the
    &quot;SQLite.Interop.dll&quot; native library).  We also want to ship the
    &quot;monster DLL&quot; (i.e. the mixed-mode
    &quot;System.Data.SQLite.dll&quot; assembly that includes all the necessary
    native and managed code).  This will make it easier for developers that wish
    to register the assembly in the Global Assembly Cache (GAC).
  </li>

  <li>
    The machine used to prepare the official releases will have the
    [http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ab99342f-5d1a-413d-8319-81da479ab0d7 | .NET Framework 3.5 SP1]
    and the corresponding
    [http://www.microsoft.com/downloads/details.aspx?FamilyId=E6E1C3DF-A74F-4207-8586-711EBE331CDC | SDK]
    installed.
  </li>

  <li>
    The machine used to prepare the official releases will have
    [http://www.jrsoftware.org/isdl.php | Inno Setup 5.4.2] or higher installed
    in &quot;%ProgramFiles%\Inno Setup 5&quot; or &quot;%ProgramFiles(x86)%\Inno
    Setup 5&quot; for an 64-bit machines.  Alternatively, the Inno Setup
    directory may be included in the PATH environment variable.
  </li>

  <li>
    The string &quot;&lt;root&gt;&quot; represents the root of your source tree
    for the System.Data.SQLite project.
  </li>

  <li>
    The string &quot;&lt;year&gt;&quot; represents the version of Visual Studio
    being used (e.g. 2008).
  </li>
</ol>

<a name="all"></a>
<h2>All Builds</h2>

<ol>
  <li>
    Make sure the version information is correct for SQLite in all of the
    following files:

    <ul>
      <li>&lt;root&gt;\SQLite.Interop\props\sqlite3.vsprops</li>
      <li>&lt;root&gt;\SQLite.Interop\props\sqlite3.props</li>
    </ul>

    You'll need to update the SQLITE_MANIFEST_VERSION and SQLITE_RC_VERSION
    properties.  This version number should track the release versions of SQLite
    (i.e. [http://www.sqlite.org/changes.html | 3.7.x]).
  </li>

  <li>
    Make sure the version information is correct for System.Data.SQLite in the
    following files:

    <ul>
      <li>&lt;root&gt;\SQLite.nuspec</li>
      <li>&lt;root&gt;\SQLite.MSIL.nuspec</li>
      <li>&lt;root&gt;\SQLite.x86.nuspec</li>
      <li>&lt;root&gt;\SQLite.x64.nuspec</li>
      <li>&lt;root&gt;\Doc\Extra\dbfactorysupport.html</li>
      <li>&lt;root&gt;\Doc\Extra\welcome.html</li>
      <li>&lt;root&gt;\Membership\Properties\AssemblyInfo.cs</li>
      <li>&lt;root&gt;\SQLite.Designer\AssemblyInfo.cs</li>
      <li>&lt;root&gt;\SQLite.Interop\props\SQLite.Interop.vsprops</li>
      <li>&lt;root&gt;\SQLite.Interop\props\SQLite.Interop.props</li>
      <li>&lt;root&gt;\SQLite.Interop\src\win\interop.h</li>
      <li>&lt;root&gt;\System.Data.SQLite\AssemblyInfo.cs</li>
      <li>&lt;root&gt;\System.Data.SQLite\SQLite3.cs</li>
      <li>&lt;root&gt;\System.Data.SQLite\UnsafeNativeMethods.cs</li>
      <li>&lt;root&gt;\System.Data.SQLite.Linq\AssemblyInfo.cs</li>
      <li>&lt;root&gt;\test\AssemblyInfo.cs</li>
      <li>&lt;root&gt;\test\app.config</li>
      <li>&lt;root&gt;\testce\AssemblyInfo.cs</li>
      <li>&lt;root&gt;\testlinq\2008\App.config</li>
      <li>&lt;root&gt;\testlinq\2010\App.config</li>
      <li>&lt;root&gt;\testlinq\Properties\AssemblyInfo.cs</li>
      <li>&lt;root&gt;\Tests\version.eagle</li>
      <li>&lt;root&gt;\tools\install\Properties\AssemblyInfo.cs</li>
    </ul>

    You'll need to update the INTEROP_BUILD_NUMBER, INTEROP_MANIFEST_VERSION,
    and INTEROP_RC_VERSION properties in the &quot;.vsprops&quot; and
    &quot;.props&quot; files, and the INTEROP_VERSION define in
    &quot;interop.h&quot;.  This version number should track the release
    versions of the System.Data.SQLite packages (i.e. [./news.wiki | 1.0.x]).
  </li>
</ol>

<a name="manual"></a>
<h2>Manual Build</h2>

<ol>
  <li>
    Complete the steps outlined in the [./build.wiki#all | All Builds] section
    (above).
  </li>

  <li>
    Open the appropriate solution for your build platform.

    <ul>
      <li>
        The &quot;SQLite.NET.2008.sln&quot; file is the top-level solution
        primarily designed for use with Visual Studio 2008 in the IDE; however,
        it may also be used from the command line with MSBuild 3.5.
      </li>

      <li>
        The &quot;SQLite.NET.2010.sln&quot; file is the top-level solution
        primarily designed for use with Visual Studio 2010 in the IDE; however,
        it may also be used from the command line with MSBuild 4.0.
      </li>

      <li>
        The &quot;SQLite.NET.2008.MSBuild.sln&quot; file is the top-level
        solution primarily designed for use with MSBuild 3.5 on the command
        line; however, it may also be used from the Visual Studio 2008 IDE.
      </li>

      <li>
        The &quot;SQLite.NET.2010.MSBuild.sln&quot; file is the top-level
        solution primarily designed for use with MSBuild 4.0 on the command
        line; however, it may also be used from the Visual Studio 2010 IDE.
      </li>
    </ul>
  </li>

  <li>
    Select the desired solution configuration (e.g. ReleaseNativeOnly) and and
    solution platform (e.g. x64), then &quot;Build->Rebuild Solution&quot;.
    Alternatively, you can select &quot;Build->Batch Build&quot;, &quot;Select
    All&quot;, and then &quot;Rebuild&quot;.
  </li>
</ol>

<a name="automated"></a>
<h2>Automated Build</h2>

<ol>
  <li>
    Complete the steps outlined in the [./build.wiki#all | All Builds] section
    (above).
  </li>

  <li>
    Make sure the &quot;&lt;root&gt;\bin&quot; and &quot;&lt;root&gt;\obj&quot;
    directories are completely free of all output files.  In theory, you should
    be able to simply delete these directories.
  </li>

  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to build the binaries for Win32 (x86):&nbsp;
    <b>build.bat ReleaseNativeOnly Win32</b><br /><i>You may need to enter the
    command &quot;<b>setenv /x86</b>&quot; first if you are using a
    &quot;Windows SDK Command Prompt&quot; or &quot;Visual Studio Command
    Prompt&quot; window.</i>
  </li>

  <li>
    Make sure everything succeeds with no errors; the log file
    &quot;%TEMP%\System.Data.SQLite.Build_ReleaseNativeOnly_Win32_&lt;year&gt;_Unknown.log&quot;
    may be checked if any errors should occur.
  </li>

  <li>
    Enter the following command to build the binaries for x64:&nbsp;<b>build.bat
    ReleaseNativeOnly x64</b><br /><i>You may need to enter the command
    &quot;<b>setenv /x64</b>&quot; first if you are using a &quot;Windows SDK
    Command Prompt&quot; or &quot;Visual Studio Command Prompt&quot; window.</i>
  </li>

  <li>
    Make sure everything succeeds with no errors; the log file
    &quot;%TEMP%\System.Data.SQLite.Build_ReleaseNativeOnly_x64_&lt;year&gt;_Unknown.log&quot;
    may be checked if any errors should occur.
  </li>

  <li>
    Enter the following command to build the setup binaries for all supported
    build configurations (unfortunately, it is not possible to build the setup
    using the Inno Setup IDE.  It must be done using the provided command line
    tools due to its highly dynamic nature):&nbsp;<b>bake_all.bat</b>
  </li>

  <li>
    Make sure everything succeeds with no errors.  Inno Setup should produce
    &quot;success&quot; messages very similar to the following:&nbsp;
    <b>Successful compile (X.XXX sec). Resulting Setup program filename
    is:&nbsp;abc</b>
  </li>
</ol>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































Deleted www/checkin.wiki.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<title>Check-in Checklist</title>

Before every check-in:

  1.   <b>fossil diff</b> &rarr; no stray changes

  2.   <b>fossil extra</b> &rarr; no unmanaged files need to be added.

  3.   The check-in will go onto the desired branch.

  4.   "Autosync" is enabled &rarr;
       <ol>
       <li> The check-in will not cause a unintentional fork.
       <li> The local system clock is set correctly.
       </ol>

Before every check-in to <b>trunk</b>:

  5.   No compiler warnings on the development machine.

  6.   Changes will not cause problems on a future <b>bisect</b>.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted www/contrib_agreement.wiki.
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
<title>System.Data.SQLite Contributor Agreement</title>

<p>
  This agreement applies to your contribution of material to the
  System.Data.SQLite ADO.NET interfaces ("SDS") that is
  mananged by Hipp, Wyrick &amp; Company, Inc. ("Hwaci") and
  sets out the intellectual property rights you grant to Hwaci in the
  contributed material.
  The terms "contribution" and "contributed material" mean any source code,
  object code, patch, tool, sample, graphic, specification, manual,
  documentation, or any other material posted, submitted, or uploaded by
  you to the SDS project.
  The term "you" means the person identified
  and signing at the bottom of this document.  If your contribution
  is on behalf of a company, the term "you" also means the company
  identified in the signature area below.
</p>

<ol>
    <li>
      <p>
        With respect to any worldwide copyrights, or copyright applications and
        registrations, in your contribution:
        <ul>
          <li>
            You hereby assign to Hwaci joint ownership, and to the extent that
            such assignment is or becomes invalid, ineffective or unenforceable,
            you hereby grant to Hwaci a perpetual, irrevocable, non-exclusive,
            worldwide, no-charge, royalty-free, unrestricted license to exercise
            all rights under those copyrights, including the right to sublicense.
          </li>
          <li>
            You agree that both you and Hwaci can do all things in relation to your
            contribution as if each of us were the sole owners, and if one of us
            makes a derivative work of your contribution, the one who makes
            (or has made) the derivative work will be the sole owner of that
            derivative work.
          </li>
          <li>
            You agree that you will not assert any moral rights in your
            contribution against Hwaci, Hwaci's licensees or transferees, or
            any other user or consumer of your contribution.
          </li>
          <li>
            You agree that Hwaci may register a copyright in your contribution and
            exercise all ownership rights associated with it.
          </li>
          <li>
            You agree that neither you nor Hwaci has any duty to consult with,
            obtain the consent of, or pay or render an accounting to the other
            for any use or distribution of your contribution.
          </li>
        </ul>
      </p>
    </li>
    <li>
      <p>
        With respect to any patents you own, or that you can license without payment
        to any third party, and which are relevant to your contribution, you hereby
        grant to Hwaci a perpetual, irrevocable, non-exclusive, worldwide, no-charge,
        royalty-free license to
        make, have made, use, sell, offer to sell, import, and otherwise
        transfer your contribution in whole or in part, alone or in
        combination with or included in any product, work or materials arising
        out of the SDS project, and to sublicense these same rights.
      </p>
    </li>
    <li>
      <p>
        Except as set out above, you keep all right, title, and interest in your
        contribution.  The rights that you grant to Hwaci under this agreement
        are effective on the date that you first submitted your contribution to the
        SDS project, even if your submission took place before the date that
        you sign this agreement.
      </p>
    </li>
    <li>
      <p>
        You represent and warrant the following:
        <ul>
          <li>
            Your contribution is an original work and that you can legally
            grant the rights set out in this agreement.
          </li>
          <li>
            Your contribution does not, to the best of your knowledge and belief,
            violate any third party's copyrights, trademarks, patents,
            or other intellectual property rights.
          </li>
          <li>
            You are authorized to sign this agreement on behalf of your
            company (if appliable).
          </li>
        </ul>
      </p>
    </li>
  </ol>

  <p>
    By filling in the following information and signing your name,
    you agree to be bound by all of the terms
    set forth in this agreement.  Please print clearly.
  </p>

  <center>
    <p>
      <table width="80%" border="1" cellpadding="0" cellspacing="0">
        <tr>
          <td width="20%" valign="top">Your name &amp email:</td>
          <td width="80%">
            <!-- Replace this line with your name and email -->
            <p>&nbsp;</p>
          </td>
        </tr>
        <tr>
          <td valign="top">Company name:<br>(if applicable)</td>
          <td>
            <!-- Replace this line with your company name -->
            <p>&nbsp;</p>
          </td>
        </tr>
        <tr>
          <td valign="top">Postal address:</td>
          <td>
            <!-- Replace this line and the next line with your postal address -->
            <p>&nbsp;</p>
            <p>&nbsp;</p>
            <p>&nbsp;</p>
          </td>
        </tr>
        <tr>
          <td valign="top">Signature:</td>
          <td>
            <p>&nbsp;</p>
          </td>
        </tr>
        <tr>
          <td valign="top">Date:</td>
          <td>
            <p>&nbsp;</p>
          </td>
        </tr>
      </table>
    </p>
  </center>

  <p>
    Send completed forms to:
    <blockquote>
      Hipp, Wyrick &amp; Company, Inc.<br>
      6200 Maple Cove Lane<br>
      Charlotte, NC 28269-1086<br>
      USA
    </blockquote>
  </p>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































Deleted www/contribute.wiki.
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
<title>Contributing To System.Data.SQLite</title>

Users are encouraged to contributed enhancements back to the System.Data.SQLite
project.  This note outlines some of the procedures for making
useful contributions.

<h2>1.0 Contributor Agreement</h2>

In order to accept your contributions, we <u>must</u> have a
[./contrib_agreement.wiki | Contributor Agreement] on file for you.  We require
this in order to maintain clear title to the System.Data.SQLite code and prevent
the introduction of code with incompatible licenses or other entanglements
that might cause legal problems for System.Data.SQLite users.  

If you do not wish to submit a Contributor Agreement, we would still
welcome your suggestions and example code, but we will not use your code
directly - we will be forced to reimplement your changes from scratch which
might take longer.

<h2>2.0 Submitting Patches</h2>

Suggested changes or bug fixes can be submitted by creating a patch
against the current source tree.  Email patches to 
<a href="mailto:drh@sqlite.org">drh@sqlite.org</a>.  Be sure to 
describe in detail what the patch does and which version of System.Data.SQLite
it is written against.  

A contributor agreement is not strictly necessary to submit a patch.
However, without a contributor agreement on file, your patch will be
used for reference only - it will not be applied to the code.  This
may delay acceptance of your patch.

Your patches or changes might not be accepted even if you do have
a contributor agreement on file.  Please do not take this personally
or as an affront to your coding ability.  Sometimes patches are rejected
because they seem to be taking the project in a direction that the
architect does not want to go.  Or, there might be an alternative
implementation of the same feature being prepared separately.

<h2>3.0 Check-in Privileges</h2>

Check-in privileges are granted on a case-by-case basis.   Your chances
of getting check-in privileges are much improved if you have a history
of submitting quality patches and/or making thoughtful posts on the
[http://www.mail-archive.com/sqlite-users@sqlite.org/ | mailing list].
A contributor agreement is, of course, a prerequisite for check-in
privileges.</p>

Contributors are asked to make all non-trivial changes on a branch.  A
System.Data.SQLite admin will review the branch and merge the changes 
into the trunk.</p>

Contributors are required to following the
[./checkin.wiki | pre-checkin checklist] prior to every checkin to
the System.Data.SQLite self-hosting repository.  This checklist is short and succinct
and should only require a few seconds to follow.  Contributors 
should print out a copy of the pre-checkin checklist and keep
it on a notecard beside their workstations, for quick reference.

Contributors should review and try to mimic the coding style
used through the rest of the System.Data.SQLite source code.  Your code should
blend in.  A third-party reader should be unable to distinguish your
code from any other code in the source corpus. 

<h2>4.0 Testing</h2>

System.Data.SQLite has a simple test harness that excercises the basic
System.Data.SQLite functions, but this is an area that needs further work.  
(Your contributions here are welcomed!)
Contributors with check-in privileges are expected to run the test harness 
on all changes they contribute, and if appropriate add new automated test 
scripts to cover their additions.

<h2>5.0 See Also</h2>

  *  [./release.wiki | Release Procedures]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































Deleted www/downloads.wiki.
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
<title>System.Data.SQLite Download Page</title>

<h3>System.Data.SQLite Download Page</h3>

<table width="100%" cellpadding="5">
  <tr>
    <td colspan="4">
      <b>Source Code</b>
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx-source-1.0.77.0.zip">sqlite-netFx-source-1.0.77.0.zip</a>
      <br />
      (2.57 MiB)
    </td>
    <td width="5"></td>
    <td valign="top">
      This ZIP archive contains all current source code for System.Data.SQLite
      1.0.77.0 (3.7.9) combined into a single archive file.
      <br />
      (sha1: 84e9b80b767118caf06206c3e83cb53eddb89a08)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx35-setup-bundle-x86-2008-1.0.77.0.exe">sqlite-netFx35-setup-bundle-x86-2008-1.0.77.0.exe</a>
      <br />
      (5.88 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.77.0 (3.7.9) package.  The Visual C++ 2008
      SP1 runtime for x86 is included.  The .NET Framework 3.5 SP1 is required.
      <br />
      (sha1: d772f21988d166e25b21ea73d645de249f083883)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx35-setup-x86-2008-1.0.77.0.exe">sqlite-netFx35-setup-x86-2008-1.0.77.0.exe</a>
      <br />
      (5.88 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.77.0
      (3.7.9) package.  The Visual C++ 2008 SP1 runtime for x86 is included.
      The .NET Framework 3.5 SP1 is required.
      <br />
      (sha1: 6257afc0cc2fefb7c4f72ffe52fe12941ee1c053)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx35-setup-bundle-x64-2008-1.0.77.0.exe">sqlite-netFx35-setup-bundle-x64-2008-1.0.77.0.exe</a>
      <br />
      (6.62 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.77.0 (3.7.9) package.  The Visual C++ 2008
      SP1 runtime for x64 is included.  The .NET Framework 3.5 SP1 is required.
      <br />
      (sha1: 3e503a9292b361e24d46ee814bf3ff4c1d0bbaa2)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx35-setup-x64-2008-1.0.77.0.exe">sqlite-netFx35-setup-x64-2008-1.0.77.0.exe</a>
      <br />
      (6.61 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.77.0
      (3.7.9) package.  The Visual C++ 2008 SP1 runtime for x64 is included.
      The .NET Framework 3.5 SP1 is required.
      <br />
      (sha1: 344e03e91c5f95e09e4dbaa8336dfbe75ece875b)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx40-setup-bundle-x86-2010-1.0.77.0.exe">sqlite-netFx40-setup-bundle-x86-2010-1.0.77.0.exe</a>
      <br />
      (10.25 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.77.0 (3.7.9) package.  The Visual C++ 2010
      SP1 runtime for x86 is included.  The .NET Framework 4.0 is required.
      <br />
      (sha1: c1f51270764c2d694a6e19ef0200243a4212c021)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx40-setup-x86-2010-1.0.77.0.exe">sqlite-netFx40-setup-x86-2010-1.0.77.0.exe</a>
      <br />
      (10.24 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.77.0
      (3.7.9) package.  The Visual C++ 2010 SP1 runtime for x86 is included.
      The .NET Framework 4.0 is required.
      <br />
      (sha1: c80d75dab1c3692be27f47c5db7d4b55af2891c3)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx40-setup-bundle-x64-2010-1.0.77.0.exe">sqlite-netFx40-setup-bundle-x64-2010-1.0.77.0.exe</a>
      <br />
      (12.04 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.77.0 (3.7.9) package.  The Visual C++ 2010
      SP1 runtime for x64 is included.  The .NET Framework 4.0 is required.
      <br />
      (sha1: 34a56eaee1d876278f42a3626b12ac6eb5713b3d)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx40-setup-x64-2010-1.0.77.0.exe">sqlite-netFx40-setup-x64-2010-1.0.77.0.exe</a>
      <br />
      (12.03 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.77.0
      (3.7.9) package.  The Visual C++ 2010 SP1 runtime for x64 is included.
      The .NET Framework 4.0 is required.
      <br />
      (sha1: aabcb26ed62540968d27a441995053b5260e9b74)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx35-binary-bundle-Win32-2008-1.0.77.0.zip">sqlite-netFx35-binary-bundle-Win32-2008-1.0.77.0.zip</a>
      <br />
      (1.97 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.77.0 (3.7.9)
      package.  The Visual C++ 2008 SP1 runtime for x86 and the .NET Framework
      3.5 SP1 are required.
      <br />
      (sha1: e7103c196e725196c0b591386ec34c7a80c9eb83)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx35-binary-Win32-2008-1.0.77.0.zip">sqlite-netFx35-binary-Win32-2008-1.0.77.0.zip</a>
      <br />
      (1.97 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.77.0 (3.7.9) package.  The Visual C++ 2008 SP1
      runtime for x86 and the .NET Framework 3.5 SP1 are required.
      <br />
      (sha1: 0c36eaf45c99b4e0a56f00711bce04b30b979578)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx35-binary-bundle-x64-2008-1.0.77.0.zip">sqlite-netFx35-binary-bundle-x64-2008-1.0.77.0.zip</a>
      <br />
      (2.04 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.77.0 (3.7.9)
      package.  The Visual C++ 2008 SP1 runtime for x64 and the .NET Framework
      3.5 SP1 are required.
      <br />
      (sha1: ac39f8a600c846ce957b17380636b5b6ce2155c4)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx35-binary-x64-2008-1.0.77.0.zip">sqlite-netFx35-binary-x64-2008-1.0.77.0.zip</a>
      <br />
      (2.03 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.77.0 (3.7.9) package.  The Visual C++ 2008 SP1
      runtime for x64 and the .NET Framework 3.5 SP1 are required.
      <br />
      (sha1: b2595aaf38de226241567cbfa9d6402b92de6658)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx40-binary-bundle-Win32-2010-1.0.77.0.zip">sqlite-netFx40-binary-bundle-Win32-2010-1.0.77.0.zip</a>
      <br />
      (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.77.0 (3.7.9)
      package.  The Visual C++ 2010 SP1 runtime for x86 and the .NET Framework
      4.0 are required.
      <br />
      (sha1: c74d1bc4f15c98a717706e6c3dcafb74e161d373)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx40-binary-Win32-2010-1.0.77.0.zip">sqlite-netFx40-binary-Win32-2010-1.0.77.0.zip</a>
      <br />
      (2.01 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.77.0 (3.7.9) package.  The Visual C++ 2010 SP1
      runtime for x86 and the .NET Framework 4.0 are required.
      <br />
      (sha1: 5467fbd64d2e9a108c479e8449496270f082f9bb)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx40-binary-bundle-x64-2010-1.0.77.0.zip">sqlite-netFx40-binary-bundle-x64-2010-1.0.77.0.zip</a>
      <br />
      (1.46 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.77.0 (3.7.9)
      package.  The Visual C++ 2010 SP1 runtime for x64 and the .NET Framework
      4.0 are required.
      <br />
      (sha1: 16cd8e7e7de4c0786aafbae5ee3a7587ac431cc7)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx40-binary-x64-2010-1.0.77.0.zip">sqlite-netFx40-binary-x64-2010-1.0.77.0.zip</a>
      <br />
      (1.45 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.77.0 (3.7.9) package.  The Visual C++ 2010 SP1
      runtime for x64 and the .NET Framework 4.0 are required.
      <br />
      (sha1: 01746a35858f6df8430335042b0ccb3edb38b7a9)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.77.0.zip">sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.77.0.zip</a>
      <br />
      (2.19 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.77.0 (3.7.9)
      package.  The Visual C++ 2008 SP1 runtime for x86 is statically linked.
      The .NET Framework 3.5 SP1 is required.
      <br />
      (sha1: e24120452d888aa19fde8409bba58f00b888ea19)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx35-static-binary-Win32-2008-1.0.77.0.zip">sqlite-netFx35-static-binary-Win32-2008-1.0.77.0.zip</a>
      <br />
      (2.18 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.77.0 (3.7.9) package.  The Visual C++ 2008 SP1
      runtime for x86 is statically linked.  The .NET Framework 3.5 SP1 is
      required.
      <br />
      (sha1: 371ae4d78b3fd28d46e2ee03c0cdf4fc0c305be7)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx35-static-binary-bundle-x64-2008-1.0.77.0.zip">sqlite-netFx35-static-binary-bundle-x64-2008-1.0.77.0.zip</a>
      <br />
      (2.22 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.77.0 (3.7.9)
      package.  The Visual C++ 2008 SP1 runtime for x64 is statically linked.
      The .NET Framework 3.5 SP1 is required.
      <br />
      (sha1: fa689fa65fe2477b9fb9aeeddc5b73849cdb5147)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx35-static-binary-x64-2008-1.0.77.0.zip">sqlite-netFx35-static-binary-x64-2008-1.0.77.0.zip</a>
      <br />
      (2.21 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.77.0 (3.7.9) package.  The Visual C++ 2008 SP1
      runtime for x64 is statically linked.  The .NET Framework 3.5 SP1 is
      required.
      <br />
      (sha1: 497b8cd02cd92fc597e852db2bc36ed77dca0659)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.77.0.zip">sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.77.0.zip</a>
      <br />
      (2.24 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.77.0 (3.7.9)
      package.  The Visual C++ 2010 SP1 runtime for x86 is statically linked.
      The .NET Framework 4.0 is required.
      <br />
      (sha1: 984cbc9b831b67ea4c7417ee6c041bc5e6bb2b45)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx40-static-binary-Win32-2010-1.0.77.0.zip">sqlite-netFx40-static-binary-Win32-2010-1.0.77.0.zip</a>
      <br />
      (2.23 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.77.0 (3.7.9) package.  The Visual C++ 2010 SP1
      runtime for x86 is statically linked.  The .NET Framework 4.0 is required.
      <br />
      (sha1: 53489a918aa53823c2b82608548486d1a1c030f6)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx40-static-binary-bundle-x64-2010-1.0.77.0.zip">sqlite-netFx40-static-binary-bundle-x64-2010-1.0.77.0.zip</a>
      <br />
      (2.24 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.77.0 (3.7.9)
      package.  The Visual C++ 2010 SP1 runtime for x64 is statically linked.
      The .NET Framework 4.0 is required.
      <br />
      (sha1: 4fe5b9bf86ec6b602af981a477be1e7942199f1c)
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="/sqlite-netFx40-static-binary-x64-2010-1.0.77.0.zip">sqlite-netFx40-static-binary-x64-2010-1.0.77.0.zip</a>
      <br />
      (2.23 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.77.0 (3.7.9) package.  The Visual C++ 2010 SP1
      runtime for x64 is statically linked.  The .NET Framework 4.0 is required.
      <br />
      (sha1: 2efbfc06e126eb49deda6799124921111e427d2a)
    </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 valign="top" align="right">
      <a href="/sqlite-netFx35-binary-PocketPC-2008-1.0.77.0.zip">sqlite-netFx35-binary-PocketPC-2008-1.0.77.0.zip</a>
      <br />
      (0.80 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.77.0 (3.7.9) package.  The .NET Compact
      Framework 3.5 is required.
      <br />
      (sha1: c7227c3b968028f4b1260b5d1bd244c950f7fbac)
    </td>
  </tr>

  <tr>
    <td colspan="4">
      <b>Legacy Versions</b>
    </td>
  </tr>

  <tr>
    <td width="10">&nbsp;</td>
    <td valign="top" align="right">
      <a href="http://sqlite.phxsoftware.com/">SQLite-1.0.66.0-setup.exe</a>
      <br />
      (3.2 MiB)
    </td>
    <td width="5"></td>
    <td valign="top">
      Legacy versions, as well as the original support forums, may still be
      found at [http://sqlite.phxsoftware.com/], though there have been no updates
      to this version since April of 2010.
    </td>
  </tr>
</table>

<h3>Build Product Names</h3>

<p>
  Beginning with System.Data.SQLite version 1.0.74.0 (3.7.7.1), the following
  templates will be used for the names of the build products:

  <ol>
    <li><b>sqlite-netFx-source-</b>version<b>.zip</b></li>
    <li><b>sqlite-netFx-source-</b>version<b>.tar.gz</b></li>
    <li><b>sqlite-</b>framework<b>-setup-</b>cpu<b>-</b>year<b>-</b>version<b>.exe</b></li>
    <li><b>sqlite-</b>framework<b>-setup-bundle-</b>cpu<b>-</b>year<b>-</b>version<b>.exe</b></li>
    <li><b>sqlite-</b>framework<b>-binary-</b>platform<b>-</b>year<b>-</b>version<b>.zip</b></li>
    <li><b>sqlite-</b>framework<b>-binary-bundle-</b>platform<b>-</b>year<b>-</b>version<b>.zip</b></li>
    <li><b>sqlite-</b>framework<b>-static-binary-</b>platform<b>-</b>year<b>-</b>version<b>.zip</b></li>
    <li><b>sqlite-</b>framework<b>-static-binary-bundle-</b>platform<b>-</b>year<b>-</b>version<b>.zip</b></li>
    <li><b>sqlite-netFx-source-</b>date<b>.zip</b></li>
  </ol>
</p>

<p>
  Templates (1) and (2) are used for source-code packages.  Template (1) is used
  for generic source-code packages and template (2) is used for source-code
  packages that are generally only useful on unix-like platforms.  Template (3)
  is used for the setup package.  Template (4) is used for the setup package
  containing the mixed-mode assembly.  Template (5) is used for the precompiled
  binary package.  Template (6) is used for the precompiled binary package
  containing the mixed-mode assembly.  Template (7) is used for the precompiled
  binary package statically linked to the Visual C++ runtime.  Template (8) is
  used for the precompiled binary package containing the mixed-mode assembly
  statically linked to the Visual C++ runtime.  Template (9) is used for
  unofficial pre-release &quot;snapshots&quot; of source code.
</p>

<p>
  The framework in templates (3), (4), (5), (6), (7), and (8) will be one of netFx35, netFx40.
</p>

<p>
  The cpu in templates (3) and (4) will be one of x86, x64, arm, ia64.
</p>

<p>
  The platform in templates (5), (6), (7), and (8) will be one of Win32, x64, PocketPC.
</p>

<p>
  The year in templates (3), (4), (5), (6), (7), and (8) will be one of 2008, 2010.
</p>

<p>
  The version in templates (1), (2), (3), (4), (5), (6), (7), and (8) is the dot-delimited version number of the primary System.Data.SQLite assembly.
</p>

<p>
  The date in template (9) is of the form: YYYYMMDDHHMM
</p>

<h3>Canonical Source Code</h3>

<p>
  The canonical System.Data.SQLite source code is maintained in a Fossil
  repository that is available for anonymous read-only access. Anyone can view
  the repository contents and download historical versions of individual files
  or ZIP archives of historical check-ins.
</p>

<p>
  The complete source tree for any [/timeline?n=20&y=ci | check-in] may always
  be downloaded using the &quot;ZIP archive&quot; link available from the
  check-in detail page.
</p>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted www/features.wiki.
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
<title>Features</title>

<h2>Features</h2>

<ul>
  <li>
    Written from scratch on Visual Studio 2008 specifically for ADO.NET,
    implementing all the base classes and features recently introduced in the
    framework, including automatic transaction enlistment.
  </li>

  <li>
    Supports the Full and Compact .NET Framework, and native C/C++ development.
    100% binary compatible with the original sqlite3.dll.
  </li>

  <li>
    Full support for Mono via a &quot;managed only&quot; provider that runs
    against the official SQLite 3.6.1 or higher library.
  </li>

  <li>Full Entity Framework support (ADO.NET 3.5 SP1).</li>

  <li>
    On the Compact Framework, it is faster than SQL Server Mobile.  SQLite's
    installed size is a fraction of SQL Mobile's.  It uses less memory at
    runtime, runs queries faster, and has a smaller database file size as well.
  </li>

  <li>
    Encrypted database support.  Encrypted databases are fully encrypted and
    support both binary and cleartext password types.
  </li>

  <li>
    Visual Studio design-time Support, works with all versions of Visual Studio
    2005/2008/2010.  You can add a SQLite database to the Servers list, design
    queries with the Query Designer, drag-and-drop tables onto a Typed DataSet,
    etc.
    <br />
    <font color="red">
      Currently not included.  We are still updating the design-time support
      installer.  Due to Visual Studio licensing restrictions, the Express
      Editions can no longer be supported.
    </font>
  </li>

  <li>
    Full SQLite schema editing inside Visual Studio.  You can create/edit tables,
    views, triggers, indexes, check constraints and foreign keys.
  </li>

  <li>
    Single file redistributable (except on Compact Framework).  The core SQLite
    native code and the ADO.NET managed wrapper are combined into one mixed-mode
    assembly.
  </li>

  <li>
    Binaries included for x86, x64, Itanium, and ARM processors.
    <br />
    <font color="red">
      Itanium processor support not currently included.
    </font>
  </li>

  <li>DbProviderFactory support.</li>

  <li>
    Full support for ATTACH'ed databases.  Exposed as <i>Catalogs</i> in the
    schema.  When cloning a connection, all attached databases are automatically
    re-attached to the new connection.
  </li>

  <li>
    DbConnection.GetSchema(...) support includes <i>ReservedWords</i>,
    <i>MetaDataCollections</i>, <i>DataSourceInformation</i>, <i>DataTypes</i>,
    <i>Columns</i>, <i>Tables</i>, <i>Views</i>, <i>ViewColumns</i>,
    <i>Catalogs</i>, <i>Indexes</i>, <i>IndexColumns</i>, <i>ForeignKeys</i> and
    <i>Triggers</i>.
  </li>

  <li>
    Enhanced DbDataReader.GetSchemaTable() functionality returns catalog,
    namespace and detailed schema information even for complex queries.
  </li>

  <li>Named and unnamed parameters.</li>

  <li>
    Full UTF-8 and UTF-16 support, each with optimized pipelines into the native
    database core.
  </li>

  <li>
    Multiple simultaneous DataReaders (one DataReader per Command however).
  </li>

  <li>
    Full support for user-defined scalar and aggregate functions, encapsulated
    into an easy-to-use base class in which only a couple of overrides are
    necessary to implement new SQL functions.
  </li>

  <li>
    Full support for user-defined collating sequences, every bit as simple to
    implement as user-defined functions and uses the same base class.
  </li>

  <li>
    Full source for the entire engine and wrapper.  No copyrights.  Public
    Domain.  100% free for commercial and non-commercial use.
  </li>
</ul>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































Deleted www/index.wiki.
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
<title>About</title>

<table align="right" border="1" cellpadding="10" hspace="10" cellspacing="0">
  <tr>
    <td>
      <ul>
        <li>[./features.wiki | Features]</li>
        <li>[./news.wiki | News]</li>
        <li>[./support.wiki | Support]</li>
        <li>[./downloads.wiki | Downloads]</li>
        <li>[./contribute.wiki | Contributing]</li>
        <li>[./build.wiki | Build Procedures]</li>
        <li>[./test.wiki | Test Procedures]</li>
        <li>[./release.wiki | Release Procedures]</li>
      </ul>
    </td>
  </tr>
</table>

<p>
  This is a fork of the popular ADO.NET adapter for
  <a href="http://www.sqlite.org/">SQLite</a> known as System.Data.SQLite. The
  originator of System.Data.SQLite, Robert Simpson, is aware of this fork, has
  expressed his approval, and has commit privileges on the new Fossil
  repository.  The SQLite development team intends to maintain
  System.Data.SQLite moving forward.
</p>

<p>
  Historical versions, as well as the original support forums, may still be
  found at <a href="http://sqlite.phxsoftware.com/">http://sqlite.phxsoftware.com/</a>,
  though there have been no updates to this version since April of 2010.
</p>

<p>
  &nbsp;
</p>

<p>
  &nbsp;
</p>

<p>
  &nbsp;
</p>

<p>
  &nbsp;
</p>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































Deleted 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
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
<title>News</title>

<b>Version History</b>

<p>
    <b>1.0.77.0 - November 28, 2011</b>
</p>
<ul>
    <li>Updated to SQLite 3.7.9 <a href="http://www.sqlite.org/src/info/a499ae3835">[a499ae3835]</a>.</li>
    <li>More enhancements to the build and test automation.</li>
    <li>Plug native memory leak when closing a database connection containing a statement that cannot be finalized for some reason.</li>
    <li>The SQLite3 class should always attempt to dispose the contained SQLiteConnectionHandle, even when called via the finalizer.</li>
    <li>When compiled with DEBUG defined, emit diagnostic information related to resource cleanup to any TraceListener objects that may be registered.</li>
    <li>Stop characterizing all log messages as errors. From now on, if the errorCode is zero, the message will not be considered an error.</li>
    <li>Never attempt to configure the native logging interface if the SQLite core library has already been initialized for the process. Fix for [2ce0870fad].</li>
    <li>Allow the SQLiteLog class to be used for logging messages without having an open connection.</li>
    <li>Support building the core System.Data.SQLite assemblies using the .NET Framework 4.0 Client Profile. Fix for [566f1ad1e4].</li>
    <li>When generating the schema based on the contents of a SQLiteDataReader, skip flagging columns as unique if the data reader is holding the result of some kind of multi-table construct (e.g. a cross join) because we must allow duplicate values in that case. Fix for [7e3fa93744].</li>
    <li>When returning schema information that may be used by the .NET Framework to construct dynamic SQL, use a fake schema name (instead of null) so that the table names will be properly qualified with the catalog name (i.e. the attached database name). Partial fix for [343d392b51].</li>
    <li>Add SQLiteSourceId property to the SQLiteConnection class to return the SQLite source identifier.</li>
    <li>Add MemoryUsed and MemoryHighwater properties to the SQLiteConnection class to help determine the memory usage of SQLite.</li>
    <li>Add DateTimeKind connection string property to control the DateTimeKind of parsed DateTime values. Partial fix for [343d392b51].</li>
    <li>Improve the robustness of the SQLiteLog class when it will be initialized and unloaded multiple times.</li>
    <li>Fix the name of the interop assembly for Windows CE. Add unit tests to prevent this type of issue from happening again. Fix for [737ca4ff74].</li>
    <li>Formally support the SQL type name BOOLEAN in addition to BOOL. Fix for [544dba0a2f].</li>
    <li>Make sure the SQLiteConvert.TypeNameToDbType method is thread-safe. Fix for [84718e79fa].</li>
</ul>
<p>
    <b>1.0.76.0 - October 4, 2011</b>
</p>
<ul>
    <li>Prevent the domain unload event handler in SQLiteLog from being registered multiple times. Fix for [0d5b1ef362].</li>
    <li>Stop allowing non-default application domains to initialize the SQLiteLog class. Fix for [ac47dd230a].</li>
</ul>
<p>
    <b>1.0.75.0 - October 3, 2011</b>
</p>
<ul>
    <li>Updated to SQLite 3.7.8 <a href="http://www.sqlite.org/src/info/3e0da808d2">[3e0da808d2]</a>.</li>
    <li>More enhancements to the build system.</li>
    <li>Add official <a href="http://www.nuget.org/">NuGet</a> packages for x86 and x64.</li>
    <li>Add Changes and LastInsertRowId properties to the connection class.</li>
    <li>Support more formats when converting data from/to the DateTime type.</li>
    <li>Make all the assembly versioning attributes consistent.</li>
    <li>Add unit testing infrastructure using <a href="http://eagle.to/">Eagle</a>.</li>
    <li>Integrate all legacy unit tests, including the &quot;testlinq&quot; project, into the new test suite.</li>
    <li>Add projects to build the interop assembly statically linked to the Visual C++ runtime. Fix for [53f0c5cbf6].</li>
    <li>Add SQLITE_ENABLE_STAT2 compile-time option to the interop assembly. Fix for [74807fbf27].</li>
    <li>Fix mutex issues exposed when running the test suite with the debug version of SQLite.</li>
    <li>Fix transaction enlistment when repeated attempts are made to enlist in the same transaction. Fix for [ccfa69fc32].</li>
    <li>Support the SQLITE_FCNTL_WIN32_AV_RETRY file control to mitigate the impact of file sharing violations caused by external processes.</li>
    <li>Refactor the logging interface to be thread-safe and self-initializing.</li>
    <li>Shutdown the SQLite native interface when the AppDomain is being unloaded. Fix for [b4a7ddc83f].</li>
    <li>Support Skip operation for LINQ using OFFSET. Fix for [8b7d179c3c].</li>
    <li>Support EndsWith operation for LINQ using SUBSTR. Fix for [59edc1018b].</li>
    <li>Support all SQLite journal modes. Fix for [448d663d11].</li>
    <li>Do not throw exceptions when disposing SQLiteDataReader. Fix for [e1b2e0f769].</li>
    <li>The REAL type should be mapped to System.Double. Fix for [2c630bffa7] and [b0a5990f48].</li>
    <li>Minor optimization to GetParamValueBytes(). Fix for [201128cc88].</li>
    <li>Support the ON UPDATE, ON DELETE, and MATCH clause information when generating schema metadata for foreign keys. Partial fix for [b226147b37]. VS designer changes are not yet tested.</li>
    <li>Fix incorrect resource name for SR.resx in the mixed-mode assembly.</li>
    <li>Reduce the number of String.Compare() calls in the hot path for SQLiteCommand.ExecuteReader().</li>
</ul>
<p>
    <b>1.0.74.0 - July 4, 2011</b>
</p>
<ul>
    <li>Updated to SQLite 3.7.7.1 <a href="http://www.sqlite.org/src/info/af0d91adf4">[af0d91adf4]</a>.</li>
    <li>Fix incorrect hard-coded .NET Framework version information SQLiteFactory_Linq.cs that was causing IServiceProvider.GetService to fail when running against the .NET Framework 3.5.</li>
    <li>Fix all XML documentation warnings.</li>
    <li>Restore support for the mixed-mode assembly (i.e. the one that can be registered in the Global Assembly Cache).</li>
    <li>Restore support for the Compact Framework.</li>
    <li>Remove unused &quot;using&quot; statements from the System.Data.SQLite and System.Data.SQLite.Linq projects.</li>
    <li>Remove hard-coded System.Data.SQLite.Linq version from SQLiteFactory_Linq.cs</li>
    <li>Modify the setup to support bundled packages (i.e. with the mixed-mode assembly) and standard packages (i.e. with the managed assembly separate from the native interop library).</li>
    <li>Disable the ability to register with the Global Assembly Cache in the standard setup package (i.e. it is available in the bundled setup only).</li>
    <li>Remove PATH modification from the setup.</li>
    <li>Modify the naming scheme for the source, setup, and binary packages to allow for the necessary variants.</li>
    <li>In the build automation, attempt to automatically detect if Visual Studio 2008 and/or 2010 are installed and support building binaries for both at once, when available.</li>
    <li>Add release automation to build the source, setup, and binary packages in all supported build variants.</li>
    <li>Add the testlinq project to the new build system and make it work properly with Visual Studio 2008 and 2010.</li>
</ul>
<p>
    <b>1.0.73.0 - June 2, 2011</b>
</p>
<ul>
    <li>Updated to SQLite 3.7.6.3 <a href="http://www.sqlite.org/src/info/ed1da510a2">[ed1da510a2]</a>.</li>
    <li>Minor optimization to GetBytes(). Fix for [8c1650482e].</li>
    <li>Update various assembly information settings.</li>
    <li>Correct System.Data.SQLite.Linq version and resource information. Fix for [6489c5a396] and [133daf50d6].</li>
    <li>Moved log handler from SQLiteConnection object to SQLiteFactory object to prevent if from being prematurely GCed.</li>
    <li>We should block x64 installs on x86 and we should install native only if the setup package itself is native. Fix for [e058ce156e].</li>
</ul>
<p>
    <b>1.0.72.0 - May 1, 2011</b>
</p>
<ul>
    <li>Add the correct directory to the path. Fix for [50515a0c8e].</li>
</ul>
<p>
    <b>1.0.71.0 - April 27, 2011</b>
</p>
<ul>
    <li>
        Updated to SQLite 3.7.6+ <a href="http://www.sqlite.org/src/info/1bd1484cd7">[1bd1484cd7]</a>
        to get additional Windows error logging.
    </li>
    <li>Updated setup to optionally add install directory to PATH if GAC option selected.</li>
</ul>
<p>
    <b>1.0.69.0 - April 12, 2011</b>
</p>
<ul>
    <li>Code merge with [http://www.sqlite.org/releaselog/3_7_6.html | SQLite 3.7.6]</li>
    <li>New VS2008 and VS2010 solution files</li>
    <li>Build and packaging automation</li>
    <li>New Inno Setup files</li>
    <li>Designer support currently not ready for release</li>
</ul>
<p>
    <b>1.0.68.0 - February 2011</b>
</p>
<ul>
    <li>Code merge with [http://www.sqlite.org/releaselog/3_7_5.html | SQLite 3.7.5]</li>
    <li>Continuing work on supporting Visual Studio 2010</li>
</ul>
<p>
    <b>1.0.67.0 - January 3, 2011</b>
</p>
<ul>
    <li>Code merge with [http://www.sqlite.org/releaselog/3_7_4.html | SQLite 3.7.4]</li>
    <li>Continuing work on supporting Visual Studio 2010</li>
</ul>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































Deleted www/release.wiki.
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
<title>Release Procedures</title>

<a name="releaseProcedures"></a>
<h2>Release Procedures</h2>

<p>
  Follow these steps to prepare a new release of System.Data.SQLite.
  Unless otherwise noted, all steps need to be done in the order specified.
</p>

<a name="buildBinaries"></a>
<h2>Build x86 &amp; x64 Binaries</h2>

<ol>
  <li>
    The binaries for all supported architectures and platforms must be built
    using procedures very similar to those documented in the normal
    [./build.wiki | build procedures].
  </li>

  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to build all the x86 and x64 binaries:&nbsp;
    <b>build_all.bat</b><br />
  </li>
</ol>

<a name="buildCeBinaries"></a>
<h2>Build Windows CE Binaries</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to build all the binaries available for Windows
    CE:&nbsp;<b>build_ce.bat</b><br />
  </li>
</ol>

<a name="updateDocumentation"></a>
<h2>Update Documentation</h2>

<ol>
  <li>
    Update the &quot;&lt;root&gt;\readme.htm&quot; file with information about
    all the major changes since the last released version.
  </li>

  <li>
    Copy those changes to the &quot;&lt;root&gt;\Doc\Extra\version.html&quot;
    and &quot;&lt;root&gt;\www\news.wiki&quot; files, reformatting as necessary
    to fit with the existing document conventions.
  </li>
</ol>

<a name="buildDocumentation"></a>
<h2>Build Documentation</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Doc&quot;.</li>

  <li>
    Enter the following command to build all the documentation in
    [http://en.wikipedia.org/wiki/Microsoft_Compiled_HTML_Help | CHM]
    format:&nbsp;<b>tclsh.exe buildChm.tcl</b><br /><i>This assumes that
    [http://www.activestate.com/activetcl | ActiveTcl] version 8.4 or later, the
    [http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=21138 | HTML Help Workshop],
    and [http://ndoc3.sourceforge.net/ | NDoc3] have all been installed using
    the default settings.</i>
  </li>
</ol>

<a name="buildSetupPackages"></a>
<h2>Build Setup Release Packages</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to build all the setup packages for x86 and
    x64:&nbsp;<b>bake_all.bat</b><br />
  </li>
</ol>

<a name="buildBinaryPackages"></a>
<h2>Build x86 &amp; x64 Binary Release Packages</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to build all the binary release packages for
    x86 and x64:&nbsp;<b>release_all.bat</b><br />
  </li>
</ol>

<a name="buildStaticBinaryPackages"></a>
<h2>Build x86 &amp; x64 Static Binary Release Packages</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to build all the static binary release packages
    for x86 and x64:&nbsp;<b>release_static.bat</b><br />
  </li>
</ol>

<a name="buildCeBinaryPackages"></a>
<h2>Build Windows CE Binary Release Packages</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to build all the binary release packages for
    Windows CE:&nbsp;<b>release_ce.bat</b><br />
  </li>
</ol>

<a name="buildSourcePackages"></a>
<h2>Build Source Release Packages</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to build all the source release packages:
    &nbsp;<b>archive.bat</b><br />
  </li>
</ol>

<a name="updateDownloadsPage"></a>
<h2>Update Downloads Page</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>

  <li>
    Enter the following command to update the sizes and hashes on the downloads
    page based on all the built release packages:&nbsp;<b>tclsh.exe
    updateFileInfo.tcl</b><br /><i>This assumes that
    [http://www.activestate.com/activetcl | ActiveTcl] version 8.4 or later has
    been installed using the default settings and that the Fossil binary is
    available somewhere along the
    [http://en.wikipedia.org/wiki/PATH_%28variable%29 | PATH] (i.e. for
    calculating the SHA1 hashes).</i>
  </li>
</ol>

<a name="buildNuGetPackages"></a>
<h2>Build NuGet Packages</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;&quot;.</li>

  <li>
    Enter the following command to build the &quot;default&quot; NuGet package:
    &nbsp;<b>nuget.exe pack SQLite.nuspec</b><br /><i>This assumes that the
    NuGet binary is available somewhere along the
    [http://en.wikipedia.org/wiki/PATH_%28variable%29 | PATH].<br />Please refer
    to [http://docs.nuget.org/ | NuGet Documentation] for further details.</i>
  </li>

  <li>
    Enter the following command to build the &quot;managed-only&quot; NuGet
    package:&nbsp;<b>nuget.exe pack SQLite.MSIL.nuspec</b><br /><i>This assumes
    that the NuGet binary is available somewhere along the
    [http://en.wikipedia.org/wiki/PATH_%28variable%29 | PATH].<br />Please refer
    to [http://docs.nuget.org/ | NuGet Documentation] for further details.</i>
  </li>

  <li>
    Enter the following command to build the NuGet package for x86:
    &nbsp;<b>nuget.exe pack SQLite.x86.nuspec</b><br /><i>This assumes that the
    NuGet binary is available somewhere along the
    [http://en.wikipedia.org/wiki/PATH_%28variable%29 | PATH].<br />Please refer
    to [http://docs.nuget.org/ | NuGet Documentation] for further details.</i>
  </li>

  <li>
    Enter the following command to build the NuGet package for x64:
    &nbsp;<b>nuget.exe pack SQLite.x64.nuspec</b><br /><i>This assumes that the
    NuGet binary is available somewhere along the
    [http://en.wikipedia.org/wiki/PATH_%28variable%29 | PATH].<br />Please refer
    to [http://docs.nuget.org/ | NuGet Documentation] for further details.</i>
  </li>
</ol>

<a name="publishRelease"></a>
<h2>Publish Release</h2>

<ol>
  <li>
    Commit pending source code changes to the
    [http://www.fossil-scm.org/ | Fossil] repository.
  </li>

  <li>Tag the release in the Fossil repository.</li>

  <li>Upload all the release packages to the web site.</li>

  <li>
    Push the [http://www.nuget.org/ | NuGet] packages.<br />
    <i>Please refer to [http://docs.nuget.org/ | NuGet Documentation] for
    further details.</i>
  </li>

  <li>Announce the release on the System.Data.SQLite mailing list.</li>
</ol>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































Deleted www/support.wiki.
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
<title>Support</title>

<h3>Mailing Lists</h3>

<p>
  SQLite has an active mailing list and support community and users of
  the System.Data.SQLite project available on this web site are encouraged to
  use these for support questions.
</p>

<p>
  Three separate mailing lists have been established to help support SQLite and
  System.Data.SQLite:
</p>

<ul>
  <li>
    <a href="http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-announce">
    sqlite-announce</a> - announcements of new releases or significant
    developments.
  </li>

  <li>
    <a href="http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users">
    sqlite-users</a> - general user discussion; most postings belong here.
  </li>

  <li>
    <a href="http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-dev">
    sqlite-dev</a> - developer conversations; for people who have or aspire to
    have write permission on the SQLite and/or System.Data.SQLite source code
    repositories.
  </li>
</ul>

<p>
  Most users of SQLite and/or System.Data.SQLite will want to join the
  <a href="http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-announce">
  sqlite-announce</a> list and many will want to join the
  <a href="http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users">
  sqlite-users</a> list.  The
  <a href="http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-dev">
  sqlite-dev</a> list is more specialized and appeals to a narrower audience.
  Off-site archives of the
  <a href="http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users">
  sqlite-users</a> list are available at:
</p>

<ul>
  <li>
    <a href="http://www.mail-archive.com/sqlite-users%40sqlite.org/">
    http://www.mail-archive.com/sqlite-users%40sqlite.org/</a>
  </li>

  <li>
    <a href="http://marc.info/?l=sqlite-users&r=1&w=2">
    http://marc.info/?l=sqlite-users&r=1&w=2</a>
  </li>

  <li>
    <a href="http://news.gmane.org/gmane.comp.db.sqlite.general">
    http://news.gmane.org/gmane.comp.db.sqlite.general</a>
  </li>
</ul>

<h3>Direct E-Mail</h3>

<p>
  Use the mailing list. Please do <b>not</b> send email directly
  to the authors of SQLite or System.Data.SQLite unless:
</p>

<ul>
  <li>
    You have or intend to acquire a
    <a href="http://www.sqlite.org/draft/support.html">
    professional support contract</a>.
  </li>

  <li>
    You are working on an open source project.
  </li>
</ul>

<p>
  You are welcomed to use SQLite and System.Data.SQLite in closed source,
  proprietary, and/or commercial projects and to ask questions about such use
  on the public mailing list.  But please do not ask to receive free direct
  technical support. The software is free; direct technical support is not.
</p>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































Deleted www/test.wiki.
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
<title>Test Procedures</title>

<a name="assumptions"></a>
<h2>Test Assumptions &amp; Prerequisites</h2>

<ol>
  <li>
    The string &quot;&lt;root&gt;&quot; represents the root of the source tree
    (i.e. the working check-out directory) for the System.Data.SQLite project.
  </li>

  <li>
    The string &quot;&lt;year&gt;&quot; represents the version of Visual Studio
    used (e.g. &quot;2008&quot; or &quot;2010&quot;) to build the binaries being
    tested.
  </li>

  <li>
    The string &quot;&lt;configuration&gt;&quot; represents the build
    configuration for the binaries being tested (e.g. &quot;Debug&quot; or
    &quot;Release&quot;).
  </li>

  <li>
    The string &quot;&lt;platform&gt;&quot; represents the native platform for
    the binaries being tested (e.g. &quot;Win32&quot; or &quot;x64&quot;).
  </li>

  <li>
    The string &quot;&lt;pid&gt;&quot; represents the process identifier for the
    instance of EagleShell being used to run the unit tests (e.g.
    &quot;1234&quot;).
  </li>
</ol>

<a name="procedures"></a>
<h2>Test Procedures</h2>

<p>
  Follow these steps to unit test the System.Data.SQLite (SDS) binaries.
  Unless otherwise noted, all steps need to be done in the order specified.
</p>

<p>
  First, you will need a full source check-out for the System.Data.SQLite
  project, including the
  &quot;<a href="/index.html/dir?name=Externals/Eagle">Externals\Eagle</a>&quot;
  directory.
</p>

<p>
  The binaries to test must be [./build.wiki | built] or
  [./downloads.wiki | downloaded].  If the binaries are downloaded, they must be
  placed in the appropriate build output directory (e.g.
  &quot;&lt;root&gt;\bin\&lt;year&gt;\&lt;configuration&gt;\bin&quot; for the
  separate managed and interop assemblies or
  &quot;&lt;root&gt;\bin\&lt;year&gt;\&lt;platform&gt;\&lt;configuration&gt;&quot;
  for the mixed-mode assembly).
</p>

<p>
  The new unit tests have been setup using <a href="http://eagle.to/">Eagle</a>
  and its associated unit testing framework, named &quot;EagleTest&quot;.  Eagle
  is an implementation of the <a href="http://www.tcl.tk/">Tcl</a> scripting
  language for the Common Language Runtime (CLR).  EagleTest is the unit testing
  framework for Eagle, packaged as a collection of Eagle scripts, based loosely
  on the implementation of
  <a href="http://www.tcl.tk/man/tcl8.4/TclCmd/tcltest.htm">tcltest</a>.
</p>

<a name="automated"></a>
<h2>Automated Unit Tests</h2>

<ol>
  <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>

  <li>Change the current directory to &quot;&lt;root&gt;&quot;.</li>

  <li>
    Enter the following command to run all the unit tests against the binaries
    built with a separate managed and interop assembly:
    <b>Externals\Eagle\bin\EagleShell.exe -file Tests\all.eagle</b>
  </li>

  <li>
    Enter the following command to run all the unit tests against the binaries
    built with a mixed-mode assembly:
    <b>Externals\Eagle\bin\EagleShell.exe -initialize -runtimeOption native -file Tests\all.eagle</b>
  </li>

  <li>
    To test binaries built with MSBuild 3.5 or Visual Studio 2008 (i.e. because
    the default is to test binaries built with MSBuild 4.0 or Visual Studio
    2010) add the following command line argument right after
    &quot;Externals\Eagle\bin\EagleShell.exe&quot; in either of the above
    command lines:
    <b>-preInitialize &quot;set test_year 2008&quot;</b>
  </li>

  <li>
    To test binaries built in the &quot;Debug&quot; build configuration (i.e.
    because the default is to test binaries built in the &quot;Release&quot;
    build configuration) add the following command line argument right after
    &quot;Externals\Eagle\bin\EagleShell.exe&quot; in either of the above
    command lines:
    <b>-preInitialize &quot;set test_configuration Debug&quot;</b>
  </li>

  <li>
    Make sure all tests pass; the log file
    &quot;%TEMP%\EagleShell.exe.test.&lt;pid&gt;.log&quot; may be checked if any
    errors should occur.  EagleTest should produce &quot;success&quot; messages
    very similar to the following:<br /><br />
    PASSED: 107<br />
    TOTAL: 107<br />
    PASS PERCENTAGE: 100%<br />
    OVERALL RESULT: SUCCESS<br />
  </li>
</ol>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<