webif/var/mongoose/html/jim/sqlite.html
hummypkg 240a4d7589 updates barring channel icons
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif@172 2a923420-c742-0410-a762-8d5b09965624
2011-06-14 11:48:55 +00:00

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 &lsquo;method&rsquo; or &lsquo;subcommand&rsquo; (&ldquo;query&rdquo; 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 &ldquo;%s&rdquo; 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
&ldquo;&rsquo;&rdquo; 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 &ldquo;&rsquo;&rdquo;:</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 &lsquo;%&rsquo; character in the query, there is just
to use two, like in &ldquo;foo %% bar&rdquo;. 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 &lsquo;close&rsquo; 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 &lsquo;tbl1&rsquo; table. Now
we can add usign the &ldquo;sqlite&rdquo; command line client another one with
a NULL value:</p>
<pre><code>sqlite&gt; INSERT INTO tbl1 VALUES(NULL,30);
sqlite&gt; .exit
</code></pre>
<p>That&rsquo;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&rsquo;s
the empty string. Using the -null option of the &lsquo;query&rsquo; 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 &lt;&lt;NULL&gt;&gt; "SELECT * from tbl1"
{one hello! two 10} {one goodbye two 20} {one &lt;&lt;NULL&gt;&gt; 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 &lsquo;changes&rsquo; 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&rsquo;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&rsquo;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>