286 lines
9.1 KiB
HTML
286 lines
9.1 KiB
HTML
|
<!DOCTYPE HTML>
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<title>Jim Tcl - Sqlite Extension</title>
|
||
|
<link rel="stylesheet" type="text/css" href="/css/style.css" media="screen">
|
||
|
<link rel="stylesheet" type="text/css" href="/css/sh_style.css" media="screen">
|
||
|
|
||
|
<script src="/javascript/sh_main.min.js" type="text/javascript"></script>
|
||
|
<script src="/javascript/sh_lang.js" type="text/javascript"></script>
|
||
|
|
||
|
<script type="text/javascript">
|
||
|
var _gaq = _gaq || [];
|
||
|
_gaq.push(['_setAccount', 'UA-23178588-2']);
|
||
|
_gaq.push(['_trackPageview']);
|
||
|
|
||
|
(function() {
|
||
|
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||
|
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||
|
})();
|
||
|
</script>
|
||
|
|
||
|
<meta name="generator" content="nanoc 3.1.6">
|
||
|
</head>
|
||
|
<body>
|
||
|
<div id="header">
|
||
|
<h1 id="blog-title">The Jim Interpreter</h1>
|
||
|
<p id="description">A small footprint implementation of the Tcl programming language</p>
|
||
|
</div>
|
||
|
<div id="content">
|
||
|
<div class="breadcrumbs">
|
||
|
|
||
|
|
||
|
<a href="/">The Jim Interpreter</a>
|
||
|
»
|
||
|
|
||
|
<a href="/documentation/">Documentation</a>
|
||
|
»
|
||
|
|
||
|
<a href="/documentation/sqlite/">Sqlite Extension</a>
|
||
|
|
||
|
|
||
|
</div>
|
||
|
<div class="main" id="main">
|
||
|
|
||
|
<h1 id="sqlite-support-for-jim-tcl">Sqlite Support for Jim Tcl</h1>
|
||
|
|
||
|
<h2 id="overview">OVERVIEW</h2>
|
||
|
|
||
|
<p>The sqlite and sqlite3 extensions makes possible to work with
|
||
|
<a href="http://www.sqlite.org">sqlite</a> databases from Jim. SQLite is a
|
||
|
small C library that implements a self-contained, embeddable,
|
||
|
zero-configuration SQL database engine. This means it is perfect
|
||
|
for embedded systems, and for stand-alone applications that need
|
||
|
the power of SQL without to use an external server like Mysql.</p>
|
||
|
|
||
|
<p><strong>Note:</strong> The same interface is exported for both the <strong>sqlite</strong> and <strong>sqlite3</strong>
|
||
|
extensions. The only difference being the open call, <strong>sqlite.open</strong> vs. <strong>sqlite3.open</strong></p>
|
||
|
|
||
|
<h2 id="basic-usage">Basic usage</h2>
|
||
|
|
||
|
<p>The Sqlite extension exports an Object Based interface for databases. In order
|
||
|
to open a database use:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
set f [sqlite3.open dbname]
|
||
|
</pre>
|
||
|
|
||
|
<p>The <code>sqlite3.open</code> command returns a db handle, that is a command name that
|
||
|
can be used to perform operations on the database. A real example:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. set db [sqlite3.open test.db]
|
||
|
sqlite.handle0
|
||
|
. $db query "SELECT * from tbl1"
|
||
|
{one hello! two 10} {one goodbye two 20}
|
||
|
</pre>
|
||
|
|
||
|
<p>In the second line the handle is used as a command name, followed
|
||
|
by the ‘method’ or ‘subcommand’ (“query” in the example), and the arguments.</p>
|
||
|
|
||
|
<h2 id="the-query-method">The query method</h2>
|
||
|
|
||
|
<p>The query method has the following signature:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
$db query SqlQuery ?args?
|
||
|
</pre>
|
||
|
|
||
|
<p>The sql query may contain occurrences of “%s” that are substituted
|
||
|
in the actual query with the following arguments, quoted in order
|
||
|
to make sure that the query is correct even if this arguments contain
|
||
|
“’” characters. So for example it is possible to write:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. $db query "SELECT * from tbl1 WHERE one='%s'" hello!
|
||
|
{one hello! two 10}
|
||
|
</pre>
|
||
|
|
||
|
<p>Instead of hello! it is possible to use a string with embedded “’”:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. $db query "SELECT * from tbl1 WHERE one='%s'" a'b
|
||
|
(no matches - the empty list is returned)
|
||
|
</pre>
|
||
|
|
||
|
<p>This does not work instead using the Tcl variable expansion in the string:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. $db query "SELECT * from tbl1 WHERE one='$foo'"
|
||
|
near "b": syntax error
|
||
|
</pre>
|
||
|
|
||
|
<p>In order to obtain an actual ‘%’ character in the query, there is just
|
||
|
to use two, like in “foo %% bar”. This is the same as the [format] argument.</p>
|
||
|
|
||
|
<h2 id="specification-of-query-results">Specification of query results</h2>
|
||
|
|
||
|
<p>In one of the above examples, the following query was used:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. $db query "SELECT * from tbl1"
|
||
|
{one hello! two 10} {one goodbye two 20}
|
||
|
</pre>
|
||
|
|
||
|
<p>As you can see the result of a query is a list of lists. Every
|
||
|
element of the list represents a row, as a list of key/value pairs,
|
||
|
so actually every row is a Jim dictionary.</p>
|
||
|
|
||
|
<p>The following example and generated output show how to take advantage
|
||
|
of this representation:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. set res [$db query "SELECT * from tbl1"]
|
||
|
{one hello! two 10} {one goodbye two 20}
|
||
|
. foreach row $res {puts "One: $row(one), Two: $row(two)"}
|
||
|
One: hello!, Two: 10
|
||
|
One: goodbye, Two: 20
|
||
|
</pre>
|
||
|
|
||
|
<p>To access every row sequentially is very simple, and field of a row
|
||
|
can be accessed using the $row(field) syntax.</p>
|
||
|
|
||
|
<h2 id="the-close-method">The close method</h2>
|
||
|
|
||
|
<p>In order to close the db, use the ‘close’ method that will have as side effect
|
||
|
to close the db and to remove the command associated with the db.
|
||
|
Just use:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
$db close
|
||
|
</pre>
|
||
|
|
||
|
<h2 id="handling-null-values">Handling NULL values</h2>
|
||
|
|
||
|
<p>In the SQL language there is a special value NULL that is not the empty
|
||
|
string, so how to represent it in a typeless language like Tcl?
|
||
|
For default this extension will use the empty string, but it is possible
|
||
|
to specify a different string for the NULL value.</p>
|
||
|
|
||
|
<p>In the above example there were two rows in the ‘tbl1’ table. Now
|
||
|
we can add usign the “sqlite” command line client another one with
|
||
|
a NULL value:</p>
|
||
|
|
||
|
<pre><code>sqlite> INSERT INTO tbl1 VALUES(NULL,30);
|
||
|
sqlite> .exit
|
||
|
</code></pre>
|
||
|
|
||
|
<p>That’s what the sqlite extension will return for default:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. $db query "SELECT * from tbl1"
|
||
|
{one hello! two 10} {one goodbye two 20} {one {} two 30}
|
||
|
</pre>
|
||
|
|
||
|
<p>As you can see in the last row, the NULL is represented as {}, that’s
|
||
|
the empty string. Using the -null option of the ‘query’ command we
|
||
|
can change this default, and tell the sqlite extension to represent
|
||
|
the NULL value as a different string:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. $db query -null <<NULL>> "SELECT * from tbl1"
|
||
|
{one hello! two 10} {one goodbye two 20} {one <<NULL>> two 30}
|
||
|
</pre>
|
||
|
|
||
|
<p>This way if the emtpy string has some semantical value for your
|
||
|
dataset you can change it.</p>
|
||
|
|
||
|
<h2 id="finding-the-id-of-the-last-inserted-row">Finding the ID of the last inserted row</h2>
|
||
|
|
||
|
<p>This is as simple as:</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. $db lastid
|
||
|
10
|
||
|
</pre>
|
||
|
|
||
|
<h2 id="number-of-rows-changed-by-the-most-recent-query">Number of rows changed by the most recent query</h2>
|
||
|
|
||
|
<p>This is also very simple, there is just to use the ‘changes’ method
|
||
|
without arugments.</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
. $db changes
|
||
|
5
|
||
|
</pre>
|
||
|
|
||
|
<p>Note that if you drop an entire table the number of changes will
|
||
|
be reported as zero, because of details of the sqlite implementation.</p>
|
||
|
|
||
|
<p>That’s all,
|
||
|
Enjoy!
|
||
|
Salvatore Sanfilippo</p>
|
||
|
|
||
|
<p>p.s. this extension is just the work of some hour thanks to the cool
|
||
|
clean C API that sqlite exports. Thanks to the author of sqlite for this
|
||
|
great work.</p>
|
||
|
|
||
|
<h2 id="in-memory-databases">In memory databases</h2>
|
||
|
|
||
|
<p>SQLite is able to create in-memory databases instead to use files.
|
||
|
This is of course faster and does not need the ability to write
|
||
|
to the filesystem. Of course this databases are only useful for
|
||
|
temp data.</p>
|
||
|
|
||
|
<p>In-memory DBs are used just like regular databases, just the name used to
|
||
|
open the database is :memory:. That’s an example that does not use the
|
||
|
filesystem at all to create and work with the db.</p>
|
||
|
|
||
|
<pre class="sh_tcl">
|
||
|
package require sqlite3
|
||
|
set db [sqlite3.open :memory:]
|
||
|
$db query {CREATE TABLE plays (id, author, title)}
|
||
|
$db query {INSERT INTO plays (id, author, title) VALUES (1, 'Goethe', 'Faust');}
|
||
|
$db query {INSERT INTO plays (id, author, title) VALUES (2, 'Shakespeare', 'Hamlet');}
|
||
|
$db query {INSERT INTO plays (id, author, title) VALUES (3, 'Sophocles', 'Oedipus Rex');}
|
||
|
set res [$db query "SELECT * FROM plays"]
|
||
|
$db close
|
||
|
foreach r $res {puts $r(author)}
|
||
|
</pre>
|
||
|
|
||
|
<p>Of course once the Jim process is destroyed the database will no longer
|
||
|
exists.</p>
|
||
|
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="sidebar">
|
||
|
<h2>About Jim Tcl</h2>
|
||
|
<ul>
|
||
|
|
||
|
|
||
|
<li class="stdlink"><a href="/">Introduction</a></li>
|
||
|
|
||
|
|
||
|
<li class="newlink"><a href="/news/">News</a></li>
|
||
|
|
||
|
|
||
|
<li class="stdlink"><a href="/download/">Download</a></li>
|
||
|
|
||
|
|
||
|
<li class="stdlink"><a href="/documentation/">Documentation</a></li>
|
||
|
|
||
|
|
||
|
<li class="stdlink"><a href="/extensions/">Extensions</a></li>
|
||
|
|
||
|
|
||
|
<li class="stdlink"><a href="/license/">License</a></li>
|
||
|
|
||
|
|
||
|
<li class="stdlink"><a href="/about/">About</a></li>
|
||
|
|
||
|
</ul>
|
||
|
<h2>Community</h2>
|
||
|
<ul>
|
||
|
<li><a href="https://lists.berlios.de/mailman/listinfo/jim-devel">Mailing List</a></li>
|
||
|
<li><a href="https://github.com/msteveb/jimtcl">Jim on github</a></li>
|
||
|
<li><a href="http://wiki.tcl.tk/jim">Jim @ the Tcler's Wiki</a></li>
|
||
|
<li><a href="http://developer.berlios.de/projects/jim">Berlios Project Page</a></li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<script language="javascript">sh_highlightDocument();</script>
|
||
|
</body>
|
||
|
</html>
|