source: project/sqlite3-tinyclos/sqlite3-tinyclos.html @ 384

Last change on this file since 384 was 384, checked in by Thomas Chust, 15 years ago

Useless keyword argument add-slot removed from
sqlite3:define-stored-object-class

File size: 21.1 KB
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2<!-- Generated by eggdoc Revision: 1.17  -->
3<html>
4<head>
5<title>Eggs Unlimited - sqlite3-tinyclos</title><style type="text/css"> <!--
6      CODE {
7            color: #666666;
8          }
9/*   DT.definition EM { font-weight: bold; font-style: normal; } */
10
11     DT.definition { 
12                   background: #eee;
13                   color: black;
14                   padding: 0.2em 1em 0.2em 0.7em;
15                   margin-left: 0.2em;
16border: 1px solid #bbc;
17                   font-family: "Andale Mono", monospace;
18                   /* font-size: 1.2em; */
19                   
20                 }
21     DD {
22                   margin-top: 0.8em;
23                   margin-bottom: 0.8em;
24     }
25     DIV.subsection {
26                    border-top: 1px solid #448;
27                    padding-left: 1em;
28     }
29         DIV.section {
30                 margin-bottom: 1.5em;
31         }
32         a:link {
33                 color: #336;
34         }
35         a:visited { color: #666; }
36         a:active  { color: #966; }
37         a:hover   { color: #669; }
38         body { margin: 0; padding: 0; background: #fff; color: #000; font: 9pt "Lucida Grande", "Verdana", sans-serif; }
39         H2 {
40                 background: #336;
41                 color: #fff;
42                 padding-top: 0.5em;
43                 padding-bottom: 0.5em;
44                 padding-left: 16px;
45                 margin: 0 0 1em 0;
46        }
47        LI {
48                list-style: none;
49        }
50        TT {
51                font-family: "Andale Mono", monospace;
52                /* font-size: 1.2em; */
53        }
54        H3 {
55                color: #113;
56                margin-bottom: 0.5em;
57        }
58     DIV#eggheader {
59         text-align: center;
60                 float: right;
61                 margin-right: 2em;
62     }
63     DIV#header IMG {
64            /* display: block; margin-left: auto; margin-right: auto;  */
65            /* float: right; */
66            border: none;  /* firefox */
67     }
68     DIV#footer {
69                background: #bbd;
70                padding: 0.7em ;
71                border-top: 1px solid #cce;
72     }
73     DIV#footer hr {
74                display: none;
75     }
76     DIV#footer a {
77                float: left;
78     }
79     DIV#revision-history {
80         float: right;
81     }
82     
83     DIV#body {
84                 margin: 1em 1em 1em 16px;
85         }
86
87     DIV#examples PRE {
88       background: #eef;
89       padding: 0.1em;
90       border: 1px solid #aac;
91     }
92     PRE#license, DIV#examples PRE {
93       padding: 0.5em;
94     }
95     DIV#examples PRE {
96       /* font-size: 85%; */
97     }
98     PRE { font-family: "Andale Mono", monospace; }
99     TABLE {
100       background: #eef;
101       padding: 0.2em;
102       border: 1px solid #aac;
103       width: 100%;
104     }
105     TABLE.symbol-table TD.symbol {
106          width: 15em;
107          font-family: "Andale Mono", monospace;
108          /* font-size: 1.2em; */
109     }
110     TH {
111       border-bottom: 1px solid black;
112     } --></style></head>
113<body>
114<div id="header">
115<h2>sqlite3-tinyclos</h2>
116<div id="eggheader"><a href="index.html">
117<img src="egg.jpg" alt="[Picture of an egg]" /></a></div></div>
118<div id="body">
119<div class="section">
120<h3>Description</h3>
121<p>A bridge between persistent storage in SQLite3 tables and TinyCLOS objects.</p></div>
122<div class="section">
123<h3>Author</h3><a href="http://www.chust.org/">Thomas Chust</a></div>
124<div class="section">
125<h3>Version</h3>
126<ul>
127<li>1.2.2 Alternative superclass for generated classes added</li>
128<li>1.2.0 Superclasses of generated classes can be specified arbitrarily</li>
129<li>1.1.0 Facility to prevent creation of certain getter and/or setter methods</li>
130<li>1.0.0 Initial release</li></ul></div>
131<div class="section">
132<h3>Usage</h3><tt>(require-extension sqlite3-tinyclos)</tt></div>
133<div class="section">
134<h3>Download</h3><a href="sqlite3-tinyclos.egg">sqlite3-tinyclos.egg</a></div>
135<div class="section">
136<h3>Requires</h3>
137<ul>
138<li>sqlite3</li></ul></div>
139<div class="section">
140<h3>Documentation</h3>
141<p>This egg is intended to quickly establish an object oriented interface to data in an SQLite3 database. The interface you are provided with is rather basic, but easily extensible.</p>
142<p>In the simplest case you just create the database with its schema of tables and then call <tt>sqlite3:define-stored-object-class</tt> once for each table you want to access through this interface. See the example below for a first impression.</p>
143<div class="subsection">
144<p><b>The class generator procedure</b></p>
145<dl>
146<dt class="definition"><strong>procedure:</strong> (sqlite3:define-stored-object-class (db &lt;sqlite3:database&gt;) (table &lt;string&gt;) #!key prefix name symbol add-super supers slots) =&gt; &lt;void&gt;</dt>
147<dd>
148<p>This procedure creates a TinyCLOS class of metaclass <tt>&lt;sqlite3:stored-object-class&gt;</tt> and superclasses <tt>supers</tt>, defaulting to a list containing only <tt>&lt;sqlite3:stored-object&gt;</tt>. The new class can be instantiated to access data stored in the <tt>table</tt> of the given SQLite3 <tt>db</tt>.</p>
149<p>Additional value slots for the instances can be obtained by specifying a list as keyword parameter <tt>slots</tt>.</p>
150<p>The list specified for <tt>supers</tt> can be chosen arbitrarily but it should probably contain either <tt>&lt;sqlite3:stored-object&gt;</tt> itself or a subclass of it. To just add superclasses in addition to the default one you may want to use <tt>add-super</tt> keyword parameters, which are prepended in sequence to the list specified by <tt>supers</tt> or the default list.</p>
151<p>The prefix referred to in the following paragraphs is either taken from the corresponding keyword argument or, if no such argument is given, is assumed to be the empty string.</p>
152<p>The generated class has the name given as a keyword argument or, if no such argument is present, a name composed of the prefix and the table name stripped of any trailing 's' characters.</p>
153<p>The generated class is assigned to the global variable specified by <tt>symbol</tt> or, if no such argument is given, the symbol composed of an opening angle bracket, the name of the class and a closing angle bracket.</p>
154<p>For all columns in the table that are not part of the primary key, two accessor methods for retrieving and setting them are defined, with names computed by <tt>sqlite3:field-name-&gt;getter-symbol</tt> and <tt>sqlite3:field-name-&gt;setter-symbol</tt> respectively. If a list is passed in the keyword argument <tt>no-getter-or-setter</tt> and it contains the name of a database field, no getter or setter is created for this field. Likewise no getter is generated for columns mentioned in <tt>no-getter</tt> and no setter is generated for those mentioned in <tt>no-setter</tt>.</p></dd></dl></div>
155<div class="subsection">
156<p><b>Generated getter and setter methods</b></p>
157<dl>
158<dt class="definition"><strong>method:</strong> (&lt;prefix&gt;&lt;name&gt; (self &lt;subclass of sqlite3:stored-object&gt;)) =&gt; &lt;top&gt;
159<br /><strong>method:</strong> (&lt;prefix&gt;&lt;name&gt;? (self &lt;subclass of sqlite3:stored-object&gt;)) =&gt; &lt;boolean&gt;</dt>
160<dd>
161<p>These methods defined by <tt>sqlite3:define-stored-object-class</tt> retrieve the value of a regular or boolean field in the database respectively. For boolean fields, whose names start with <tt>is_</tt> in the database, an automatic conversion from <tt>NULL</tt> or <tt>0</tt> to <tt>#f</tt> and anything else to <tt>#t</tt> is performed.</p></dd>
162<dt class="definition"><strong>method:</strong> (&lt;prefix&gt;set-&lt;name&gt;! (self &lt;subclass of sqlite3:stored-object&gt;) (value &lt;top&gt;)) =&gt; &lt;void&gt;</dt>
163<dd>
164<p>These methods defined by <tt>sqlite3:define-stored-object-class</tt> set the value of a field in the database. For boolean fields, whose names start with <tt>is_</tt> in the database, an automatic conversion from <tt>#f</tt> to <tt>0</tt> and anything else to <tt>1</tt> is performed.</p></dd></dl></div>
165<div class="subsection">
166<p><b>Metaclasses and classes</b></p>
167<dl>
168<dt class="definition"><strong>class:</strong> &lt;sqlite3:stored-object-class&gt;</dt>
169<dd>
170<p>The metaclass for classes generated by <tt>sqlite3:define-stored-object-class</tt>. It provides its class instances with facilities to store the database handle and analyze the schema.</p>
171<p>In particular, instances of this class contain <tt>db</tt>, <tt>table</tt>, <tt>pk</tt> and <tt>fields</tt> slots. Of these <tt>db</tt> and <tt>table</tt> must be set when instantiating (which is automatically done by <tt>sqlite3:define-stored-object-class</tt>), while <tt>pk</tt> and <tt>fields</tt> are computed by the <tt>initialize</tt> method. All these fields should be read with the accessors described below.</p></dd>
172<dt class="definition"><strong>class:</strong> &lt;sqlite3:stored-object&gt;</dt>
173<dd>
174<p>The common base class of classes generated by <tt>sqlite3:define-stored-object-class</tt>. It provides general facilities for row level data access.</p>
175<p>In particular, instances of this class contain a <tt>pk</tt> slot storing the current values of the primary key columns for this object. The contents of this slot should be retrieved and set using the accessors described below. When creating an object of class <tt>&lt;sqlite3:stored-object&gt;</tt>, the <tt>pk</tt> slot can either be set with the usual TinyCLOS initialization argument syntax or by specifying exactly all the primary key values as initialization arguments.</p>
176<p>The <tt>initialize</tt> method for this class also checks whether a row with the specified primary key already exists in the database using <tt>sqlite3:in-store?</tt> and inserts such a row using <tt>sqlite3:create-in-store!</tt> if this is not the case.</p></dd>
177<dt class="definition"><strong>class:</strong> &lt;sqlite3:stored-object/automatic-integer-pk&gt;</dt>
178<dd>
179<p>This subclass of <tt>&lt;sqlite3:stored-object&gt;</tt> has a modified <tt>sqlite3:in-store?</tt> method that automatically allocates a new primary key one larger than the largest one in use if the object was created with an empty primary key. This means that objects created by a simple <tt>(make &lt;class&gt;)</tt> call, where <tt>&lt;class&gt;</tt> is a subclass of <tt>&lt;sqlite3:stored-object/automatic-integer-pk&gt;</tt>, will immediately be entered into the database with a new unique id.</p>
180<p><em>Note that this class can only be used sensibly with tables that have a single integer primary key. Also note that instances of this class should only be created with proper exclusive locks on the database in place.</em></p></dd></dl></div>
181<div class="subsection">
182<p><b>Methods</b></p>
183<dl>
184<p>The following methods are common to the standard metaclass and class:</p>
185<dt class="definition"><strong>method:</strong> (sqlite3:db (self &lt;sqlite3:stored-object-class&gt;)) =&gt; &lt;sqlite3:database&gt;
186<br /><strong>method:</strong> (sqlite3:db (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;sqlite3:database&gt;</dt>
187<dd>
188<p>Given a stored object class or a stored object instance this method returns the database connection that object belongs to.</p></dd>
189<dt class="definition"><strong>method:</strong> (sqlite3:table (self &lt;sqlite3:stored-object-class&gt;)) =&gt; &lt;string&gt;
190<br /><strong>method:</strong> (sqlite3:table (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;string&gt;</dt>
191<dd>
192<p>Given a stored object class or a stored object instance this method returns the name of the database table that holds the instances of the class or the object respectively.</p></dd>
193<dt class="definition"><strong>method:</strong> (sqlite3:pk (self &lt;sqlite3:stored-object-class&gt;)) =&gt; &lt;list of string&gt;
194<br /><strong>method:</strong> (sqlite3:pk (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;list of string&gt;</dt>
195<dd>
196<p>Given a stored object class this method returns a list of column names that hold the primary key for objects of this class.</p>
197<p>Given a stored object instance this method returns the list of primary key values for this object corresponding in sequence to the list of primary key columns.</p></dd>
198<dt class="definition"><strong>method:</strong> (sqlite3:pk/select (self &lt;sqlite3:stored-object-class&gt;)) =&gt; &lt;string&gt;
199<br /><strong>method:</strong> (sqlite3:pk/select (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;string&gt;</dt>
200<dd>
201<p>Given a stored object class or a stored object instance this method returns a comma separated list of primary key column names.</p></dd>
202<dt class="definition"><strong>method:</strong> (sqlite3:pk/update (self &lt;sqlite3:stored-object-class&gt;)) =&gt; &lt;string&gt;
203<br /><strong>method:</strong> (sqlite3:pk/update (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;string&gt;</dt>
204<dd>
205<p>Given a stored object class or a stored object instance this method returns a comma separated list of tokens in the form <tt>primary_key_column_name = ?</tt>.</p></dd>
206<dt class="definition"><strong>method:</strong> (sqlite3:pk/where (self &lt;sqlite3:stored-object-class&gt;)) =&gt; &lt;string&gt;
207<br /><strong>method:</strong> (sqlite3:pk/where (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;string&gt;</dt>
208<dd>
209<p>Given a stored object class or a stored object instance this method returns a list of tokens in the form <tt>primary_key_column_name = ?</tt>, separated by the word <tt>AND</tt>.</p></dd>
210<dt class="definition"><strong>method:</strong> (sqlite3:fields (self &lt;sqlite3:stored-object-class&gt;)) =&gt; &lt;list of string&gt;
211<br /><strong>method:</strong> (sqlite3:fields (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;list of string&gt;</dt>
212<dd>
213<p>Given a stored object class or a stored object instance this method returns a list of column names which are not part of the primary key.</p></dd></dl>
214<dl>
215<p>The following methods are available for objects of class <tt>&lt;sqlite3:stored-object&gt;</tt>:</p>
216<dt class="definition"><strong>method:</strong> (sqlite3:set-pk! (self &lt;sqlite3:stored-object&gt;) . new-pk) =&gt; &lt;void&gt;</dt>
217<dd>
218<p>Changes the value of the primary key columns for the given object to the new given values.</p></dd>
219<dt class="definition"><strong>method:</strong> (sqlite3:in-store? (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;boolean&gt;</dt>
220<dd>
221<p>Checks whether a row with the currently set primary key column values (still) exists in the database.</p></dd>
222<dt class="definition"><strong>method:</strong> (sqlite3:create-in-store! (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;boolean&gt;</dt>
223<dd>
224<p>Creates a row with the currently set primary key column values and default values for all other columns if no such row already exists. Returns <tt>#t</tt> or <tt>#f</tt> if a row was inserted or not.</p>
225<p>This method may return <tt>#f</tt> if a row with the given primary key already exists, but it may also return <tt>#f</tt> if the database imposes some constraints on the values of further rows that is not fulfilled by the default values. You should generally either not create tables with such constraints for use with this egg or you should override <tt>sqlite3:create-in-store!</tt> for your stored object classes because it is called from <tt>initialize</tt> if an object of class <tt>&lt;sqlite3:stored-object&gt;</tt> is created with a not yet existing primary key.</p></dd>
226<dt class="definition"><strong>method:</strong> (sqlite3:remove-from-store! (self &lt;sqlite3:stored-object&gt;)) =&gt; &lt;boolean&gt;</dt>
227<dd>
228<p>Removes the row with the currently stored primary key column values from the database and returns <tt>#t</tt> or returns <tt>#f</tt> and does nothing if no such row exists.</p></dd></dl>
229<dl>
230<p>The following two methods should seldomly be needed, as specific field accessors are generated automatically by <tt>sqlite3:define-stored-object-class</tt>:</p>
231<dt class="definition"><strong>method:</strong> (sqlite3:get-stored-property (self &lt;sqlite3:stored-object&gt;) (name &lt;string&gt;)) =&gt; &lt;top&gt;</dt>
232<dd>
233<p>Retrieves the value stored in column <tt>name</tt> from the table apropriate for this object where the primary key columns have the values currently stored in this object.</p></dd>
234<dt class="definition"><strong>method:</strong> (sqlite3:set-stored-property! (self &lt;sqlite3:stored-object&gt;) (name &lt;string&gt;) (value &lt;top&gt;)) =&gt; &lt;void&gt;</dt>
235<dd>
236<p>Sets the column <tt>name</tt> to the given <tt>value</tt> in the table apropriate for this object where the primary key columns have the values stored in this object.</p></dd></dl></div>
237<div class="subsection">
238<p><b>Helper procedures</b></p>
239<dl>
240<dt class="definition"><strong>procedure:</strong> (sqlite3:field-name-&gt;getter-symbol (name &lt;string&gt;) #!optional ((prefix &lt;string|symbol&gt;) &quot;&quot;)) =&gt; &lt;symbol&gt;</dt>
241<dd>
242<p>Given the name of a database column this procedure returns a mangled version of the name with underscores replaced by dashes and the prefix <tt>is-</tt> replaced by a trailing question mark. Thus the return value is a scheme symbol in the form <tt>&lt;prefix&gt;&lt;name&gt;[?]</tt>.</p>
243<p>This procedure is internally used by <tt>sqlite3:define-stored-object-class</tt> to compute the names of getter methods.</p></dd>
244<dt class="definition"><strong>procedure:</strong> (sqlite3:field-name-&gt;setter-symbol (name &lt;string&gt;) #!optional ((prefix &lt;string|symbol&gt;) &quot;&quot;)) =&gt; &lt;symbol&gt;</dt>
245<dd>
246<p>Given the name of a database column this procedure returns a mangled version of the name with underscores replaced by dashes and the prefix <tt>is-</tt> stripped. In addition to the given prefix, <tt>set-</tt> is prepended to the result and an exclamation mark is appended. Thus the return value is a scheme symbol in the form <tt>&lt;prefix&gt;set-&lt;name&gt;!</tt>.</p>
247<p>This procedure is internally used by <tt>sqlite3:define-stored-object-class</tt> to compute the names of setter methods.</p></dd></dl></div>
248<div class="section">
249<h3>Examples</h3>
250<div id="examples"><pre>
251<i><font color="#B22222">;;;; sqlite3-tinyclos-demo.scm
252</font></i><i><font color="#B22222">;;;; Small demonstration of the capabilities of sqlite3-tinyclos
253</font></i>
254<i><font color="#B22222">;;; load extensions
255</font></i>(require-extension
256  sqlite3 tinyclos sqlite3-tinyclos)
257
258<i><font color="#B22222">;;; create a database
259</font></i>(<b><font color="#A020F0">define</font></b> <b><font color="#0000FF">db</font></b>
260  (sqlite3:open <font color="#BC8F8F"><b>"test.db"</b></font>))
261
262(sqlite3:exec db
263  <font color="#BC8F8F"><b>"CREATE TABLE eggs(
264                  name TEXT NOT NULL, license TEXT, is_module INTEGER NOT NULL DEFAULT 0,
265                  PRIMARY KEY(name), CHECK(is_module IN (0, 1)));"</b></font>)
266
267<i><font color="#B22222">;;; define the object class
268</font></i>(sqlite3:define-stored-object-class db <font color="#BC8F8F"><b>"eggs"</b></font>)
269
270<i><font color="#B22222">;;; add some data
271</font></i>(<b><font color="#A020F0">let</font></b> ((egg (make &lt;egg&gt; <font color="#BC8F8F"><b>"sqlite3"</b></font>)))
272  <i><font color="#B22222">;; now the entry should already exist
273</font></i>  (print (sqlite3:in-store? egg))
274  <i><font color="#B22222">;; let's add some data
275</font></i>  (set-license! egg <font color="#BC8F8F"><b>"BSD"</b></font>)
276  <i><font color="#B22222">;; and read it back
277</font></i>  (print (license egg))
278  <i><font color="#B22222">;; other fields are filled with default data
279</font></i>  (print (module? egg))
280  <i><font color="#B22222">;; changing the primary key is possible as well
281</font></i>  (sqlite3:set-pk! egg <font color="#BC8F8F"><b>"foo"</b></font>)
282  (print (sqlite3:pk egg))
283  <i><font color="#B22222">;; which does not change data, of course
284</font></i>  (print (license egg))
285  <i><font color="#B22222">;; and we can also delete the entry
286</font></i>  (print (sqlite3:remove-from-store! egg))
287  <i><font color="#B22222">;; then it is gone
288</font></i>  (print (sqlite3:in-store? egg)))
289
290<i><font color="#B22222">;;;; vim:set shiftwidth=2 softtabstop=2: ;;;;
291</font></i></pre></div></div>
292<div class="section">
293<h3>License</h3>
294<pre id="license">Copyright (c) 2006, Thomas Chust &lt;chust@web.de&gt;.  All rights reserved.
295
296Redistribution and use in source and binary forms, with or without
297modification, are permitted provided that the following conditions are met:
298
299  Redistributions of source code must retain the above copyright notice,
300  this list of conditions and the following disclaimer. Redistributions in
301  binary form must reproduce the above copyright notice, this list of
302  conditions and the following disclaimer in the documentation and/or
303  other materials provided with the distribution. Neither the name of the
304  author nor the names of its contributors may be used to endorse or
305  promote products derived from this software without specific prior
306  written permission.
307
308THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS
309IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
310THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
311PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
312CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
313EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
314PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
315PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
316LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
317NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
318SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</pre></div></div></div>
319<div id="footer">
320<hr /><a href="index.html">&lt; Egg index</a>
321<div id="revision-history">$Revision$ $Date$</div>&nbsp;</div></body></html>
Note: See TracBrowser for help on using the repository browser.