Changes to more broadly support auto-increment. new odbc-postgresql-database type
[clsql.git] / doc / ref-ooddl.xml
1 <?xml version='1.0' ?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
3 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
4 <!ENTITY % myents SYSTEM "entities.inc">
5 %myents;
6 ]>
7
8 <!-- Object Oriented Data Definition Language -->
9 <reference id="ref-ooddl">
10   <title>Object Oriented Data Definition Language (OODDL)</title>
11   <partintro>
12     <para>
13       The Object Oriented Data Definition Language (OODDL) provides
14       access to relational SQL tables using Common Lisp Object System
15       (CLOS) objects.  SQL tables are mapped to CLOS objects with the
16       SQL columns being mapped to slots of the CLOS object.
17     </para>
18     <para>
19       The mapping between SQL tables and CLOS objects is defined with
20       the macro <link
21       linkend="def-view-class"><function>def-view-class</function></link>. SQL
22       tables are created with <link
23       linkend="create-view-from-class"><function>create-view-from-class</function></link>
24       and SQL tables can be deleted with <link
25       linkend="drop-view-from-class"><function>drop-view-from-class</function></link>.
26     </para>
27     <note>
28       <para>The above functions refer to the Lisp
29       <emphasis>view</emphasis> of the SQL table. This Lisp view
30       should not be confused with SQL <function>VIEW</function>
31       statement.</para>
32     </note>
33   </partintro>
34
35   <refentry id="standard-db-object">
36     <refnamediv>
37       <refname>STANDARD-DB-OBJECT</refname>
38       <refpurpose>Superclass for all &clsql; View Classes.</refpurpose>
39       <refclass>Class</refclass>
40     </refnamediv>
41     <refsect1>
42       <title>Class Precedence List</title>
43       <para>
44         <simplelist type="inline">
45           <member><type>standard-db-object</type></member>
46           <member><type>standard-object</type></member>
47           <member><type>t</type></member>
48         </simplelist>
49       </para>
50     </refsect1>
51     <refsect1>
52       <title>Description</title> <para>This class is the superclass
53       of all &clsql; View Classes.</para>
54     </refsect1>
55     <refsect1>
56       <title>Class details</title>
57       <programlisting>(defclass STANDARD-DB-OBJECT ()(...))</programlisting>
58     </refsect1>
59     <refsect1>
60       <title>Slots</title>
61       <para>
62         <simplelist>
63           <member>slot VIEW-DATABASE is of type (OR NULL DATABASE)
64           which stores the associated database for the
65           instance.</member>
66         </simplelist>
67       </para>
68     </refsect1>
69   </refentry>
70
71   <refentry id="default-string-length">
72     <refnamediv>
73       <refname>*DEFAULT-STRING-LENGTH*</refname>
74       <refpurpose>Default length of SQL strings.</refpurpose>
75       <refclass>Variable</refclass>
76     </refnamediv>
77     <refsect1>
78       <title>Value Type</title>
79       <para>
80         Fixnum
81       </para>
82     </refsect1>
83     <refsect1>
84       <title>Initial Value</title>
85       <para><parameter>255</parameter></para>
86     </refsect1>
87     <refsect1>
88       <title>Description</title>
89       <para>
90         If a slot of a class defined by
91         <function>def-view-class</function> is of the type
92         <parameter>string</parameter> or
93         <parameter>varchar</parameter> and does not have a length
94         specified, then the value of this variable is used as SQL
95         length.
96       </para>
97     </refsect1>
98     <refsect1>
99       <title>Examples</title>
100       <screen>
101 (let ((*default-string-length* 80))
102   (def-view-class s80 ()
103     ((a :type string)
104      (b :type (string 80))
105      (c :type varchar))))
106 => #&lt;Standard-Db-Class S80 {480A431D}>
107
108 (create-view-from-class 's80)
109 =>
110 (table-exists-p [s80])
111 => T
112       </screen>
113       <para>
114         The above code causes a SQL table to be created with the SQL command
115       </para>
116       <screen>CREATE TABLE (A VARCHAR(80), B CHAR(80), C VARCHAR(80))</screen>
117     </refsect1>
118     <refsect1>
119       <title>Affected By</title>
120       <para>
121         Some SQL backends do not support
122         <parameter>varchar</parameter> lengths greater than 255.
123       </para>
124     </refsect1>
125     <refsect1>
126       <title>See Also</title>
127       <para>None.</para>
128     </refsect1>
129     <refsect1>
130       <title>Notes</title>
131       <para>This is a CLSQL extension to the CommonSQL API.</para>
132     </refsect1>
133   </refentry>
134
135   <refentry id="create-view-from-class">
136     <refnamediv>
137       <refname>CREATE-VIEW-FROM-CLASS</refname>
138       <refpurpose>Create a SQL table from a <glossterm linkend="gloss-view-class">View Class</glossterm>.</refpurpose>
139       <refclass>Function</refclass>
140     </refnamediv>
141     <refsect1>
142       <title>Syntax</title>
143       <synopsis>
144       <function>create-view-from-class</function> <replaceable>view-class-name</replaceable> &amp;key <replaceable>database</replaceable> <replaceable>transactions</replaceable> => <returnvalue><!-- no values --></returnvalue></synopsis>
145     </refsect1>
146     <refsect1>
147       <title>Arguments and Values</title>
148       <variablelist>
149         <varlistentry>
150           <term><parameter>view-class-name</parameter></term>
151           <listitem>
152             <para>
153               The name of a <glossterm linkend="gloss-view-class">View
154               Class</glossterm> that has been defined with <link
155               linkend="def-view-class"><function>def-view-class</function></link>.
156             </para>
157           </listitem>
158         </varlistentry>
159         <varlistentry>
160           <term><parameter>database</parameter></term>
161           <listitem>
162             <para>
163               The <glossterm
164               linkend="gloss-database-object">database</glossterm> in
165               which to create the SQL table. This will default to the
166               value of <symbol>*default-database*</symbol>.
167             </para>
168           </listitem>
169         </varlistentry>
170         <varlistentry>
171           <term><parameter>transactions</parameter></term>
172           <listitem>
173             <para>
174               When &nil; specifies that a table type which does not
175               support transactions should be used.
176             </para>
177           </listitem>
178         </varlistentry>
179       </variablelist>
180     </refsect1>
181     <refsect1>
182       <title>Description</title>
183       <para>
184         Creates a table as defined by the <glossterm
185         linkend="gloss-view-class">View Class</glossterm>
186         <parameter>view-class-name</parameter> in
187         <parameter>database</parameter>.
188       </para>
189     </refsect1>
190     <refsect1>
191       <title>Examples</title>
192       <screen>
193 (def-view-class foo () ((a :type (string 80))))
194 => #&lt;Standard-Db-Class FOO {4807F7CD}>
195 (create-view-from-class 'foo)
196 =>
197 (list-tables)
198 => ("FOO")
199       </screen>
200     </refsect1>
201     <refsect1>
202       <title>Side Effects</title>
203       <para>
204         Causes a table to be created in the SQL database.
205       </para>
206     </refsect1>
207     <refsect1>
208       <title>Affected by</title>
209       <para>
210         Most SQL database systems will signal an error if a table
211         creation is attempted when a table with the same name already
212         exists. The SQL user, as specified in the database connection,
213         must have sufficient permission for table creation.
214       </para>
215     </refsect1>
216     <refsect1>
217       <title>Exceptional Situations</title>
218       <para>
219         A condition will be signaled if the table can not be created
220         in the SQL database.
221       </para>
222     </refsect1>
223     <refsect1>
224       <title>See Also</title>
225       <para>
226         <simplelist>
227           <member><link linkend="def-view-class"><function>def-view-class</function></link></member>
228           <member><link linkend="drop-view-from-class"><function>drop-view-from-class</function></link></member>
229         </simplelist>
230       </para>
231     </refsect1>
232     <refsect1>
233       <title>Notes</title>
234       <para>
235         Currently, only &mysql; supports transactionless
236         tables. &clsql; provides the ability to create such tables for
237         applications which would benefit from faster table access and
238         do not require transaction support.
239       </para>
240       <para>
241         The case of the table name is determined by the type of the
242         database. &mysql;, for example, creates databases in upper-case
243         while &postgresql; uses lowercase.
244       </para>
245     </refsect1>
246   </refentry>
247
248   <refentry id="def-view-class">
249     <refnamediv>
250       <refname>DEF-VIEW-CLASS</refname>
251       <refpurpose>Defines CLOS classes with mapping to SQL database.</refpurpose>
252       <refclass>Macro</refclass>
253     </refnamediv>
254     <refsect1>
255       <title>Syntax</title>
256       <synopsis>
257       <function>def-view-class</function> <replaceable>name</replaceable> <replaceable>superclasses</replaceable> <replaceable>slots</replaceable> &amp;rest <replaceable>class-options</replaceable> => <returnvalue>class</returnvalue></synopsis>
258     </refsect1>
259     <refsect1>
260       <title>Arguments and Values</title>
261       <variablelist>
262         <varlistentry>
263           <term><parameter>name</parameter></term>
264           <listitem>
265             <para>
266               The class name.
267             </para>
268           </listitem>
269         </varlistentry>
270         <varlistentry>
271           <term><parameter>superclasses</parameter></term>
272           <listitem>
273             <para>
274               The superclasses for the defined class.
275             </para>
276           </listitem>
277         </varlistentry>
278         <varlistentry>
279           <term><parameter>slots</parameter></term>
280           <listitem>
281             <para>
282               The class slot definitions.
283             </para>
284           </listitem>
285         </varlistentry>
286         <varlistentry>
287           <term><parameter>class options</parameter></term>
288           <listitem>
289             <para>
290               The class options.
291             </para>
292           </listitem>
293         </varlistentry>
294         <varlistentry>
295           <term><parameter>class</parameter></term>
296           <listitem>
297             <para>
298               The defined class.
299             </para>
300           </listitem>
301         </varlistentry>
302       </variablelist>
303     </refsect1>
304     <refsect1>
305       <title>Slot Options</title>
306       <itemizedlist>
307         <listitem>
308           <para>
309             <parameter>:db-kind</parameter> - specifies the kind of
310             database mapping which is performed for this slot and
311             defaults to <parameter>:base</parameter> which indicates
312             that the slot maps to an ordinary column of the database
313             table. A <parameter>:db-kind</parameter> value of
314             <parameter>:key</parameter> indicates that this slot is a
315             special kind of <parameter>:base</parameter> slot which
316             maps onto a column which is one of the unique keys for the
317             database table, the value <parameter>:join</parameter>
318             indicates this slot represents a join onto another
319             <glossterm linkend="gloss-view-class">View Class</glossterm>
320             which contains View Class objects, and the value
321             <parameter>:virtual</parameter> indicates a standard CLOS
322             slot which does not map onto columns of the database
323             table.
324           </para>
325         </listitem>
326         <listitem>
327           <para>
328             <parameter>:db-info</parameter> - if a slot is specified
329             with <parameter>:db-kind</parameter>
330             <parameter>:join</parameter>, the slot option
331             <parameter>:db-info</parameter> contains a property list
332             which specifies the nature of the join. The valid members
333             of the list are:
334           </para>
335           <itemizedlist>
336             <listitem>
337               <para>
338                 <parameter>:join-class</parameter>
339                 <emphasis>class-name</emphasis> - the name of the
340                 class to join on.
341               </para>
342             </listitem>
343             <listitem>
344               <para>
345                 <parameter>:home-key</parameter>
346                 <emphasis>slot-name</emphasis> - the name of the slot
347                 of this class for joining
348               </para>
349             </listitem>
350             <listitem>
351               <para>
352                 <parameter>:foreign-key</parameter>
353                 <emphasis>slot-name</emphasis> - the name of the slot
354                 of the <parameter>:join-class</parameter> for joining
355               </para>
356             </listitem>
357             <listitem>
358               <para>
359                 <parameter>:target-slot</parameter>
360                 <emphasis>target-slot</emphasis> - this is an optional
361                 parameter. If specified, then the join slot of the
362                 defining class will contain instances of this target
363                 slot rather than of the join class. This can be useful
364                 when the <parameter>:join-class</parameter> is an
365                 intermediate class in a
366                 <emphasis>many-to-many</emphasis> relationship and the
367                 application is actually interested in the
368                 <parameter>:target-slot</parameter>.
369               </para>
370             </listitem>
371             <listitem>
372               <para>
373                 <parameter>:retrieval</parameter>
374                 <emphasis>time</emphasis> - The default value is
375                 <parameter>:deferred</parameter>, which defers filling
376                 this slot until the value is accessed. The other valid
377                 value is <parameter>:immediate</parameter> which
378                 performs the SQL query when the instance of the class
379                 is created. In this case, the
380                 <parameter>:set</parameter> is automatically set to
381                 &nil;
382               </para>
383             </listitem>
384             <listitem>
385               <para>
386                 <parameter>:set</parameter> <emphasis>set</emphasis> -
387                 This controls what is stored in the join slot.  The
388                 default value is &t;. When <emphasis>set</emphasis> is
389                 &t; and <emphasis>target-slot</emphasis> is undefined,
390                 the join slot will contain a list of instances of the
391                 join class. Whereas, if
392                 <emphasis>target-slot</emphasis> is defined, then the
393                 join slot will contain a list of pairs of
394                 <emphasis>(target-value join-instance)</emphasis>.
395                 When <emphasis>set</emphasis> is &nil;, the join slot
396                 will contain a single instances.
397               </para>
398             </listitem>
399           </itemizedlist>
400         </listitem>
401         <listitem>
402           <para>
403             <parameter>:type</parameter> - for slots of
404             <parameter>:db-kind</parameter> <parameter>:base</parameter> or
405             <parameter>:key</parameter>, the <parameter>:type</parameter> slot
406             option has a special interpretation such that Lisp
407             types, such as string, integer and float are
408             automatically converted into appropriate SQL types for
409             the column onto which the slot maps. This behaviour may
410             be overridden using the <parameter>:db-type</parameter> slot
411             option. The valid values are:
412             <simplelist>
413               <member>
414                 <parameter>string</parameter> - a variable length
415                 character field up to <link
416                 linkend="default-string-length">*default-string-length*</link>
417                 characters.
418               </member>
419               <member>
420                 <parameter>(string n)</parameter> - a fixed length
421                 character field <parameter>n</parameter> characters
422                 long.
423               </member>
424               <member>
425                 <parameter>varchar</parameter> - a variable length
426                 character field up to <link
427                 linkend="default-string-length">*default-string-length*</link>
428                 characters.
429               </member>
430               <member>
431                 <parameter>(varchar n)</parameter> - a variable length
432                 character field up to <parameter>n</parameter>
433                 characters in length.
434               </member>
435               <member>
436                 <parameter>char</parameter> - a single character field
437               </member>
438               <member><parameter>integer</parameter> - signed integer
439               at least 32-bits wide</member>
440               <member><parameter>(integer n)</parameter></member>
441               <member><parameter>float</parameter></member>
442               <member><parameter>(float n)</parameter></member>
443               <member><parameter>long-float</parameter></member>
444               <member><parameter>number</parameter></member>
445               <member><parameter>(number n)</parameter></member>
446               <member><parameter>(number n p)</parameter></member>
447               <member>
448                 <parameter>tinyint</parameter> - An integer column 8-bits
449                 wide. [not supported by all database backends]
450               </member>
451               <member>
452                 <parameter>smallint</parameter> - An integer column 16-bits
453                 wide. [not supported by all database backends]
454               </member>
455               <member>
456                 <parameter>bigint</parameter> - An integer column
457                 64-bits wide. [not supported by all database backends]
458               </member>
459               <member>
460                 <parameter>universal-time</parameter> - an integer
461                 field sufficiently wide to store a
462                 universal-time. On most databases, a slot of this
463                 type assigned a SQL type of
464                 <parameter>BIGINT</parameter>
465               </member>
466               <member>
467                 <parameter>wall-time</parameter> - a slot which stores
468                 a date and time in a SQL timestamp column. &clsql;
469                 provides a number of time manipulation functions to
470                 support objects of type <type>wall-time</type>.
471               </member>
472               <member>
473                 <parameter>date</parameter> - a slot which stores the
474                 date (without any time of day resolution) in a
475                 column. &clsql; provides a number of time
476                 manipulation functions that operate on date values.
477               </member>
478               <member>
479                 <parameter>duration</parameter> - stores a
480                 <type>duration</type> structure.  &clsql; provides
481                 routines for <type>wall-time</type> and
482                 <type>duration</type> processing.
483               </member>
484               <member><parameter>boolean</parameter> - stores a &t; or
485               &nil; value.</member>
486               <member>
487                 <parameter>generalized-boolean</parameter> - similar
488                 to a <parameter>boolean</parameter> in that either a
489                 &t; or &nil; value is stored in the SQL
490                 database. However, any Lisp object can be stored in
491                 the Lisp object. A Lisp value of &nil; is stored as
492                 <constant>FALSE</constant> in the database, any
493                 other Lisp value is stored as
494                 <constant>TRUE</constant>.
495               </member>
496               <member>
497                 <parameter>keyword</parameter> - stores a keyword
498               </member>
499               <member><parameter>symbol</parameter> - stores a symbol</member>
500               <member>
501                 <parameter>list</parameter> - stores a list by writing
502                 it to a string. The items in the list must be able to
503                 be readable written.
504               </member>
505               <member><parameter>vector</parameter> - stores a vector
506               similarly to <parameter>list</parameter></member>
507               <member><parameter>array</parameter> - stores a array
508               similarly to <parameter>list</parameter></member>
509             </simplelist>
510           </para>
511
512         </listitem>
513         <listitem>
514           <para>
515             <parameter>:column</parameter> - specifies the name of
516             the SQL column which the slot maps onto, if
517             <parameter>:db-kind</parameter> is not
518             <parameter>:virtual</parameter>, and defaults to the
519             slot name. If the slot name is used for the SQL column
520             name, any hypens in the slot name are converted
521             to underscore characters.
522           </para>
523         </listitem>
524         <listitem>
525           <para>
526             <parameter>:void-value</parameter> - specifies the value
527             to store in the Lisp instance if the SQL value is NULL and
528             defaults to NIL.
529           </para>
530         </listitem>
531         <listitem>
532           <para>
533             <parameter>:db-constraints</parameter> - is a keyword
534             symbol representing an SQL column constraint expression or
535             a list of such symbols. The following column constraints
536             are supported: <symbol>:not-null</symbol>,
537             <symbol>:primary-key</symbol>, <symbol>:unique</symbol>,
538             <symbol>:unsigned</symbol> (&mysql; specific),
539             <symbol>:zerofill</symbol> (&mysql; specific) and
540             <symbol>:auto-increment</symbol> (&mysql; specific).
541           </para>
542         </listitem>
543         <listitem>
544           <para>
545             <parameter>:db-type</parameter> - a string to specify the SQL
546             column type. If specified, this string overrides the SQL
547             column type as computed from the <parameter>:type</parameter>
548             slot value.
549           </para>
550         </listitem>
551         <listitem>
552           <para>
553             <parameter>:db-reader</parameter> - If a string, then when
554             reading values from the database, the string will be used
555             for a format string, with the only value being the value
556             from the database.  The resulting string will be used as
557             the slot value.  If a function then it will take one
558             argument, the value from the database, and return the
559             value that should be put into the slot. If a symbol, then
560             the symbol-function of the symbol will be used.
561           </para>
562         </listitem>
563         <listitem>
564           <para>
565             <parameter>:db-writer</parameter> - If a string, then when
566             reading values from the slot for the database, the string
567             will be used for a format string, with the only value
568             being the value of the slot.  The resulting string will be
569             used as the column value in the database.  If a function
570             then it will take one argument, the value of the slot, and
571             return the value that should be put into the database. If
572             a symbol, then the symbol-function of the symbol will be
573             used.
574           </para>
575         </listitem>
576       </itemizedlist>
577     </refsect1>
578     <refsect1>
579       <title>Class Options</title>
580       <para>
581         <itemizedlist>
582           <listitem>
583             <para>
584               <parameter>:base-table</parameter> - specifies the name
585               of the SQL database table. The default value is the
586               class name. Like slot names, hypens in the class name
587               are converted to underscore characters.
588             </para>
589           </listitem>
590           <listitem>
591             <para>
592               <parameter>:normalizedp</parameter> - specifies whether
593           this class uses normalized inheritance from parent classes.
594           Defaults to nil, i.e. non-normalized schemas. When true,
595           SQL database tables that map to this class and parent
596           classes are joined on their primary keys to get the full
597           set of database columns for this class.  This means that 
598           the primary key of the base class will be copied to all 
599           subclasses as we insert so that all parent classes of an 
600           instance will have the same value in their primary key slots
601           (see tests/ds-nodes.lisp and oodml.lisp)
602             </para>
603           </listitem>
604         </itemizedlist>
605       </para>
606     </refsect1>
607     <refsect1>
608       <title>Description</title>
609       <para>
610         Creates a <glossterm linkend="gloss-view-class">View
611         Class</glossterm> called <parameter>name</parameter> whose
612         slots <parameter>slots</parameter> can map onto the attributes
613         of a table in a database. If
614         <parameter>superclasses</parameter> is &nil; then the
615         superclass of <parameter>class</parameter> will be
616         <parameter>standard-db-object</parameter>, otherwise
617         <parameter>superclasses</parameter> is a list of superclasses
618         for <parameter>class</parameter> which must include
619         <parameter>standard-db-object</parameter> or a descendent of
620         this class.
621       </para>
622
623       <refsect2>
624       <title>Normalized inheritance schemas</title>
625       <para>
626     Specifying that <symbol>:normalizedp</symbol> is <symbol>T</symbol>
627     tells &clsql; to normalize the database schema for inheritance.
628     What this means is shown in the examples below.
629       </para>
630
631       <para>
632     With <symbol>:normalizedp</symbol> equal to <symbol>NIL</symbol>
633     (the default) the class inheritance would result in the following:
634       </para>
635       <screen>
636 (def-view-class node ()
637   ((title :accessor title :initarg :title :type (varchar 240))))
638
639 SQL table NODE:
640 +-------+--------------+------+-----+---------+-------+
641 | Field | Type         | Null | Key | Default | Extra |
642 +-------+--------------+------+-----+---------+-------+
643 | TITLE | varchar(240) | YES  |     | NULL    |       |
644 +-------+--------------+------+-----+---------+-------+
645
646 (def-view-class user (node)
647   ((user-id :accessor user-id :initarg :user-id
648             :type integer :db-kind :key :db-constraints (:not-null))
649    (nick :accessor nick :initarg :nick :type (varchar 64))))
650
651 SQL table USER:
652 +---------+--------------+------+-----+---------+-------+
653 | Field   | Type         | Null | Key | Default | Extra |
654 +---------+--------------+------+-----+---------+-------+
655 | USER_ID | int(11)      | NO   | PRI |         |       |
656 | NICK    | varchar(64)  | YES  |     | NULL    |       |
657 | TITLE   | varchar(240) | YES  |     | NULL    |       |
658 +---------+--------------+------+-----+---------+-------+
659       </screen>
660
661       <para>
662     Using <symbol>:normalizedp</symbol> <symbol>T</symbol>, both
663     view-classes need a primary key to join them on:
664       </para>
665       <screen>
666 (def-view-class node ()
667   ((node-id :accessor node-id :initarg :node-id
668             :type integer :db-kind :key
669             :db-constraints (:not-null))
670    (title :accessor title :initarg :title :type (varchar 240))))
671
672 SQL table NODE:
673 +---------+--------------+------+-----+---------+-------+
674 | Field   | Type         | Null | Key | Default | Extra |
675 +---------+--------------+------+-----+---------+-------+
676 | NODE_ID | int(11)      | NO   | PRI |         |       |
677 | TITLE   | varchar(240) | YES  |     | NULL    |       |
678 +---------+--------------+------+-----+---------+-------+
679
680 (def-view-class user (node)
681   ((user-id :accessor user-id :initarg :user-id
682             :type integer :db-kind :key :db-constraints (:not-null))
683    (nick :accessor nick :initarg :nick :type (varchar 64)))
684   (:normalizedp t))
685
686 SQL table USER:
687 +---------+-------------+------+-----+---------+-------+
688 | Field   | Type        | Null | Key | Default | Extra |
689 +---------+-------------+------+-----+---------+-------+
690 | USER_ID | int(11)     | NO   | PRI |         |       |
691 | NICK    | varchar(64) | YES  |     | NULL    |       |
692 +---------+-------------+------+-----+---------+-------+
693       </screen>
694
695       <para>
696         In this second case, all slots of the view-class 'node
697         are also available in view-class 'user, and can be used
698         as one would expect. For example, with the above normalized
699         view-classes 'node and 'user, and SQL tracing turned on:
700       </para>
701       <screen>
702 CLSQL> (setq test-user (make-instance 'user :node-id 1 :nick "test-user"
703                                             :title "This is a test user"))
704 <![CDATA[#<USER {1003B392E1}>]]>
705
706 CLSQL> (update-records-from-instance test-user :database db)
707 <![CDATA[
708 ;; .. => INSERT INTO NODE (NODE_ID,TITLE) VALUES (1,'This is a test user')
709 ;; .. <= T
710 ;; .. => INSERT INTO USER (USER_ID,NICK) VALUES (1,'test-user')
711 ;; .. <= T
712 1
713 ]]>
714
715 CLSQL> (node-id test-user)
716 1
717
718 CLSQL> (title test-user)
719 "This is a test user"
720
721 CLSQL> (nick test-user)
722 "test-user"
723       </screen>
724       <para>
725         Notes from a refactor of this code.
726
727         There are many assumptions that need to be met for normalized classes to work
728
729         * The each of the classes should have its own single key column (of a different name)
730           that will contain an identical value.  EG: node has a node-id, setting which
731           is a node has a node-id and a setting-id which must be equal.  You cannot use
732           node-id as the primary key on both tables (as I would have expected).  The exception
733           to this seems to be if your class has no slots at all, then you dont need to have a
734           single key column, because your class is fully represented in the db by its parent(s)
735
736         * more than one parent class per normalized class should be considered experimental
737           and untested (vaya con Dios)
738
739         * There are a few code paths that just dont pay any attention to normalized classes
740           eg: delete-records-for-instance
741
742       </para>
743       </refsect2>
744     </refsect1>
745     <refsect1>
746       <title>Examples</title>
747       <para>
748         The following examples are from the &clsql; test suite.
749       </para>
750       <screen>
751 (def-view-class person (thing)
752   ((height :db-kind :base :accessor height :type float
753            :initarg :height)
754    (married :db-kind :base :accessor married :type boolean
755             :initarg :married)
756    (birthday :type clsql:wall-time :initarg :birthday)
757    (bd-utime :type clsql:universal-time :initarg :bd-utime)
758    (hobby :db-kind :virtual :initarg :hobby :initform nil)))
759
760 (def-view-class employee (person)
761   ((emplid
762     :db-kind :key
763     :db-constraints :not-null
764     :type integer
765     :initarg :emplid)
766    (groupid
767     :db-kind :key
768     :db-constraints :not-null
769     :type integer
770     :initarg :groupid)
771    (first-name
772     :accessor first-name
773     :type (varchar 30)
774     :initarg :first-name)
775    (last-name
776     :accessor last-name
777     :type (varchar 30)
778     :initarg :last-name)
779    (email
780     :accessor employee-email
781     :type (varchar 100)
782     :initarg :email)
783    (ecompanyid
784     :type integer
785     :initarg :companyid)
786    (company
787     :accessor employee-company
788     :db-kind :join
789     :db-info (:join-class company
790                           :home-key ecompanyid
791                           :foreign-key companyid
792                           :set nil))
793    (managerid
794     :type integer
795     :initarg :managerid)
796    (manager
797     :accessor employee-manager
798     :db-kind :join
799     :db-info (:join-class employee
800                           :home-key managerid
801                           :foreign-key emplid
802                           :set nil))
803    (addresses
804     :accessor employee-addresses
805     :db-kind :join
806     :db-info (:join-class employee-address
807                           :home-key emplid
808                           :foreign-key aemplid
809                           :target-slot address
810                           :set t)))
811   (:base-table employee))
812
813 (def-view-class company ()
814   ((companyid
815     :db-kind :key
816     :db-constraints :not-null
817     :type integer
818     :initarg :companyid)
819    (groupid
820     :db-kind :key
821     :db-constraints :not-null
822     :type integer
823     :initarg :groupid)
824    (name
825     :type (varchar 100)
826     :initarg :name)
827    (presidentid
828     :type integer
829     :initarg :presidentid)
830    (president
831     :reader president
832     :db-kind :join
833     :db-info (:join-class employee
834                           :home-key presidentid
835                           :foreign-key emplid
836                           :set nil))
837    (employees
838     :reader company-employees
839     :db-kind :join
840     :db-info (:join-class employee
841                           :home-key (companyid groupid)
842                           :foreign-key (ecompanyid groupid)
843                           :set t))))
844
845 (def-view-class address ()
846   ((addressid
847     :db-kind :key
848     :db-constraints :not-null
849     :type integer
850     :initarg :addressid)
851    (street-number
852     :type integer
853     :initarg :street-number)
854    (street-name
855     :type (varchar 30)
856     :void-value ""
857     :initarg :street-name)
858    (city
859     :column "city_field"
860     :void-value "no city"
861     :type (varchar 30)
862     :initarg :city)
863    (postal-code
864     :column zip
865     :type integer
866     :void-value 0
867     :initarg :postal-code))
868   (:base-table addr))
869
870 ;; many employees can reside at many addressess
871 (def-view-class employee-address ()
872   ((aemplid :type integer :initarg :emplid)
873    (aaddressid :type integer :initarg :addressid)
874    (verified :type boolean :initarg :verified)
875    (address :db-kind :join
876             :db-info (:join-class address
877                                   :home-key aaddressid
878                                   :foreign-key addressid
879                                   :retrieval :immediate)))
880   (:base-table "ea_join"))
881
882 (def-view-class deferred-employee-address ()
883   ((aemplid :type integer :initarg :emplid)
884    (aaddressid :type integer :initarg :addressid)
885    (verified :type boolean :initarg :verified)
886    (address :db-kind :join
887             :db-info (:join-class address
888                                   :home-key aaddressid
889                                   :foreign-key addressid
890                                   :retrieval :deferred
891                                   :set nil)))
892   (:base-table "ea_join"))
893       </screen>
894     </refsect1>
895     <refsect1>
896       <title>Side Effects</title>
897       <para>Creates a new CLOS class.</para>
898     </refsect1>
899     <refsect1>
900       <title>Affected by</title>
901       <para>
902         Nothing.
903       </para>
904     </refsect1>
905     <refsect1>
906       <title>Exceptional Situations</title>
907       <para>
908         None.
909       </para>
910     </refsect1>
911     <refsect1>
912       <title>See Also</title>
913       <para>
914         <simplelist>
915           <member><link linkend="create-view-from-class"><function>create-view-from-class</function></link></member>
916           <member><link linkend="standard-db-object"><parameter>standard-db-object</parameter></link></member>
917           <member><link linkend="drop-view-from-class"><function>drop-view-from-class</function></link></member>
918         </simplelist>
919       </para>
920     </refsect1>
921     <refsect1>
922       <title>Notes</title>
923       <para>
924         The actual SQL type for a column depends up the database type
925         in which the SQL table is stored. As an example, the view
926         class type <parameter>(varchar 100)</parameter> specifies a
927         SQL column type <parameter>VARCHAR(100)</parameter> in &mysql;
928         and a column type <parameter>VARCHAR2(100)</parameter> in
929         &oracle;
930       </para>
931       <para>
932         The actual lisp type for a slot may be different than the
933         value specified by the <parameter>:type</parameter> attribute.
934         For example, a slot declared with "<parameter>:type (string
935         30)</parameter>" actually sets the slots Lisp type as
936         <parameter>(or null string)</parameter>. This is to allow a
937         &nil; value or a string shorter than 30 characters to be
938         stored in the slot.
939       </para>
940     </refsect1>
941   </refentry>
942
943   <refentry id="drop-view-from-class">
944     <refnamediv>
945       <refname>DROP-VIEW-FROM-CLASS</refname>
946       <refpurpose>Delete table from SQL database.</refpurpose>
947       <refclass>Function</refclass>
948     </refnamediv>
949     <refsect1>
950       <title>Syntax</title>
951       <synopsis>
952       <function>drop-view-from-class</function> <replaceable>view-class-name</replaceable> &amp;key <replaceable>database</replaceable> => <returnvalue><!-- result --></returnvalue></synopsis>
953     </refsect1>
954     <refsect1>
955       <title>Arguments and Values</title>
956       <variablelist>
957         <varlistentry>
958           <term><parameter>view-class-name</parameter></term>
959           <listitem>
960             <para>
961               The name of the <glossterm linkend="gloss-view-class">View
962               Class</glossterm>.
963             </para>
964           </listitem>
965         </varlistentry>
966         <varlistentry>
967           <term><parameter>database</parameter></term>
968           <listitem>
969             <para>
970               <glossterm linkend="gloss-database-object">database
971               object</glossterm>. This will default to the value of
972               <symbol>*default-database*</symbol>.
973             </para>
974           </listitem>
975         </varlistentry>
976       </variablelist>
977     </refsect1>
978     <refsect1>
979       <title>Description</title>
980       <para>Removes a table defined by the <glossterm
981       linkend="gloss-view-class">View Class</glossterm>
982       <parameter>view-class-name</parameter> from
983       <parameter>database</parameter> which defaults to
984       <parameter>*default-database*</parameter>.
985       </para>
986     </refsect1>
987     <refsect1>
988       <title>Examples</title>
989       <screen>
990 (list-tables)
991 => ("FOO" "BAR")
992 (drop-view-from-class 'foo)
993 =>
994 (list-tables)
995 => ("BAR")
996       </screen>
997     </refsect1>
998     <refsect1>
999       <title>Side Effects</title>
1000       <para>
1001         Deletes a table from the SQL database.
1002       </para>
1003     </refsect1>
1004     <refsect1>
1005       <title>Affected by</title>
1006       <para>
1007         Whether the specified table exists in the SQL database.
1008       </para>
1009     </refsect1>
1010     <refsect1>
1011       <title>Exceptional Situations</title>
1012       <para>
1013         A condition may be signalled if the table does not exist in
1014         the SQL database or if the SQL connection does not have
1015         sufficient permissions to delete tables.
1016       </para>
1017     </refsect1>
1018     <refsect1>
1019       <title>See Also</title>
1020       <para>
1021         <simplelist>
1022           <member><link linkend="create-view-from-class"><function>create-view-from-class</function></link></member>
1023           <member><link linkend="def-view-class"><function>def-view-class</function></link></member>
1024         </simplelist>
1025       </para>
1026     </refsect1>
1027     <refsect1>
1028       <title>Notes</title>
1029       <para>
1030         None.
1031       </para>
1032     </refsect1>
1033   </refentry>
1034
1035   <refentry id="list-classes">
1036     <refnamediv>
1037       <refname>LIST-CLASSES</refname>
1038       <refpurpose>List classes for tables in SQL database.</refpurpose>
1039       <refclass>Function</refclass>
1040     </refnamediv>
1041     <refsect1>
1042       <title>Syntax</title>
1043       <synopsis>
1044       <function>list-classes</function> &amp;key <replaceable>test</replaceable> <replaceable>root-class</replaceable> <replaceable>database</replaceable> => <returnvalue>classes</returnvalue></synopsis>
1045     </refsect1>
1046     <refsect1>
1047       <title>Arguments and Values</title>
1048       <variablelist>
1049         <varlistentry>
1050           <term><parameter>test</parameter></term>
1051           <listitem>
1052             <para>
1053               a function used to filter the search. By default, <parameter>identity</parameter> is used which
1054               will return all classes.
1055             </para>
1056           </listitem>
1057         </varlistentry>
1058         <varlistentry>
1059           <term><parameter>root-class</parameter></term>
1060           <listitem>
1061             <para>
1062               specifies the root class to the search. By default,
1063               <parameter>standard-db-object</parameter> is used which
1064               is the root for all view classes.
1065             </para>
1066           </listitem>
1067         </varlistentry>
1068         <varlistentry>
1069           <term><parameter>database</parameter></term>
1070           <listitem>
1071             <para>
1072               The <glossterm
1073               linkend="gloss-database-object">database</glossterm> to
1074               search for view classes. This will default to the value
1075               of <symbol>*default-database*</symbol>.
1076             </para>
1077           </listitem>
1078         </varlistentry>
1079         <varlistentry>
1080           <term><parameter>classes</parameter></term>
1081           <listitem>
1082             <para>
1083               List of view classes.
1084             </para>
1085           </listitem>
1086         </varlistentry>
1087       </variablelist>
1088     </refsect1>
1089     <refsect1>
1090       <title>Description</title>
1091       <para>Returns a list of all the View Classes which have been
1092       defined in the Lisp session and are connected to
1093       <parameter>database</parameter> and which descended from the
1094       class <parameter>root-class</parameter> and which satisfy the
1095       function <parameter>test</parameter>.
1096       </para>
1097     </refsect1>
1098     <refsect1>
1099       <title>Examples</title>
1100       <screen>
1101 (list-classes)
1102 => (#&lt;clsql-sys::standard-db-class big> #&lt;clsql-sys::standard-db-class employee-address>
1103     #&lt;clsql-sys::standard-db-class address> #&lt;clsql-sys::standard-db-class company>
1104     #&lt;clsql-sys::standard-db-class employee>)
1105
1106 (list-classes :test #'(lambda (c) (> (length (symbol-name (class-name c))) 3)))
1107 => (#&lt;clsql-sys::standard-db-class employee-address> #&lt;clsql-sys::standard-db-class address>
1108     #&lt;clsql-sys::standard-db-class company> #&lt;clsql-sys::standard-db-class employee>)
1109       </screen>
1110     </refsect1>
1111     <refsect1>
1112       <title>Side Effects</title>
1113       <para>
1114         None.
1115       </para>
1116     </refsect1>
1117     <refsect1>
1118       <title>Affected by</title>
1119       <para>
1120         <simplelist>
1121           <member>Which view classes have been defined in the Lisp
1122           session.</member>
1123         </simplelist>
1124       </para>
1125     </refsect1>
1126     <refsect1>
1127       <title>Exceptional Situations</title>
1128       <para>
1129         None.
1130       </para>
1131     </refsect1>
1132     <refsect1>
1133       <title>See Also</title>
1134       <para>
1135         <simplelist>
1136           <member><link linkend="def-view-class"><function>def-view-class</function></link></member>
1137         </simplelist>
1138       </para>
1139     </refsect1>
1140     <refsect1>
1141       <title>Notes</title>
1142       <para>
1143         None.
1144       </para>
1145     </refsect1>
1146   </refentry>
1147
1148
1149 </reference>