File: csql.xml

package info (click to toggle)
cl-sql 6.7.2-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 3,552 kB
  • sloc: lisp: 24,508; xml: 17,898; makefile: 487; ansic: 201; sh: 39; cpp: 9
file content (749 lines) | stat: -rw-r--r-- 24,385 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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
<?xml version='1.0' ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "entities.inc">
%myents;
]>

<chapter id="csql">
  <title>&commonsql; Tutorial</title>
  <subtitle>Based on the &usql; Tutorial</subtitle>

  <sect1 id="csql-intro">
    <title>Introduction</title>

    <para>
      The goal of this tutorial is to guide a new developer thru the
      process of creating a set of &clsql; classes providing a
      Object-Oriented interface to persistent data stored in an &sql;
      database.  We will assume that the reader is familiar with how
      &sql; works, how relations (tables) should be structured, and
      has created at least one &sql; application previously.  We will
      also assume a minor level of experience with Common Lisp.
    </para>

    <para>
      &clsql; provides two different interfaces to &sql; databases, a
      Functional interface, and an Object-Oriented interface.  The
      Functional interface consists of a special syntax for embedded
      &sql; expressions in Lisp, and provides lisp functions for &sql;
      operations like <symbol>SELECT</symbol> and
      <symbol>UPDATE</symbol>.  The object-oriented interface provides
      a way for mapping Common Lisp Objects System (CLOS) objects into
      databases and includes functions for inserting new objects,
      querying objects, and removing objects.  Most applications will
      use a combination of the two.
    </para>

    <para>
      &clsql; is based on the CommonSQL package from LispWorks Ltd, so the
      documentation that LispWorks makes available online is useful for
      &clsql; as well.  It is suggested that developers new to &clsql; read
      their documentation as well, as any differences between CommonSQL
      and &clsql; are minor. LispWorks makes the following documents
      available:
    </para>

    <itemizedlist>
      <listitem>
	<para>
	  <ulink url="http://www.lispworks.com/documentation/lw44/LWUG/html/lwuser-204.htm">
	    <citetitle>&lw; User Guide - The &commonsql;
	    Package
	    </citetitle>
	  </ulink>
	</para>
      </listitem>

      <listitem>
	<para>
	  <ulink url="http://www.lispworks.com/documentation/lw44/LWRM/html/lwref-424.htm">
	    <citetitle>&lw; Reference Manual - The SQL
	    Package</citetitle>
	  </ulink>
	</para>
      </listitem>

      <listitem>
	<para>
	<ulink url="http://www.lispworks.com/documentation/sql-tutorial/index.html">
	  <citetitle>&commonsql; Tutorial by Nick Levine</citetitle>
	</ulink>
	</para>
      </listitem>
    </itemizedlist>
  </sect1>

  <sect1>
    <title>Data Modeling with &clsql;</title>

    <para>
      Before we can create, query and manipulate &clsql; objects, we
      need to define our data model as noted by Philip Greenspun
      <footnote>
	<para>
	<ulink
	 url="http://philip.greenspun.com/sql/data-modeling.html">
	  <citetitle>Philip Greenspun's "SQL For Web Nerds" - Data
	  Modeling</citetitle>
	</ulink>
	</para>
      </footnote>
    </para>

    <para>
      When data modeling, you are telling the relational database
      management system (RDBMS) the following:
    </para>

    <itemizedlist>
      <listitem>
	<para>What elements of the data you will store.</para>
      </listitem> 
      <listitem>
	<para>How large each element can be.</para>
      </listitem>
      <listitem>
	<para>What kind of information each element can contain.</para>
      </listitem>
      <listitem>
	<para>What elements may be left blank.</para> 
      </listitem>
      <listitem>
	<para>Which elements are constrained to a fixed range.</para>
      </listitem>
      <listitem>
	<para>Whether and how various tables are to be linked.</para>
      </listitem>
    </itemizedlist>

    <para>
      With &sql; database one would do this by defining a set of
      relations, or tables, followed by a set of queries for joining
      the tables together in order to construct complex records.
      However, with &clsql; we do this by defining a set of CLOS
      classes, specifying how they will be turned into tables, and how
      they can be joined to one another via relations between their
      attributes.  The &sql; tables, as well as the queries for
      joining them together are created for us automatically, saving
      us from dealing with some of the tedium of &sql;.
    </para>

    <para>
      Let us start with a simple example of two &sql; tables, and the
      relations between them.
    </para>

<programlisting>
CREATE TABLE EMPLOYEE ( emplid     NOT NULL number(38),
                        first_name NOT NULL varchar2(30),
                        last_name  NOT NULL varchar2(30),
                        email               varchar2(100),
                        companyid  NOT NULL number(38),
                        managerid           number(38))

CREATE TABLE COMPANY ( companyid   NOT NULL number(38),
                       name        NOT NULL varchar2(100),
                       presidentid NOT NULL number(38))
</programlisting>

<para>
This is of course the canonical &sql; tutorial example, "The Org Chart".
</para>

<para>
In &clsql;, we would have two "view classes" (a fancy word for a class
mapped into a database).  They would be defined as follows:
</para>

<programlisting>
(clsql:def-view-class employee ()
  ((emplid
    :db-kind :key
    :db-constraints :not-null
    :type integer
    :initarg :emplid)
   (first-name
    :accessor first-name
    :type (string 30)
    :initarg :first-name)
   (last-name
    :accessor last-name
    :type (string 30)
    :initarg :last-name)
   (email
    :accessor employee-email
    :type (string 100)
    :nulls-ok t
    :initarg :email)
   (companyid
    :type integer
    :initarg :companyid)
   (managerid
    :type integer
    :nulls-ok t
    :initarg :managerid))
  (:base-table employee))

(clsql:def-view-class company ()
  ((companyid
    :db-kind :key
    :db-constraints :not-null
    :type integer
    :initarg :companyid)
   (name
    :type (string 100)
    :initarg :name)
   (presidentid
    :type integer
    :initarg :presidentid))
  (:base-table company))
</programlisting>

<para>
  The <function>DEF-VIEW-CLASS</function> macro is just like the
  normal CLOS <function>DEFCLASS</function> macro, except that it
  handles several slot options that <function>DEFCLASS</function>
  doesn't.  These slot options have to do with the mapping of the slot
  into the database.  We only use a few of the slot options in the
  above example, but there are several others.
</para>

<itemizedlist>

  <listitem><para>
  <symbol>:column</symbol> - The name of the &sql; column this slot is stored in.
    Defaults to the slot name.  If the slot name is not a valid &sql;
    identifier, it is escaped, so foo-bar becomes foo_bar.
  </para></listitem>

  <listitem>
    <para> 
      <symbol>:db-kind</symbol> - The kind of database mapping which
      is performed for this slot.  <symbol>:base</symbol> indicates
      the slot maps to an ordinary column of the database view.
      <symbol>:key</symbol> indicates that this slot corresponds to
      part of the unique keys for this view, <symbol>:join</symbol>
      indicates a join slot representing a relation to another view
      and :virtual indicates that this slot is an ordinary CLOS slot.
      Defaults to <symbol>:base</symbol>. </para></listitem>

  <listitem>
    <para>
      <symbol>:db-reader</symbol> - If a string, then when reading
      values from the database, the string will be used for a format
      string, with the only value being the value from the database.
      The resulting string will be used as the slot value.  If a
      function then it will take one argument, the value from the
      database, and return the value that should be put into the slot.
      </para></listitem>

  <listitem>
    <para>
      <symbol>:db-writer</symbol> - If a string, then when reading
      values from the slot for the database, the string will be used
      for a format string, with the only value being the value of the
      slot.  The resulting string will be used as the column value in
      the database.  If a function then it will take one argument, the
      value of the slot, and return the value that should be put into
      the database.</para></listitem>

  <listitem>
    <para>
      <symbol>:db-type</symbol> - A string which will be used as the
      type specifier for this slots column definition in the database.
      </para></listitem>

  <listitem>
    <para>
      <symbol>:void-value</symbol> - The Lisp value to return if the
      field is &null;. The default is &nil;.</para></listitem>

  <listitem>
    <para>
      <symbol>:db-info</symbol> - A join specification.
      </para></listitem>
</itemizedlist>

<para>
  In our example each table as a primary key attribute, which is
  required to be unique.  We indicate that a slot is part of the
  primary key (&clsql; supports multi-field primary keys) by specifying
  the <symbol>:db-kind</symbol> key slot option.
</para>

<para>
  The &sql; type of a slot when it is mapped into the database is
  determined by the <symbol>:type</symbol> slot option.  The argument
  for the <symbol>:type</symbol> option is a Common Lisp datatype.
  The &clsql; framework will determine the appropriate mapping
  depending on the database system the table is being created in.  If
  we really wanted to determine what &sql; type was used for a slot,
  we could specify a <symbol>:db-type</symbol> option like
  "NUMBER(38)" and we would be guaranteed that the slot would be
  stored in the database as a NUMBER(38).  This is not recomended
  because it could makes your view class unportable across database
  systems.
</para>

<para>
  <function>DEF-VIEW-CLASS</function> also supports some class
  options, like <symbol>:base-table</symbol>.  The
  <symbol>:base-table</symbol> option specifies what the table name
  for the view class will be when it is mapped into the database.
</para>

<para>
  Another class option is <symbol>:normalizedp</symbol>, which signals
  &clsql; to use a normalized schema for the mapping from slots to
  &sql; columns. By default &clsql; includes all the slots of a parent
  class that map to &sql; columns into the child class. This option
  tells &clsql; to normalize the schema, so that a join is done on the
  primary keys of the concerned tables to get a complete column set
  for the classes. For more information, see <link linkend="def-view-class">
  <function>def-view-class</function></link>.
</para>
  </sect1>

<sect1 id="csql-rel">
<title>Class Relations</title> 

<para>
In an &sql; only application, the <symbol>EMPLOYEE</symbol> and
<symbol>COMPANY</symbol> tables can be queried to determine things
like, "Who is Vladimir's manager?", "What company does Josef work
for?", and "What employees work for Widgets Inc.".  This is done by
joining tables with an &sql; query.
</para>

<para>
Who works for Widgets Inc.?
</para>

<programlisting>
SELECT first_name, last_name FROM employee, company
       WHERE employee.companyid = company.companyid
	     AND company.company_name = "Widgets Inc."
</programlisting>

<para>
Who is Vladimir's manager?
</para>

<programlisting>
SELECT managerid FROM employee
       WHERE employee.first_name = "Vladimir"
	     AND employee.last_name = "Lenin"
</programlisting>

<para>
What company does Josef work for?
</para>

<programlisting>
SELECT company_name FROM company, employee
       WHERE employee.first_name = "Josef"
	     AND employee.last-name = "Stalin"
	     AND employee.companyid = company.companyid
</programlisting>

<para>
With &clsql; however we do not need to write out such queries because
our view classes can maintain the relations between employees and
companies, and employees to their managers for us.  We can then access
these relations like we would any other attribute of an employee or
company object.  In order to do this we define some join slots for our
view classes.
</para>

<para>
What company does an employee work for?  If we add the following slot
definition to the employee class we can then ask for it's
<symbol>COMPANY</symbol> slot and get the appropriate result.
</para>

<programlisting>
    ;; In the employee slot list
    (company
      :accessor employee-company
      :db-kind :join
      :db-info (:join-class company
	        :home-key companyid
		:foreign-key companyid
		:set nil))
</programlisting>

<para>
Who are the employees of a given company?  And who is the president of
it? We add the following slot definition to the company view class and
we can then ask for it's <symbol>EMPLOYEES</symbol> slot and get the
right result.
</para>

<programlisting>
      ;; In the company slot list
      (employees
	:reader company-employees
	:db-kind :join
	:db-info (:join-class employee
		  :home-key companyid
		  :foreign-key companyid
		  :set t))

       (president
        :reader president
	:db-kind :join
	:db-info (:join-class employee
		  :home-key presidentid
		  :foreign-key emplid
		  :set nil))
</programlisting>

<para>
And lastly, to define the relation between an employee and their
manager:
</para>

<programlisting>
	;; In the employee slot list
       (manager
        :accessor employee-manager
	:db-kind :join
	:db-info (:join-class employee
	          :home-key managerid
		  :foreign-key emplid
		  :set nil))
</programlisting>

<para>
&clsql; join slots can represent one-to-one, one-to-many, and
many-to-many relations.  Above we only have one-to-one and one-to-many
relations, later we will explain how to model many-to-many relations.
First, let's go over the slot definitions and the available options.
</para>

<para>
In order for a slot to be a join, we must specify that it's
<symbol>:db-kind</symbol> <symbol>:join</symbol>, as opposed to
<symbol>:base</symbol> or <symbol>:key</symbol>.  Once we do that, we
still need to tell &clsql; how to create the join statements for the
relation.  This is what the <symbol>:db-info</symbol> option does.  It
is a list of keywords and values.  The available keywords are:
</para>

<itemizedlist>
  <listitem>
    <para>
      <symbol>:join-class</symbol> - The view class to which we want
      to join.  It can be another view class, or the same view class
      as our object.</para></listitem>

  <listitem>
    <para>
      <symbol>:home-key</symbol> - The slot(s) in the immediate object
      whose value will be compared to the foreign-key slot(s) in the
      join-class in order to join the two tables.  It can be a single
      slot-name, or it can be a list of slot names.</para></listitem>
      
  <listitem>
    <para>
      <symbol>:foreign-key</symbol> - The slot(s) in the join-class
      which will be compared to the value(s) of the home-key.
      </para></listitem>

  <listitem>
    <para>
      <symbol>:set</symbol> - A boolean which if false, indicates that
      this is a one-to-one relation, only one object will be returned.
      If true, than this is a one-to-many relation, a list of objects
      will be returned when we ask for this slots value.
      </para></listitem>
</itemizedlist>

<para>
There are other :join-info options available in &clsql;, but we will
save those till we get to the many-to-many relation examples.
</para>

<simplesect>
  <title>Object Oriented Class Relations</title>

  <para>
    &clsql; provides an Object Oriented Data Definition Language, which
    provides a mapping from &sql; tables to CLOS objects. By default class
    inheritance is handled by including all the columns from parent
    classes into the child class. This means your database schema becomes
    very much denormalized. The class option <symbol>:normalizedp</symbol>
    can be used to disable the default behaviour and have &clsql;
    normalize the database schemas of inherited classes.
  </para>
  
  <para>
    See <link linkend="def-view-class"><function>def-view-class</function></link>
    for more information.
  </para>
</simplesect>
</sect1>

<sect1 id="csql-creat">
<title>Object Creation</title>

<para>
Now that we have our model laid out, we should create some object.
Let us assume that we have a database connect set up already.  We
first need to create our tables in the database:
</para>

<para>
Note: the file <filename>examples/clsql-tutorial.lisp</filename> contains
view class definitions which you can load into your list at this point
in order to play along at home.
</para>

<programlisting>
(clsql:create-view-from-class 'employee)
(clsql:create-view-from-class 'company)
</programlisting>

<para>
Then we will create our objects.  We create them just like you would
any other CLOS object:
</para>

<programlisting>
(defvar company1 (make-instance 'company
			      :companyid 1
			      :presidentid 1
			      :name "Widgets Inc."))
			      
(defvar employee1 (make-instance 'employee
			       :emplid 1
			       :first-name "Vladimir"
			       :last-name "Lenin"
			       :email "lenin@soviet.org"
			       :companyid 1))

(defvar employee2 (make-instance 'employee
			       :emplid 2
			       :first-name "Josef"
			       :last-name "Stalin"
			       :email "stalin@soviet.org"
			       :companyid 1
			       :managerid 1))
</programlisting>

<para>
In order to insert an objects into the database we use the
<function>UPDATE-RECORDS-FROM-INSTANCE</function> function as follows:
</para>

<programlisting>
(clsql:update-records-from-instance employee1)
(clsql:update-records-from-instance employee2)
(clsql:update-records-from-instance company1)
</programlisting>

<para>
  After you make any changes to an object, you have to specifically
  tell &clsql; to update the &sql; database.  The
  <function>UPDATE-RECORDS-FROM-INSTANCE</function> method will write
  all of the changes you have made to the object into the database.
</para>

<para>
  Since &clsql; objects are just normal CLOS objects, we can manipulate
  their slots just like any other object.  For instance, let's say
  that Lenin changes his email because he was getting too much spam
  from the German Socialists.
</para>

<programlisting>
;; Print Lenin's current email address, change it and save it to the
;; database.  Get a new object representing Lenin from the database
;; and print the email

;; This lets us use the functional &clsql; interface with [] syntax
(clsql:locally-enable-sql-reader-syntax)

(format t "The email address of ~A ~A is ~A"
	(first-name employee1)
	(last-name employee1)
	(employee-email employee1))

(setf (employee-email employee1) "lenin-nospam@soviets.org")

;; Update the database
(clsql:update-records-from-instance employee1)

(let ((new-lenin (car (clsql:select 'employee
	                :where [= [slot-value 'employee 'emplid] 1]))))
      (format t "His new email is ~A"
	  (employee-email new-lenin)))
</programlisting>

<para>
  Everything except for the last <function>LET</function> expression
  is already familiar to us by now.  To understand the call to
  <function>CLSQL:SELECT</function> we need to discuss the
  Functional &sql; interface and it's integration with the Object
  Oriented interface of &clsql;.
</para>

</sect1>

<sect1 id="csql-find">
<title>Finding Objects</title>

<para>
  Now that we have our objects in the database, how do we get them out
  when we need to work with them?  &clsql; provides a functional
  interface to &sql;, which consists of a special Lisp reader macro
  and some functions.  The special syntax allows us to embed &sql; in
  lisp expressions, and lisp expressions in &sql;, with ease.
</para>

<para>
  Once we have turned on the syntax with the expression:
</para>

<programlisting>
(clsql:locally-enable-sql-reader-syntax)
</programlisting>

<para>
  We can start entering fragments of &sql; into our lisp reader.  We
  will get back objects which represent the lisp expressions.  These
  objects will later be compiled into &sql; expressions that are
  optimized for the database backed we are connected to.  This means
  that we have a database independent &sql; syntax.  Here are some
  examples:
</para>

<programlisting>
;; an attribute or table name
[foo] => #&lt;CLSQL-SYS::SQL-IDENT-ATTRIBUTE FOO>

;; a attribute identifier with table qualifier
[foo bar] => #&lt;CLSQL-SYS::SQL-IDENT-ATTRIBUTE FOO.BAR>

;; a attribute identifier with table qualifier
[= "Lenin" [first_name]] =>
   #&lt;CLSQL-SYS::SQL-RELATIONAL-EXP ('Lenin' = FIRST_NAME)>

[&lt; [emplid] 3] =>
   #&lt;CLSQL-SYS::SQL-RELATIONAL-EXP (EMPLID &lt; 3)>

[and [&lt; [emplid] 2] [= [first_name] "Lenin"]] =>
   #&lt;CLSQL-SYS::SQL-RELATIONAL-EXP ((EMPLID &lt; 2) AND
                                     (FIRST_NAME = 'Lenin'))>


;; If we want to reference a slot in an object we can us the
;;  SLOT-VALUE sql extension
[= [slot-value 'employee 'emplid] 1] =>
   #&lt;CLSQL-SYS::SQL-RELATIONAL-EXP (EMPLOYEE.EMPLID = 1)>

[= [slot-value 'employee 'emplid]
   [slot-value 'company 'presidentid]] =>
   #&lt;CLSQL-SYS::SQL-RELATIONAL-EXP (EMPLOYEE.EMPLID = COMPANY.PRESIDENTID)>
</programlisting>

<para>
  The <function>SLOT-VALUE</function> operator is important because it
  let's us query objects in a way that is robust to any changes in the
  object->table mapping, like column name changes, or table name
  changes.  So when you are querying objects, be sure to use the
  <function>SLOT-VALUE</function> &sql; extension.
</para>

<para>
  Since we can now formulate &sql; relational expression which can be
  used as qualifiers, like we put after the <symbol>WHERE</symbol>
  keyword in &sql; statements, we can start querying our objects.
  &clsql; provides a function <symbol>SELECT</symbol> which can return
  use complete objects from the database which conform to a qualifier,
  can be sorted, and various other &sql; operations.
</para>

<para>
  The first argument to <symbol>SELECT</symbol> is a class name.  it
  also has a set of keyword arguments which are covered in the
  documentation.  For now we will concern ourselves only with the
  :where keyword.  Select returns a list of objects, or nil if it
  can't find any.  It's important to remember that it always returns a
  list, so even if you are expecting only one result, you should
  remember to extract it from the list you get from
  <symbol>SELECT</symbol>.
</para>

<programlisting>
;; all employees
(clsql:select 'employee)
;; all companies
(clsql:select 'company)

;; employees named Lenin
(clsql:select 'employee :where [= [slot-value 'employee 'last-name]
				"Lenin"])

(clsql:select 'company :where [= [slot-value 'company 'name]
			       "Widgets Inc."])

;; Employees of Widget's Inc.
(clsql:select 'employee
	    :where [and [= [slot-value 'employee 'companyid]
			   [slot-value 'company 'companyid]]
			[= [slot-value 'company 'name]
			   "Widgets Inc."]])

;; Same thing, except that we are using the employee
;; relation in the company view class to do the join for us,
;; saving us the work of writing out the &sql;!
(company-employees company1)

;; President of Widgets Inc.
(president company1)

;; Manager of Josef Stalin
(employee-manager employee2)
</programlisting>

</sect1>

<sect1 id="csql-del">
<title>Deleting Objects</title>

<para>
  Now that we know how to create objects in our database, manipulate
  them and query them (including using our predefined relations to
  save us the trouble writing alot of &sql;) we should learn how to
  clean up after ourself.  It's quite simple really. The function
  <function>DELETE-INSTANCE-RECORDS</function> will remove an object
  from the database.  However, when we remove an object we are
  responsible for making sure that the database is left in a correct
  state.
</para>

<para>
  For example, if we remove a company record, we need to either remove
  all of it's employees or we need to move them to another company.
  Likewise if we remove an employee, we should make sure to update any
  other employees who had them as a manager.
</para>

</sect1>

<sect1 id="csql-concl">
<title>Conclusion</title>

<para>
  There are many nooks and crannies to &clsql;, some of which are
  covered in the Xanalys documents we refered to earlier, some are
  not.  The best documentation at this time is still the source code
  for &clsql; itself and the inline documentation for its various
  functions.
</para>

</sect1>

</chapter>