diff options
Diffstat (limited to 'slib_6.html')
-rw-r--r-- | slib_6.html | 3658 |
1 files changed, 0 insertions, 3658 deletions
diff --git a/slib_6.html b/slib_6.html deleted file mode 100644 index 804d4e9..0000000 --- a/slib_6.html +++ /dev/null @@ -1,3658 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html40/loose.dtd"> -<HTML> -<!-- Created on January, 10 2005 by texi2html 1.66 --> -<!-- -Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author) - Karl Berry <karl@freefriends.org> - Olaf Bachmann <obachman@mathematik.uni-kl.de> - and many others. -Maintained by: Many creative people <dev@texi2html.cvshome.org> -Send bugs and suggestions to <users@texi2html.cvshome.org> - ---> -<HEAD> -<TITLE>SLIB: Database Packages</TITLE> - -<META NAME="description" CONTENT="SLIB: Database Packages"> -<META NAME="keywords" CONTENT="SLIB: Database Packages"> -<META NAME="resource-type" CONTENT="document"> -<META NAME="distribution" CONTENT="global"> -<META NAME="Generator" CONTENT="texi2html 1.66"> - -</HEAD> - -<BODY LANG="en" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"> - -<A NAME="SEC140"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC139"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H1> 6. Database Packages </H1> -<!--docid::SEC140::--> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC141">6.1 Relational Database</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'relational-database</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC165">6.2 Relational Infrastructure</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC178">6.3 Weight-Balanced Trees</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'wt-tree</TD></TR> -</TABLE> -<P> - -<A NAME="Relational Database"></A> -<HR SIZE="6"> -<A NAME="SEC141"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC142"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 6.1 Relational Database </H2> -<!--docid::SEC141::--> -<P> - -<CODE>(require 'relational-database)</CODE> -<A NAME="IDX917"></A> -</P> -<P> - -This package implements a database system inspired by the Relational -Model (<CITE>E. F. Codd, A Relational Model of Data for Large Shared -Data Banks</CITE>). An SLIB relational database implementation can be created -from any <A HREF="slib_6.html#SEC166">6.2.1 Base Table</A> implementation. -</P> -<P> - -Why relational database? For motivations and design issues see<BR> -<A HREF="http://swissnet.ai.mit.edu/~jaffer/DBManifesto.html">http://swissnet.ai.mit.edu/~jaffer/DBManifesto.html</A>. -</P> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC142">6.1.1 Using Databases</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'databases</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC147">6.1.2 Table Operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC154">6.1.3 Database Interpolation</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'database-interpolate</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC155">6.1.4 Embedded Commands</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'database-commands</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC162">6.1.5 Database Macros</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'within-database</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC164">6.1.6 Database Browser</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'database-browse</TD></TR> -</TABLE> -<P> - -<A NAME="Using Databases"></A> -<HR SIZE="6"> -<A NAME="SEC142"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.1.1 Using Databases </H3> -<!--docid::SEC142::--> -<P> - -<CODE>(require 'databases)</CODE> -<A NAME="IDX918"></A> -</P> -<P> - -This enhancement wraps a utility layer on <CODE>relational-database</CODE> -which provides: -</P> -<P> - -<UL> -<LI> -Identification of open databases by filename. -<LI> -Automatic sharing of open (immutable) databases. -<LI> -Automatic loading of base-table package when creating a database. -<LI> -Detection and automatic loading of the appropriate base-table package -when opening a database. -<LI> -Table and data definition from Scheme lists. -</UL> -<P> - -<A NAME="SEC143"></A> -<H4> Database Sharing </H4> -<!--docid::SEC143::--> -<P> - -<EM>Auto-sharing</EM> refers to a call to the procedure -<A NAME="IDX919"></A> -<CODE>open-database</CODE> returning an already open database (procedure), -rather than opening the database file a second time. -</P> -<P> - -<BLOCKQUOTE> -<EM>Note:</EM> Databases returned by <CODE>open-database</CODE> do not include -wrappers applied by packages like <A HREF="slib_6.html#SEC155">6.1.4 Embedded Commands</A>. But -wrapped databases do work as arguments to these functions. -</BLOCKQUOTE> -<P> - -When a database is created, it is mutable by the creator and not -auto-sharable. A database opened mutably is also not auto-sharable. -But any number of readers can (open) share a non-mutable database file. -</P> -<P> - -This next set of procedures mirror the whole-database methods in -<A HREF="slib_6.html#SEC177">6.2.4 Database Operations</A>. Except for <CODE>create-database</CODE>, each -procedure will accept either a filename or database procedure for its -first argument. -</P> -<P> - -<A NAME="IDX920"></A> -</P> -<DL> -<DT><U>Function:</U> <B>create-database</B> <I>filename base-table-type</I> -<DD><P> - -<VAR>filename</VAR> should be a string naming a file; or <CODE>#f</CODE>. <VAR>base-table-type</VAR> must be a -symbol naming a feature which can be passed to <CODE>require</CODE>. <CODE>create-database</CODE> -returns a new, open relational database (with base-table type <VAR>base-table-type</VAR>) -associated with <VAR>filename</VAR>, or a new ephemeral database if <VAR>filename</VAR> is <CODE>#f</CODE>. -</P> -<P> - -<CODE>create-database</CODE> is the only run-time use of require in SLIB -which crosses module boundaries. When <VAR>base-table-type</VAR> is <CODE>require</CODE>d by <CODE>create-database</CODE>; it -adds an association of <VAR>base-table-type</VAR> with its <EM>relational-system</EM> procedure -<A NAME="IDX921"></A> -to <VAR>mdbm:*databases*</VAR>. -</P> -<P> - -alist-table is the default base-table type: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(require 'databases) -(define my-rdb (create-database "my.db" 'alist-table)) -</pre></td></tr></table></DL> -Only <CODE>alist-table</CODE> and base-table modules which have been -<CODE>require</CODE>d will dispatch correctly from the -<CODE>open-database</CODE> procedures. Therefore, either pass two -arguments to <CODE>open-database</CODE>, or require the base-table of your -database file uses before calling <CODE>open-database</CODE> with one -argument. -<P> - -<A NAME="IDX922"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>open-database!</B> <I>rdb base-table-type</I> -<DD><P> - -Returns <EM>mutable</EM> open relational database or #f. -</P> -</DL> -<P> - -<A NAME="IDX923"></A> -</P> -<DL> -<DT><U>Function:</U> <B>open-database</B> <I>rdb base-table-type</I> -<DD><P> - -Returns an open relational database associated with <VAR>rdb</VAR>. The -database will be opened with base-table type <VAR>base-table-type</VAR>). -</P> -<P> - -<A NAME="IDX924"></A> -<DT><U>Function:</U> <B>open-database</B> <I>rdb</I> -<DD>Returns an open relational database associated with <VAR>rdb</VAR>. -<CODE>open-database</CODE> will attempt to deduce the correct base-table-type. -</P> -</DL> -<P> - -<A NAME="IDX925"></A> -</P> -<DL> -<DT><U>Function:</U> <B>write-database</B> <I>rdb filename</I> -<DD><P> - -Writes the mutable relational-database <VAR>rdb</VAR> to <VAR>filename</VAR>. -</P> -</DL> -<P> - -<A NAME="IDX926"></A> -</P> -<DL> -<DT><U>Function:</U> <B>sync-database</B> <I>rdb</I> -<DD><P> - -Writes the mutable relational-database <VAR>rdb</VAR> to the filename it was -opened with. -</P> -</DL> -<P> - -<A NAME="IDX927"></A> -</P> -<DL> -<DT><U>Function:</U> <B>solidify-database</B> <I>rdb</I> -<DD><P> - -Syncs <VAR>rdb</VAR> and makes it immutable. -</P> -</DL> -<P> - -<A NAME="IDX928"></A> -</P> -<DL> -<DT><U>Function:</U> <B>close-database</B> <I>rdb</I> -<DD><P> - -<VAR>rdb</VAR> will only be closed when the count of <CODE>open-database</CODE> - <CODE>close-database</CODE> -calls for <VAR>rdb</VAR> (and its filename) is 0. <CODE>close-database</CODE> returns #t if successful; -and #f otherwise. -</P> -</DL> -<P> - -<A NAME="IDX929"></A> -</P> -<DL> -<DT><U>Function:</U> <B>mdbm:report</B> -<DD><P> - -Prints a table of open database files. The columns are the -base-table type, number of opens, `<SAMP>!</SAMP>' for mutable, the -filename, and the lock certificate (if locked). -</P> -</DL> -<TABLE><tr><td> </td><td class=example><pre>(mdbm:report) --| - alist-table 003 /usr/local/lib/slib/clrnamdb.scm - alist-table 001 ! sdram.db jaffer@aubrey.jaffer.3166:1038628199 -</pre></td></tr></table><P> - -<A NAME="SEC144"></A> -<H4> Opening Tables </H4> -<!--docid::SEC144::--> -<P> - -<A NAME="IDX930"></A> -</P> -<DL> -<DT><U>Function:</U> <B>open-table</B> <I>rdb table-name</I> -<DD><P> - -<VAR>rdb</VAR> must be a relational database and <VAR>table-name</VAR> a symbol. -</P> -<P> - -<CODE>open-table</CODE> returns a "methods" procedure for an existing relational table in -<VAR>rdb</VAR> if it exists and can be opened for reading, otherwise returns -<CODE>#f</CODE>. -</P> -</DL> -<P> - -<A NAME="IDX931"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>open-table!</B> <I>rdb table-name</I> -<DD><P> - -<VAR>rdb</VAR> must be a relational database and <VAR>table-name</VAR> a symbol. -</P> -<P> - -<CODE>open-table!</CODE> returns a "methods" procedure for an existing relational table in -<VAR>rdb</VAR> if it exists and can be opened in mutable mode, otherwise returns -<CODE>#f</CODE>. -</P> -</DL> -<A NAME="SEC145"></A> -<H4> Defining Tables </H4> -<!--docid::SEC145::--> -<P> - -<A NAME="IDX932"></A> -</P> -<DL> -<DT><U>Function:</U> <B>define-domains</B> <I>rdb row5 <small>...</small></I> -<DD><P> - -Adds the domain rows <VAR>row5</VAR> <small>...</small> to the `<SAMP>*domains-data*</SAMP>' table -in <VAR>rdb</VAR>. The format of the row is given in <A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A>. -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define-domains rdb '(permittivity #f complex? c64 #f)) -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX933"></A> -</P> -<DL> -<DT><U>Function:</U> <B>add-domain</B> <I>rdb row5</I> -<DD><P> - -Use <CODE>define-domains</CODE> instead. -</P> -</DL> -<P> - -<A NAME="IDX934"></A> -</P> -<DL> -<DT><U>Function:</U> <B>define-tables</B> <I>rdb spec-0 <small>...</small></I> -<DD><P> - -Adds tables as specified in <VAR>spec-0</VAR> <small>...</small> to the open -relational-database <VAR>rdb</VAR>. Each <VAR>spec</VAR> has the form: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(<name> <descriptor-name> <descriptor-name> <rows>) -</pre></td></tr></table>or -<TABLE><tr><td> </td><td class=example><pre>(<name> <primary-key-fields> <other-fields> <rows>) -</pre></td></tr></table><P> - -where <name> is the table name, <descriptor-name> is the symbol -name of a descriptor table, <primary-key-fields> and -<other-fields> describe the primary keys and other fields -respectively, and <rows> is a list of data rows to be added to the -table. -</P> -<P> - -<primary-key-fields> and <other-fields> are lists of field -descriptors of the form: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(<column-name> <domain>) -</pre></td></tr></table>or -<TABLE><tr><td> </td><td class=example><pre>(<column-name> <domain> <column-integrity-rule>) -</pre></td></tr></table><P> - -where <column-name> is the column name, <domain> is the domain -of the column, and <column-integrity-rule> is an expression whose -value is a procedure of one argument (which returns <CODE>#f</CODE> to signal -an error). -</P> -<P> - -If <domain> is not a defined domain name and it matches the name of -this table or an already defined (in one of <VAR>spec-0</VAR> <small>...</small>) single -key field table, a foreign-key domain will be created for it. -</P> -</DL> -<A NAME="SEC146"></A> -<H4> Listing Tables </H4> -<!--docid::SEC146::--> -<P> - -<A NAME="IDX935"></A> -</P> -<DL> -<DT><U>Function:</U> <B>list-table-definition</B> <I>rdb table-name</I> -<DD><P> - -If symbol <VAR>table-name</VAR> exists in the open relational-database -<VAR>rdb</VAR>, then returns a list of the table-name, its primary key names -and domains, its other key names and domains, and the table's records -(as lists). Otherwise, returns #f. -</P> -<P> - -The list returned by <CODE>list-table-definition</CODE>, when passed as an -argument to <CODE>define-tables</CODE>, will recreate the table. -</P> -</DL> -<P> - -<A NAME="Table Operations"></A> -<HR SIZE="6"> -<A NAME="SEC147"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC142"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC148"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.1.2 Table Operations </H3> -<!--docid::SEC147::--> -<P> - -These are the descriptions of the methods available from an open -relational table. A method is retrieved from a table by calling -the table with the symbol name of the operation. For example: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>((plat 'get 'processor) 'djgpp) => i386 -</pre></td></tr></table><P> - -Some operations described below require primary key arguments. Primary -keys arguments are denoted <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small>. It is an -error to call an operation for a table which takes primary key arguments -with the wrong number of primary keys for that table. -</P> -<P> - -<A NAME="IDX936"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>get</B> <I>column-name</I> -<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which -returns the value for the <VAR>column-name</VAR> column of the row associated -with primary keys <VAR>key1</VAR>, <VAR>key2</VAR> <small>...</small> if that row exists in -the table, or <CODE>#f</CODE> otherwise. -<P> - -<TABLE><tr><td> </td><td class=example><pre>((plat 'get 'processor) 'djgpp) => i386 -((plat 'get 'processor) 'be-os) => #f -</pre></td></tr></table></DL> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC148">6.1.2.1 Single Row Operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC149">6.1.2.2 Match-Keys</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC150">6.1.2.3 Multi-Row Operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC151">6.1.2.4 Indexed Sequential Access Methods</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC152">6.1.2.5 Sequential Index Operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC153">6.1.2.6 Table Administration</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -</TABLE> -<P> - -<A NAME="Single Row Operations"></A> -<HR SIZE="6"> -<A NAME="SEC148"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC149"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.2.1 Single Row Operations </H4> -<!--docid::SEC148::--> -<P> - -The term <EM>row</EM> used below refers to a Scheme list of values (one for -each column) in the order specified in the descriptor (table) for this -table. Missing values appear as <CODE>#f</CODE>. Primary keys must not -be missing. -</P> -<P> - -<A NAME="IDX937"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:insert</B> -<DD>Adds the row <VAR>row</VAR> to this table. If a row for the primary key(s) -specified by <VAR>row</VAR> already exists in this table an error is -signaled. The value returned is unspecified. -</DL> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define telephone-table-desc - ((my-database 'create-table) 'telephone-table-desc)) -(define ndrp (telephone-table-desc 'row:insert)) -(ndrp '(1 #t name #f string)) -(ndrp '(2 #f telephone - (lambda (d) - (and (string? d) (> (string-length d) 2) - (every - (lambda (c) - (memv c '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 - #\+ #\( #\ #\) #\-))) - (string->list d)))) - string)) -</pre></td></tr></table><P> - -<A NAME="IDX938"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:update</B> -<DD>Returns a procedure of one argument, <VAR>row</VAR>, which adds the row, -<VAR>row</VAR>, to this table. If a row for the primary key(s) specified by -<VAR>row</VAR> already exists in this table, it will be overwritten. The -value returned is unspecified. -</DL> -<P> - -<A NAME="IDX939"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:retrieve</B> -<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which -returns the row associated with primary keys <VAR>key1</VAR>, <VAR>key2</VAR> -<small>...</small> if it exists, or <CODE>#f</CODE> otherwise. -</DL> -<P> - -<TABLE><tr><td> </td><td class=example><pre>((plat 'row:retrieve) 'linux) => (linux i386 linux gcc) -((plat 'row:retrieve) 'multics) => #f -</pre></td></tr></table><P> - -<A NAME="IDX940"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:remove</B> -<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which -removes and returns the row associated with primary keys <VAR>key1</VAR>, -<VAR>key2</VAR> <small>...</small> if it exists, or <CODE>#f</CODE> otherwise. -</DL> -<P> - -<A NAME="IDX941"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:delete</B> -<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which -deletes the row associated with primary keys <VAR>key1</VAR>, <VAR>key2</VAR> -<small>...</small> if it exists. The value returned is unspecified. -</DL> -<P> - -<A NAME="Match-Keys"></A> -<HR SIZE="6"> -<A NAME="SEC149"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC148"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC150"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.2.2 Match-Keys </H4> -<!--docid::SEC149::--> -<P> - -<A NAME="IDX942"></A> -The (optional) <VAR>match-key1</VAR> <small>...</small> arguments are used to restrict -actions of a whole-table operation to a subset of that table. Those -procedures (returned by methods) which accept match-key arguments will -accept any number of match-key arguments between zero and the number of -primary keys in the table. Any unspecified <VAR>match-key</VAR> arguments -default to <CODE>#f</CODE>. -</P> -<P> - -The <VAR>match-key1</VAR> <small>...</small> restrict the actions of the table command -to those records whose primary keys each satisfy the corresponding -<VAR>match-key</VAR> argument. The arguments and their actions are: -</P> -<P> - -<BLOCKQUOTE> -<DL COMPACT> -<DT><CODE>#f</CODE> -<DD>The false value matches any key in the corresponding position. -<DT>an object of type procedure -<DD>This procedure must take a single argument, the key in the corresponding -position. Any key for which the procedure returns a non-false value is -a match; Any key for which the procedure returns a <CODE>#f</CODE> is not. -<DT>other values -<DD>Any other value matches only those keys <CODE>equal?</CODE> to it. -</DL> -</BLOCKQUOTE> -<P> - -<A NAME="IDX943"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>get*</B> <I>column-name</I> -<DD>Returns a procedure of optional arguments <VAR>match-key1</VAR> <small>...</small> which -returns a list of the values for the specified column for all rows in -this table. The optional <VAR>match-key1</VAR> <small>...</small> arguments restrict -actions to a subset of the table. -<P> - -<TABLE><tr><td> </td><td class=example><pre>((plat 'get* 'processor)) => -(i386 i8086 i386 i8086 i386 i386 i8086 m68000 - m68000 m68000 m68000 m68000 powerpc) - -((plat 'get* 'processor) #f) => -(i386 i8086 i386 i8086 i386 i386 i8086 m68000 - m68000 m68000 m68000 m68000 powerpc) - -(define (a-key? key) - (char=? #\a (string-ref (symbol->string key) 0))) - -((plat 'get* 'processor) a-key?) => -(m68000 m68000 m68000 m68000 m68000 powerpc) - -((plat 'get* 'name) a-key?) => -(atari-st-turbo-c atari-st-gcc amiga-sas/c-5.10 - amiga-aztec amiga-dice-c aix) -</pre></td></tr></table></DL> -<P> - -<A NAME="Multi-Row Operations"></A> -<HR SIZE="6"> -<A NAME="SEC150"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC149"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC151"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.2.3 Multi-Row Operations </H4> -<!--docid::SEC150::--> -<P> - -<A NAME="IDX944"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:retrieve*</B> -<DD>Returns a procedure of optional arguments <VAR>match-key1</VAR> <small>...</small> -which returns a list of all rows in this table. The optional -<VAR>match-key1</VAR> <small>...</small> arguments restrict actions to a subset of the -table. For details see See section <A HREF="slib_6.html#SEC149">6.1.2.2 Match-Keys</A>. -</DL> -<P> - -<TABLE><tr><td> </td><td class=example><pre>((plat 'row:retrieve*) a-key?) => -((atari-st-turbo-c m68000 atari turbo-c) - (atari-st-gcc m68000 atari gcc) - (amiga-sas/c-5.10 m68000 amiga sas/c) - (amiga-aztec m68000 amiga aztec) - (amiga-dice-c m68000 amiga dice-c) - (aix powerpc aix -)) -</pre></td></tr></table><P> - -<A NAME="IDX945"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:remove*</B> -<DD>Returns a procedure of optional arguments <VAR>match-key1</VAR> <small>...</small> which -removes and returns a list of all rows in this table. The optional -<VAR>match-key1</VAR> <small>...</small> arguments restrict actions to a subset of the -table. -</DL> -<P> - -<A NAME="IDX946"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:delete*</B> -<DD>Returns a procedure of optional arguments <VAR>match-key1</VAR> <small>...</small> -which Deletes all rows from this table. The optional <VAR>match-key1</VAR> -<small>...</small> arguments restrict deletions to a subset of the table. The -value returned is unspecified. The descriptor table and catalog entry -for this table are not affected. -</DL> -<P> - -<A NAME="IDX947"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>for-each-row</B> -<DD>Returns a procedure of arguments <VAR>proc</VAR> <VAR>match-key1</VAR> <small>...</small> -which calls <VAR>proc</VAR> with each <VAR>row</VAR> in this table. The -optional <VAR>match-key1</VAR> <small>...</small> arguments restrict actions to a -subset of the table. For details see See section <A HREF="slib_6.html#SEC149">6.1.2.2 Match-Keys</A>. -</DL> -<P> - -Note that <CODE>row:insert*</CODE> and <CODE>row:update*</CODE> do <EM>not</EM> use -match-keys. -</P> -<P> - -<A NAME="IDX948"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:insert*</B> -<DD>Returns a procedure of one argument, <VAR>rows</VAR>, which adds each row in -the list of rows, <VAR>rows</VAR>, to this table. If a row for the primary -key specified by an element of <VAR>rows</VAR> already exists in this table, -an error is signaled. The value returned is unspecified. -</DL> -<P> - -<A NAME="IDX949"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>row:update*</B> -<DD>Returns a procedure of one argument, <VAR>rows</VAR>, which adds each row in -the list of rows, <VAR>rows</VAR>, to this table. If a row for the primary -key specified by an element of <VAR>rows</VAR> already exists in this table, -it will be overwritten. The value returned is unspecified. -</DL> -<P> - -<A NAME="Indexed Sequential Access Methods"></A> -<HR SIZE="6"> -<A NAME="SEC151"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC150"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC152"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.2.4 Indexed Sequential Access Methods </H4> -<!--docid::SEC151::--> -<P> - -<A NAME="IDX950"></A> -<EM>Indexed Sequential Access Methods</EM> are a way of arranging -database information so that records can be accessed both by key and -by key sequence (ordering). <EM>ISAM</EM> is not part of Codd's -relational model. Hardcore relational programmers might use some -least-upper-bound join for every row to get them into an order. -</P> -<P> - -Associative memory in B-Trees is an example of a database -implementation which can support a native key ordering. SLIB's -<CODE>alist-table</CODE> implementation uses <CODE>sort</CODE> to implement -<CODE>for-each-row-in-order</CODE>, but does not support <CODE>isam-next</CODE> -and <CODE>isam-prev</CODE>. -</P> -<P> - -The multi-primary-key ordering employed by these operations is the -lexicographic collation of those primary-key fields in their given -order. For example: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(12 a 34) < (12 a 36) < (12 b 1) < (13 a 0) -</pre></td></tr></table><P> - -<A NAME="Sequential Index Operations"></A> -<HR SIZE="6"> -<A NAME="SEC152"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC151"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC153"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.2.5 Sequential Index Operations </H4> -<!--docid::SEC152::--> -<P> - -The following procedures are individually optional depending on the -base-table implememtation. If an operation is <EM>not</EM> supported, -then calling the table with that operation symbol will return false. -</P> -<P> - -<A NAME="IDX951"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>for-each-row-in-order</B> -<DD>Returns a procedure of arguments <VAR>proc</VAR> <VAR>match-key1</VAR> <small>...</small> -which calls <VAR>proc</VAR> with each <VAR>row</VAR> in this table in the -(implementation-dependent) natural, repeatable ordering for rows. The -optional <VAR>match-key1</VAR> <small>...</small> arguments restrict actions to a -subset of the table. For details see See section <A HREF="slib_6.html#SEC149">6.1.2.2 Match-Keys</A>. -</DL> -<P> - -<A NAME="IDX952"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>isam-next</B> -<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which -returns the key-list identifying the lowest record higher than -<VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which is stored in the relational-table; -or false if no higher record is present. -<P> - -<A NAME="IDX953"></A> -<DT><U>Operation:</U> relational-table <B>isam-next</B> <I>column-name</I> -<DD>The symbol <VAR>column-name</VAR> names a key field. In the list returned -by <CODE>isam-next</CODE>, that field, or a field to its left, will be -changed. This allows one to skip over less significant key fields. -</P> -</DL> -<P> - -<A NAME="IDX954"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>isam-prev</B> -<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which -returns the key-list identifying the highest record less than -<VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which is stored in the relational-table; -or false if no lower record is present. -<P> - -<A NAME="IDX955"></A> -<DT><U>Operation:</U> relational-table <B>isam-prev</B> <I>index</I> -<DD>The symbol <VAR>column-name</VAR> names a key field. In the list returned -by <CODE>isam-next</CODE>, that field, or a field to its left, will be -changed. This allows one to skip over less significant key fields. -</P> -</DL> -<P> - -For example, if a table has key fields: -<TABLE><tr><td> </td><td class=example><pre>(col1 col2) -(9 5) -(9 6) -(9 7) -(9 8) -(12 5) -(12 6) -(12 7) -</pre></td></tr></table><P> - -Then: -<TABLE><tr><td> </td><td class=example><pre>((table 'isam-next) '(9 5)) => (9 6) -((table 'isam-next 'col2) '(9 5)) => (9 6) -((table 'isam-next 'col1) '(9 5)) => (12 5) -((table 'isam-prev) '(12 7)) => (12 6) -((table 'isam-prev 'col2) '(12 7)) => (12 6) -((table 'isam-prev 'col1) '(12 7)) => (9 8) -</pre></td></tr></table><P> - -<A NAME="Table Administration"></A> -<HR SIZE="6"> -<A NAME="SEC153"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC152"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC154"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.2.6 Table Administration </H4> -<!--docid::SEC153::--> -<P> - -<A NAME="IDX956"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>column-names</B> -<DD><A NAME="IDX957"></A> -<DT><U>Operation:</U> relational-table <B>column-foreigns</B> -<DD><A NAME="IDX958"></A> -<DT><U>Operation:</U> relational-table <B>column-domains</B> -<DD><A NAME="IDX959"></A> -<DT><U>Operation:</U> relational-table <B>column-types</B> -<DD>Return a list of the column names, foreign-key table names, domain -names, or type names respectively for this table. These 4 methods are -different from the others in that the list is returned, rather than a -procedure to obtain the list. -<P> - -<A NAME="IDX960"></A> -<DT><U>Operation:</U> relational-table <B>primary-limit</B> -<DD>Returns the number of primary keys fields in the relations in this -table. -</P> -</DL> -<P> - -<A NAME="IDX961"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-table <B>close-table</B> -<DD>Subsequent operations to this table will signal an error. -</DL> -<P> - -<A NAME="Database Interpolation"></A> -<HR SIZE="6"> -<A NAME="SEC154"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC153"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.1.3 Database Interpolation </H3> -<!--docid::SEC154::--> -<P> - -<CODE>(require 'database-interpolate)</CODE> -</P> -<P> - -Indexed sequential access methods allow finding the keys (having -associations) closest to a given value. This facilitates the -interpolation of associations between those in the table. -</P> -<P> - -<A NAME="IDX962"></A> -</P> -<DL> -<DT><U>Function:</U> <B>interpolate-from-table</B> <I>table column</I> -<DD><VAR>Table</VAR> should be a relational table with one numeric primary key -field which supports the <CODE>isam-prev</CODE> and <CODE>isam-next</CODE> -operations. <VAR>column</VAR> should be a symbol or exact positive integer -designating a numerically valued column of <VAR>table</VAR>. -<P> - -<CODE>interpolate-from-table</CODE> calculates and returns a value -proportionally intermediate between its values in the next and -previous key records contained in <VAR>table</VAR>. For keys larger than -all the stored keys the value associated with the largest stored key -is used. For keys smaller than all the stored keys the value -associated with the smallest stored key is used. -</P> -</DL> -<P> - -<A NAME="Embedded Commands"></A> -<HR SIZE="6"> -<A NAME="SEC155"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC154"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC156"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.1.4 Embedded Commands </H3> -<!--docid::SEC155::--> -<P> - -<CODE>(require 'database-commands)</CODE> -</P> -<P> - -This enhancement wraps a utility layer on <CODE>relational-database</CODE> -which provides: -</P> -<P> - -<UL> -<LI> -Automatic execution of initialization commands stored in database. -<LI> -Transparent execution of database commands stored in <CODE>*commands*</CODE> -table in database. -</UL> -<P> - -When an enhanced relational-database is called with a symbol which -matches a <VAR>name</VAR> in the <CODE>*commands*</CODE> table, the associated -procedure expression is evaluated and applied to the enhanced -relational-database. A procedure should then be returned which the user -can invoke on (optional) arguments. -</P> -<P> - -The command <CODE>*initialize*</CODE> is special. If present in the -<CODE>*commands*</CODE> table, <CODE>open-database</CODE> or <CODE>open-database!</CODE> -will return the value of the <CODE>*initialize*</CODE> command. Notice that -arbitrary code can be run when the <CODE>*initialize*</CODE> procedure is -automatically applied to the enhanced relational-database. -</P> -<P> - -Note also that if you wish to shadow or hide from the user -relational-database methods described in <A HREF="slib_6.html#SEC177">6.2.4 Database Operations</A>, this -can be done by a dispatch in the closure returned by the -<CODE>*initialize*</CODE> expression rather than by entries in the -<CODE>*commands*</CODE> table if it is desired that the underlying methods -remain accessible to code in the <CODE>*commands*</CODE> table. -</P> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC156">6.1.4.1 Database Extension</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC157">6.1.4.2 Command Intrinsics</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC158">6.1.4.3 Define-tables Example</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC159">6.1.4.4 The *commands* Table</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC160">6.1.4.5 Command Service</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC161">6.1.4.6 Command Example</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -</TABLE> -<P> - -<A NAME="Database Extension"></A> -<HR SIZE="6"> -<A NAME="SEC156"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC157"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.4.1 Database Extension </H4> -<!--docid::SEC156::--> -<P> - -<A NAME="IDX963"></A> -</P> -<DL> -<DT><U>Function:</U> <B>wrap-command-interface</B> <I>rdb</I> -<DD>Returns relational database <VAR>rdb</VAR> wrapped with additional commands -defined in its *commands* table. -</DL> -<P> - -<A NAME="IDX964"></A> -</P> -<DL> -<DT><U>Function:</U> <B>add-command-tables</B> <I>rdb</I> -<DD>The relational database <VAR>rdb</VAR> must be mutable. -<VAR>add-command-tables</VAR> adds a *command* table to <VAR>rdb</VAR>; then -returns <CODE>(wrap-command-interface <VAR>rdb</VAR>)</CODE>. -</DL> -<P> - -<A NAME="IDX965"></A> -</P> -<DL> -<DT><U>Function:</U> <B>define-*commands*</B> <I>rdb spec-0 <small>...</small></I> -<DD><P> - -Adds commands to the <CODE>*commands*</CODE> table as specified in -<VAR>spec-0</VAR> <small>...</small> to the open relational-database <VAR>rdb</VAR>. Each -<VAR>spec</VAR> has the form: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>((<name> <rdb>) "comment" <expression1> <expression2> <small>...</small>) -</pre></td></tr></table>or -<TABLE><tr><td> </td><td class=example><pre>((<name> <rdb>) <expression1> <expression2> <small>...</small>) -</pre></td></tr></table><P> - -where <name> is the command name, <rdb> is a formal passed the -calling relational database, "comment" describes the -command, and <expression1>, <expression1>, <small>...</small> are the -body of the procedure. -</P> -<P> - -<CODE>define-*commands*</CODE> adds to the <CODE>*commands*</CODE> table a command -<name>: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(lambda (<name> <rdb>) <expression1> <expression2> <small>...</small>) -</pre></td></tr></table><P> - -</P> -</DL> -<P> - -<A NAME="IDX966"></A> -</P> -<DL> -<DT><U>Function:</U> <B>open-command-database</B> <I>filename</I> -<DD><A NAME="IDX967"></A> -<DT><U>Function:</U> <B>open-command-database</B> <I>filename base-table-type</I> -<DD>Returns an open enhanced relational database associated with -<VAR>filename</VAR>. The database will be opened with base-table type -<VAR>base-table-type</VAR>) if supplied. If <VAR>base-table-type</VAR> is not -supplied, <CODE>open-command-database</CODE> will attempt to deduce the correct -base-table-type. If the database can not be opened or if it lacks the -<CODE>*commands*</CODE> table, <CODE>#f</CODE> is returned. -<P> - -<A NAME="IDX968"></A> -<DT><U>Function:</U> <B>open-command-database!</B> <I>filename</I> -<DD><A NAME="IDX969"></A> -<DT><U>Function:</U> <B>open-command-database!</B> <I>filename base-table-type</I> -<DD>Returns <EM>mutable</EM> open enhanced relational database <small>...</small> -</P> -<P> - -<A NAME="IDX970"></A> -<DT><U>Function:</U> <B>open-command-database</B> <I>database</I> -<DD>Returns <VAR>database</VAR> if it is an immutable relational database; #f -otherwise. -</P> -<P> - -<A NAME="IDX971"></A> -<DT><U>Function:</U> <B>open-command-database!</B> <I>database</I> -<DD>Returns <VAR>database</VAR> if it is a mutable relational database; #f -otherwise. -</P> -</DL> -<P> - -<A NAME="Command Intrinsics"></A> -<HR SIZE="6"> -<A NAME="SEC157"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC156"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC158"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.4.2 Command Intrinsics </H4> -<!--docid::SEC157::--> -<P> - -Some commands are defined in all extended relational-databases. The are -called just like <A HREF="slib_6.html#SEC177">6.2.4 Database Operations</A>. -</P> -<P> - -<A NAME="IDX972"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>add-domain</B> <I>domain-row</I> -<DD>Adds <VAR>domain-row</VAR> to the <EM>domains</EM> table if there is no row in -the domains table associated with key <CODE>(car <VAR>domain-row</VAR>)</CODE> and -returns <CODE>#t</CODE>. Otherwise returns <CODE>#f</CODE>. -<P> - -For the fields and layout of the domain table, See section <A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A>. Currently, these fields are -<UL> -<LI> -domain-name -<LI> -foreign-table -<LI> -domain-integrity-rule -<LI> -type-id -<LI> -type-param -</UL> -<P> - -The following example adds 3 domains to the `<SAMP>build</SAMP>' database. -`<SAMP>Optstring</SAMP>' is either a string or <CODE>#f</CODE>. <CODE>filename</CODE> is a -string and <CODE>build-whats</CODE> is a symbol. -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(for-each (build 'add-domain) - '((optstring #f - (lambda (x) (or (not x) (string? x))) - string - #f) - (filename #f #f string #f) - (build-whats #f #f symbol #f))) -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX973"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>delete-domain</B> <I>domain-name</I> -<DD>Removes and returns the <VAR>domain-name</VAR> row from the <EM>domains</EM> -table. -</DL> -<P> - -<A NAME="IDX974"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>domain-checker</B> <I>domain</I> -<DD>Returns a procedure to check an argument for conformance to domain -<VAR>domain</VAR>. -</DL> -<P> - -<A NAME="Define-tables Example"></A> -<HR SIZE="6"> -<A NAME="SEC158"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC157"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC159"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.4.3 Define-tables Example </H4> -<!--docid::SEC158::--> -<P> - -The following example shows a new database with the name of -`<TT>foo.db</TT>' being created with tables describing processor families -and processor/os/compiler combinations. The database is then -solidified; saved and changed to immutable. -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(require 'databases) -<A NAME="IDX975"></A>(define my-rdb (create-database "foo.db" 'alist-table)) -(define-tables my-rdb - '(processor-family - ((family atom)) - ((also-ran processor-family)) - ((m68000 #f) - (m68030 m68000) - (i386 i8086) - (i8086 #f) - (powerpc #f))) - - '(platform - ((name symbol)) - ((processor processor-family) - (os symbol) - (compiler symbol)) - ((aix powerpc aix -) - (amiga-dice-c m68000 amiga dice-c) - (amiga-aztec m68000 amiga aztec) - (amiga-sas/c-5.10 m68000 amiga sas/c) - (atari-st-gcc m68000 atari gcc) - (atari-st-turbo-c m68000 atari turbo-c) - (borland-c-3.1 i8086 ms-dos borland-c) - (djgpp i386 ms-dos gcc) - (linux i386 linux gcc) - (microsoft-c i8086 ms-dos microsoft-c) - (os/2-emx i386 os/2 gcc) - (turbo-c-2 i8086 ms-dos turbo-c) - (watcom-9.0 i386 ms-dos watcom)))) - -(solidify-database my-rdb) -</pre></td></tr></table><P> - -<A NAME="The *commands* Table"></A> -<HR SIZE="6"> -<A NAME="SEC159"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC158"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC160"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.4.4 The *commands* Table </H4> -<!--docid::SEC159::--> -<P> - -The table <CODE>*commands*</CODE> in an <EM>enhanced</EM> relational-database has -the fields (with domains): -<TABLE><tr><td> </td><td class=example><pre>PRI name symbol - parameters parameter-list - procedure expression - documentation string -</pre></td></tr></table><P> - -The <CODE>parameters</CODE> field is a foreign key (domain -<CODE>parameter-list</CODE>) of the <CODE>*catalog-data*</CODE> table and should -have the value of a table described by <CODE>*parameter-columns*</CODE>. This -<CODE>parameter-list</CODE> table describes the arguments suitable for passing -to the associated command. The intent of this table is to be of a form -such that different user-interfaces (for instance, pull-down menus or -plain-text queries) can operate from the same table. A -<CODE>parameter-list</CODE> table has the following fields: -<TABLE><tr><td> </td><td class=example><pre>PRI index ordinal - name symbol - arity parameter-arity - domain domain - defaulter expression - expander expression - documentation string -</pre></td></tr></table><P> - -The <CODE>arity</CODE> field can take the values: -</P> -<P> - -</P> -<DL COMPACT> -<DT><CODE>single</CODE> -<DD>Requires a single parameter of the specified domain. -<DT><CODE>optional</CODE> -<DD>A single parameter of the specified domain or zero parameters is -acceptable. -<DT><CODE>boolean</CODE> -<DD>A single boolean parameter or zero parameters (in which case <CODE>#f</CODE> -is substituted) is acceptable. -<DT><CODE>nary</CODE> -<DD>Any number of parameters of the specified domain are acceptable. The -argument passed to the command function is always a list of the -parameters. -<DT><CODE>nary1</CODE> -<DD>One or more of parameters of the specified domain are acceptable. The -argument passed to the command function is always a list of the -parameters. -</DL> -<P> - -The <CODE>domain</CODE> field specifies the domain which a parameter or -parameters in the <CODE>index</CODE>th field must satisfy. -</P> -<P> - -The <CODE>defaulter</CODE> field is an expression whose value is either -<CODE>#f</CODE> or a procedure of one argument (the parameter-list) which -returns a <EM>list</EM> of the default value or values as appropriate. -Note that since the <CODE>defaulter</CODE> procedure is called every time a -default parameter is needed for this column, <EM>sticky</EM> defaults can -be implemented using shared state with the domain-integrity-rule. -</P> -<P> - -<A NAME="Command Service"></A> -<HR SIZE="6"> -<A NAME="SEC160"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC159"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC161"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.4.5 Command Service </H4> -<!--docid::SEC160::--> -<P> - -<A NAME="IDX976"></A> -</P> -<DL> -<DT><U>Function:</U> <B>make-command-server</B> <I>rdb table-name</I> -<DD>Returns a procedure of 2 arguments, a (symbol) command and a call-back -procedure. When this returned procedure is called, it looks up -<VAR>command</VAR> in table <VAR>table-name</VAR> and calls the call-back -procedure with arguments: -<DL COMPACT> -<DT><VAR>command</VAR> -<DD>The <VAR>command</VAR> -<DT><VAR>command-value</VAR> -<DD>The result of evaluating the expression in the <VAR>procedure</VAR> field of -<VAR>table-name</VAR> and calling it with <VAR>rdb</VAR>. -<DT><VAR>parameter-name</VAR> -<DD>A list of the <EM>official</EM> name of each parameter. Corresponds to the -<CODE>name</CODE> field of the <VAR>command</VAR>'s parameter-table. -<DT><VAR>positions</VAR> -<DD>A list of the positive integer index of each parameter. Corresponds to -the <CODE>index</CODE> field of the <VAR>command</VAR>'s parameter-table. -<DT><VAR>arities</VAR> -<DD>A list of the arities of each parameter. Corresponds to the -<CODE>arity</CODE> field of the <VAR>command</VAR>'s parameter-table. For a -description of <CODE>arity</CODE> see table above. -<DT><VAR>types</VAR> -<DD>A list of the type name of each parameter. Correspnds to the -<CODE>type-id</CODE> field of the contents of the <CODE>domain</CODE> of the -<VAR>command</VAR>'s parameter-table. -<DT><VAR>defaulters</VAR> -<DD>A list of the defaulters for each parameter. Corresponds to -the <CODE>defaulters</CODE> field of the <VAR>command</VAR>'s parameter-table. -<DT><VAR>domain-integrity-rules</VAR> -<DD>A list of procedures (one for each parameter) which tests whether a -value for a parameter is acceptable for that parameter. The procedure -should be called with each datum in the list for <CODE>nary</CODE> arity -parameters. -<DT><VAR>aliases</VAR> -<DD>A list of lists of <CODE>(alias parameter-name)</CODE>. There can be -more than one alias per <VAR>parameter-name</VAR>. -</DL> -</DL> -<P> - -For information about parameters, See section <A HREF="slib_4.html#SEC65">4.4.4 Parameter lists</A>. -</P> -<P> - -<A NAME="Command Example"></A> -<HR SIZE="6"> -<A NAME="SEC161"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC160"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC162"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.4.6 Command Example </H4> -<!--docid::SEC161::--> -<P> - -Here is an example of setting up a command with arguments and parsing -those arguments from a <CODE>getopt</CODE> style argument list -(see section <A HREF="slib_4.html#SEC62">4.4.1 Getopt</A>). -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(require 'database-commands) -<A NAME="IDX977"></A>(require 'databases) -<A NAME="IDX978"></A>(require 'getopt-parameters) -<A NAME="IDX979"></A>(require 'parameters) -<A NAME="IDX980"></A>(require 'getopt) -<A NAME="IDX981"></A>(require 'fluid-let) -(require 'printf) - -(define my-rdb (add-command-tables (create-database #f 'alist-table))) - -(define-tables my-rdb - '(foo-params - *parameter-columns* - *parameter-columns* - ((1 single-string single string - (lambda (pl) '("str")) #f "single string") - (2 nary-symbols nary symbol - (lambda (pl) '()) #f "zero or more symbols") - (3 nary1-symbols nary1 symbol - (lambda (pl) '(symb)) #f "one or more symbols") - (4 optional-number optional ordinal - (lambda (pl) '()) #f "zero or one number") - (5 flag boolean boolean - (lambda (pl) '(#f)) #f "a boolean flag"))) - '(foo-pnames - ((name string)) - ((parameter-index ordinal)) - (("s" 1) - ("single-string" 1) - ("n" 2) - ("nary-symbols" 2) - ("N" 3) - ("nary1-symbols" 3) - ("o" 4) - ("optional-number" 4) - ("f" 5) - ("flag" 5))) - '(my-commands - ((name symbol)) - ((parameters parameter-list) - (parameter-names parameter-name-translation) - (procedure expression) - (documentation string)) - ((foo - foo-params - foo-pnames - (lambda (rdb) (lambda args (print args))) - "test command arguments")))) - -(define (dbutil:serve-command-line rdb command-table command argv) - (set! *argv* (if (vector? argv) (vector->list argv) argv)) - ((make-command-server rdb command-table) - command - (lambda (comname comval options positions - arities types defaulters dirs aliases) - (apply comval (getopt->arglist options positions - arities types defaulters dirs aliases))))) - -(define (cmd . opts) - (fluid-let ((*optind* 1)) - (printf "%-34s => " - (call-with-output-string - (lambda (pt) (write (cons 'cmd opts) pt)))) - (set! opts (cons "cmd" opts)) - (force-output) - (dbutil:serve-command-line - my-rdb 'my-commands 'foo (length opts) opts))) - -(cmd) => ("str" () (symb) () #f) -(cmd "-f") => ("str" () (symb) () #t) -(cmd "--flag") => ("str" () (symb) () #t) -(cmd "-o177") => ("str" () (symb) (177) #f) -(cmd "-o" "177") => ("str" () (symb) (177) #f) -(cmd "--optional" "621") => ("str" () (symb) (621) #f) -(cmd "--optional=621") => ("str" () (symb) (621) #f) -(cmd "-s" "speciality") => ("speciality" () (symb) () #f) -(cmd "-sspeciality") => ("speciality" () (symb) () #f) -(cmd "--single" "serendipity") => ("serendipity" () (symb) () #f) -(cmd "--single=serendipity") => ("serendipity" () (symb) () #f) -(cmd "-n" "gravity" "piety") => ("str" () (piety gravity) () #f) -(cmd "-ngravity" "piety") => ("str" () (piety gravity) () #f) -(cmd "--nary" "chastity") => ("str" () (chastity) () #f) -(cmd "--nary=chastity" "") => ("str" () ( chastity) () #f) -(cmd "-N" "calamity") => ("str" () (calamity) () #f) -(cmd "-Ncalamity") => ("str" () (calamity) () #f) -(cmd "--nary1" "surety") => ("str" () (surety) () #f) -(cmd "--nary1=surety") => ("str" () (surety) () #f) -(cmd "-N" "levity" "fealty") => ("str" () (fealty levity) () #f) -(cmd "-Nlevity" "fealty") => ("str" () (fealty levity) () #f) -(cmd "--nary1" "surety" "brevity") => ("str" () (brevity surety) () #f) -(cmd "--nary1=surety" "brevity") => ("str" () (brevity surety) () #f) -(cmd "-?") --| -Usage: cmd [OPTION ARGUMENT ...] ... - - -f, --flag - -o, --optional[=]<number> - -n, --nary[=]<symbols> ... - -N, --nary1[=]<symbols> ... - -s, --single[=]<string> - -ERROR: getopt->parameter-list "unrecognized option" "-?" -</pre></td></tr></table><P> - -<A NAME="Database Macros"></A> -<HR SIZE="6"> -<A NAME="SEC162"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC161"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC163"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.1.5 Database Macros </H3> -<!--docid::SEC162::--> -<P> - -<CODE>(require 'within-database)</CODE> -</P> -<P> - -The object-oriented programming interface to SLIB relational databases -has failed to support clear, understandable, and modular code-writing -for database applications. -</P> -<P> - -This seems to be a failure of the object-oriented paradigm where the -type of an object is not manifest (or even traceable) in source code. -</P> -<P> - -<CODE>within-database</CODE>, along with the `<SAMP>databases</SAMP>' package, -reorganizes high-level database functions toward a more declarative -style. Using this package, one can tag database table and command -declarations for emacs: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>etags -lscheme -r'/ *(define-\(command\|table\) (\([^; \t]+\)/\2/' \ - source1.scm ... -</pre></td></tr></table><P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC163">6.1.5.1 Within-database Example</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -</TABLE> -<P> - -<A NAME="IDX982"></A> -</P> -<DL> -<DT><U>Function:</U> <B>within-database</B> <I>database statement-1 <small>...</small></I> -<DD><P> - -<CODE>within-database</CODE> creates a lexical scope in which the commands -<CODE>define-table</CODE> and <CODE>define-command</CODE> create tables and -<CODE>*commands*</CODE>-table entries respectively in open relational -database <VAR>database</VAR>. -</P> -<P> - -<CODE>within-database</CODE> Returns <VAR>database</VAR>. -</P> -</DL> -<P> - -<A NAME="IDX983"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>define-command</B> <I>(<name> <rdb>) "comment" <expression1> <expression2> <small>...</small></I> -<DD><A NAME="IDX984"></A> -<DT><U>Syntax:</U> <B>define-command</B> <I>(<name> <rdb>) <expression1> <expression2> <small>...</small></I> -<DD><P> - -Adds to the <CODE>*commands*</CODE> table a command -<name>: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(lambda (<name> <rdb>) <expression1> <expression2> <small>...</small>) -</pre></td></tr></table><P> - -</P> -</DL> -<P> - -<A NAME="IDX985"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>define-table</B> <I><name> <descriptor-name> <descriptor-name> <rows></I> -<DD><A NAME="IDX986"></A> -<DT><U>Syntax:</U> <B>define-table</B> <I><name> <primary-key-fields> <other-fields> <rows></I> -<DD><P> - -where <name> is the table name, <descriptor-name> is the symbol -name of a descriptor table, <primary-key-fields> and -<other-fields> describe the primary keys and other fields -respectively, and <rows> is a list of data rows to be added to the -table. -</P> -<P> - -<primary-key-fields> and <other-fields> are lists of field -descriptors of the form: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(<column-name> <domain>) -</pre></td></tr></table>or -<TABLE><tr><td> </td><td class=example><pre>(<column-name> <domain> <column-integrity-rule>) -</pre></td></tr></table><P> - -where <column-name> is the column name, <domain> is the domain -of the column, and <column-integrity-rule> is an expression whose -value is a procedure of one argument (which returns <CODE>#f</CODE> to signal -an error). -</P> -<P> - -If <domain> is not a defined domain name and it matches the name of -this table or an already defined (in one of <VAR>spec-0</VAR> <small>...</small>) single -key field table, a foreign-key domain will be created for it. -</P> -<P> - -</P> -</DL> -<P> - -<A NAME="Within-database Example"></A> -<HR SIZE="6"> -<A NAME="SEC163"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC162"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC164"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC162"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.1.5.1 Within-database Example </H4> -<!--docid::SEC163::--> -<P> - -Here is an example of <CODE>within-database</CODE> macros: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(require 'within-database) - -(define my-rdb - (add-command-tables - (create-database "foo.db" 'alist-table))) - -(within-database my-rdb - (define-command (*initialize* rdb) - "Print Welcome" - (display "Welcome") - (newline) - rdb) - (define-command (without-documentation rdb) - (display "without-documentation called") - (newline)) - (define-table (processor-family - ((family atom)) - ((also-ran processor-family))) - (m68000 #f) - (m68030 m68000) - (i386 i8086) - (i8086 #f) - (powerpc #f)) - (define-table (platform - ((name symbol)) - ((processor processor-family) - (os symbol) - (compiler symbol))) - (aix powerpc aix -) - ;; ... - (amiga-aztec m68000 amiga aztec) - (amiga-sas/c-5.10 m68000 amiga sas/c) - (atari-st-gcc m68000 atari gcc) - ;; ... - (watcom-9.0 i386 ms-dos watcom)) - (define-command (get-processor rdb) - "Get processor for given platform." - (((rdb 'open-table) 'platform #f) 'get 'processor))) - -(close-database my-rdb) - -(set! my-rdb (open-command-database! "foo.db")) --| -Welcome - -(my-rdb 'without-documentation) --| -without-documentation called - -((my-rdb 'get-processor) 'amiga-sas/c-5.10) -=> m68000 - -(close-database my-rdb) -</pre></td></tr></table><P> - -<A NAME="Database Browser"></A> -<HR SIZE="6"> -<A NAME="SEC164"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC163"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.1.6 Database Browser </H3> -<!--docid::SEC164::--> -<P> - -(require 'database-browse) -</P> -<P> - -<A NAME="IDX987"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>browse</B> <I>database</I> -<DD><P> - -Prints the names of all the tables in <VAR>database</VAR> and sets browse's -default to <VAR>database</VAR>. -</P> -<P> - -<A NAME="IDX988"></A> -<DT><U>Procedure:</U> <B>browse</B> -<DD></P> -<P> - -Prints the names of all the tables in the default database. -</P> -<P> - -<A NAME="IDX989"></A> -<DT><U>Procedure:</U> <B>browse</B> <I>table-name</I> -<DD></P> -<P> - -For each record of the table named by the symbol <VAR>table-name</VAR>, -prints a line composed of all the field values. -</P> -<P> - -<A NAME="IDX990"></A> -<DT><U>Procedure:</U> <B>browse</B> <I>pathname</I> -<DD></P> -<P> - -Opens the database named by the string <VAR>pathname</VAR>, prints the names -of all its tables, and sets browse's default to the database. -</P> -<P> - -<A NAME="IDX991"></A> -<DT><U>Procedure:</U> <B>browse</B> <I>database table-name</I> -<DD></P> -<P> - -Sets browse's default to <VAR>database</VAR> and prints the records of the -table named by the symbol <VAR>table-name</VAR>. -</P> -<P> - -<A NAME="IDX992"></A> -<DT><U>Procedure:</U> <B>browse</B> <I>pathname table-name</I> -<DD></P> -<P> - -Opens the database named by the string <VAR>pathname</VAR> and sets browse's -default to it; <CODE>browse</CODE> prints the records of the table named by -the symbol <VAR>table-name</VAR>. -</P> -<P> - -</P> -</DL> -<P> - -<A NAME="Relational Infrastructure"></A> -<HR SIZE="6"> -<A NAME="SEC165"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC164"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 6.2 Relational Infrastructure </H2> -<!--docid::SEC165::--> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC166">6.2.1 Base Table</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC176">6.2.3 Relational Database Objects</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC177">6.2.4 Database Operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -</TABLE> -<P> - -<A NAME="Base Table"></A> -<HR SIZE="6"> -<A NAME="SEC166"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC167"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.2.1 Base Table </H3> -<!--docid::SEC166::--> -<P> - -<A NAME="IDX993"></A> -A <EM>base-table</EM> is the primitive database layer upon which SLIB -relational databases are built. At the minimum, it must support the -types integer, symbol, string, and boolean. The base-table may restrict -the size of integers, symbols, and strings it supports. -</P> -<P> - -A base table implementation is available as the value of the identifier -naming it (eg. <VAR>alist-table</VAR>) after requiring the symbol of that -name. -</P> -<P> - -<A NAME="IDX994"></A> -</P> -<DL> -<DT><U>Feature:</U> <B>alist-table</B> -<DD><CODE>(require 'alist-table)</CODE> -<A NAME="IDX995"></A> -<P> - -Association-list base tables support all Scheme types and are suitable -for small databases. In order to be retrieved after being written to a -file, the data stored should include only objects which are readable and -writeable in the Scheme implementation. -</P> -<P> - -The <EM>alist-table</EM> base-table implementation is included in the -SLIB distribution. -</P> -</DL> -<P> - -<EM>WB</EM> is a B-tree database package with SCM interfaces. Being -disk-based, WB databases readily store and access hundreds of -megabytes of data. WB comes with two base-table embeddings. -</P> -<P> - -<A NAME="IDX996"></A> -</P> -<DL> -<DT><U>Feature:</U> <B>wb-table</B> -<DD><CODE>(require 'wb-table)</CODE> -<A NAME="IDX997"></A> -<P> - -<A NAME="IDX998"></A> -<CODE>wb-table</CODE> supports scheme expressions for keys and values whose -text representations are less than 255 characters in length. -See section `wb-table' in <CITE>WB</CITE>. -</P> -</DL> -<P> - -<A NAME="IDX999"></A> -</P> -<DL> -<DT><U>Feature:</U> <B>rwb-isam</B> -<DD><CODE>(require 'rwb-isam)</CODE> -<A NAME="IDX1000"></A> -<P> - -<EM>rwb-isam</EM> is a sophisticated base-table implementation built on -WB and SCM which uses binary numerical formats for key and non-key -fields. It supports IEEE floating-point and fixed-precision integer -keys with the correct numerical collation order. -</P> -</DL> -<P> - -This rest of this section documents the interface for a base table -implementation from which the <A HREF="slib_6.html#SEC141">6.1 Relational Database</A> package -constructs a Relational system. It will be of interest primarily to -those wishing to port or write new base-table implementations. -</P> -<P> - -<A NAME="IDX1001"></A> -</P> -<DL> -<DT><U>Variable:</U> <B>*base-table-implementations*</B> -<DD>To support automatic dispatch for <CODE>open-database</CODE>, each base-table -module adds an association to <VAR>*base-table-implementations*</VAR> when -loaded. This association is the list of the base-table symbol and the -value returned by <CODE>(make-relational-system <VAR>base-table</VAR>)</CODE>. -</DL> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC167">6.2.1.1 The Base</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC168">6.2.1.2 Base Tables</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC169">6.2.1.3 Base Field Types</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC170">6.2.1.4 Composite Keys</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC171">6.2.1.5 Base Record Operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC172">6.2.1.6 Match Keys</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC173">6.2.1.7 Aggregate Base Operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC174">6.2.1.8 Base ISAM Operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -</TABLE> -<P> - -<A NAME="The Base"></A> -<HR SIZE="6"> -<A NAME="SEC167"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC168"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.2.1.1 The Base </H4> -<!--docid::SEC167::--> -<P> - -All of these functions are accessed through a single procedure by -calling that procedure with the symbol name of the operation. A -procedure will be returned if that operation is supported and <CODE>#f</CODE> -otherwise. For example: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(require 'alist-table) -<A NAME="IDX1002"></A><A NAME="IDX1003"></A>(define my-base (alist-table 'make-base)) -my-base => *a procedure* -(define foo (alist-table 'foo)) -foo => #f -</pre></td></tr></table><P> - -<A NAME="IDX1004"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-base</B> <I>filename key-dimension column-types</I> -<DD>Returns a new, open, low-level database (collection of tables) -associated with <VAR>filename</VAR>. This returned database has an empty -table associated with <VAR>catalog-id</VAR>. The positive integer -<VAR>key-dimension</VAR> is the number of keys composed to make a -<VAR>primary-key</VAR> for the catalog table. The list of symbols -<VAR>column-types</VAR> describes the types of each column for that table. -If the database cannot be created as specified, <CODE>#f</CODE> is returned. -<P> - -Calling the <CODE>close-base</CODE> method on this database and possibly other -operations will cause <VAR>filename</VAR> to be written to. If -<VAR>filename</VAR> is <CODE>#f</CODE> a temporary, non-disk based database will be -created if such can be supported by the base table implelentation. -</P> -</DL> -<P> - -<A NAME="IDX1005"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>open-base</B> <I>filename mutable</I> -<DD>Returns an open low-level database associated with <VAR>filename</VAR>. If -<VAR>mutable</VAR> is <CODE>#t</CODE>, this database will have methods capable of -effecting change to the database. If <VAR>mutable</VAR> is <CODE>#f</CODE>, only -methods for inquiring the database will be available. If the database -cannot be opened as specified <CODE>#f</CODE> is returned. -<P> - -Calling the <CODE>close-base</CODE> (and possibly other) method on a -<VAR>mutable</VAR> database will cause <VAR>filename</VAR> to be written to. -</P> -</DL> -<P> - -<A NAME="IDX1006"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>write-base</B> <I>lldb filename</I> -<DD>Causes the low-level database <VAR>lldb</VAR> to be written to -<VAR>filename</VAR>. If the write is successful, also causes <VAR>lldb</VAR> to -henceforth be associated with <VAR>filename</VAR>. Calling the -<CODE>close-database</CODE> (and possibly other) method on <VAR>lldb</VAR> may -cause <VAR>filename</VAR> to be written to. If <VAR>filename</VAR> is <CODE>#f</CODE> -this database will be changed to a temporary, non-disk based database if -such can be supported by the underlying base table implelentation. If -the operations completed successfully, <CODE>#t</CODE> is returned. -Otherwise, <CODE>#f</CODE> is returned. -</DL> -<P> - -<A NAME="IDX1007"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>sync-base</B> <I>lldb</I> -<DD>Causes the file associated with the low-level database <VAR>lldb</VAR> to be -updated to reflect its current state. If the associated filename is -<CODE>#f</CODE>, no action is taken and <CODE>#f</CODE> is returned. If this -operation completes successfully, <CODE>#t</CODE> is returned. Otherwise, -<CODE>#f</CODE> is returned. -</DL> -<P> - -<A NAME="IDX1008"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>close-base</B> <I>lldb</I> -<DD>Causes the low-level database <VAR>lldb</VAR> to be written to its associated -file (if any). If the write is successful, subsequent operations to -<VAR>lldb</VAR> will signal an error. If the operations complete -successfully, <CODE>#t</CODE> is returned. Otherwise, <CODE>#f</CODE> is returned. -</DL> -<P> - -<A NAME="Base Tables"></A> -<HR SIZE="6"> -<A NAME="SEC168"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC167"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC169"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.2.1.2 Base Tables </H4> -<!--docid::SEC168::--> -<P> - -<A NAME="IDX1009"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-table</B> <I>lldb key-dimension column-types</I> -<DD>Returns the ordinal <VAR>base-id</VAR> for a new base table, otherwise -returns <CODE>#f</CODE>. The base table can then be opened using -<CODE>(open-table <VAR>lldb</VAR> <VAR>base-id</VAR>)</CODE>. The positive integer -<VAR>key-dimension</VAR> is the number of keys composed to make a -<VAR>primary-key</VAR> for this table. The list of symbols -<VAR>column-types</VAR> describes the types of each column. -</DL> -<P> - -<A NAME="IDX1010"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>open-table</B> <I>lldb base-id key-dimension column-types</I> -<DD>Returns a <VAR>handle</VAR> for an existing base table in the low-level -database <VAR>lldb</VAR> if that table exists and can be opened in the mode -indicated by <VAR>mutable</VAR>, otherwise returns <CODE>#f</CODE>. -<P> - -As with <CODE>make-table</CODE>, the positive integer <VAR>key-dimension</VAR> is -the number of keys composed to make a <VAR>primary-key</VAR> for this table. -The list of symbols <VAR>column-types</VAR> describes the types of each -column. -</P> -</DL> -<P> - -<A NAME="IDX1011"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>kill-table</B> <I>lldb base-id key-dimension column-types</I> -<DD>Returns <CODE>#t</CODE> if the base table associated with <VAR>base-id</VAR> was -removed from the low level database <VAR>lldb</VAR>, and <CODE>#f</CODE> otherwise. -</DL> -<P> - -<A NAME="IDX1012"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>catalog-id</B> -<DD>A constant <VAR>base-id</VAR> ordinal suitable for passing as a parameter to -<CODE>open-table</CODE>. <VAR>catalog-id</VAR> will be used as the base table for -the system catalog. -</DL> -<P> - -<A NAME="Base Field Types"></A> -<HR SIZE="6"> -<A NAME="SEC169"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC168"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC170"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.2.1.3 Base Field Types </H4> -<!--docid::SEC169::--> -<P> - -<A NAME="IDX1013"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>supported-type?</B> <I>symbol</I> -<DD>Returns <CODE>#t</CODE> if <VAR>symbol</VAR> names a type allowed as a column -value by the implementation, and <CODE>#f</CODE> otherwise. At a minimum, -an implementation must support the types <CODE>integer</CODE>, -<CODE>ordinal</CODE>, <CODE>symbol</CODE>, <CODE>string</CODE>, and <CODE>boolean</CODE>. -</DL> -<P> - -<A NAME="IDX1014"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>supported-key-type?</B> <I>symbol</I> -<DD>Returns <CODE>#t</CODE> if <VAR>symbol</VAR> names a type allowed as a key value -by the implementation, and <CODE>#f</CODE> otherwise. At a minimum, an -implementation must support the types <CODE>ordinal</CODE>, and -<CODE>symbol</CODE>. -</DL> -<P> - -An <EM>ordinal</EM> is an exact positive integer. The other types are -standard Scheme. -</P> -<P> - -<A NAME="Composite Keys"></A> -<HR SIZE="6"> -<A NAME="SEC170"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC169"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC171"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.2.1.4 Composite Keys </H4> -<!--docid::SEC170::--> -<P> - -<A NAME="IDX1015"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-keyifier-1</B> <I>type</I> -<DD>Returns a procedure which accepts a single argument which must be of -type <VAR>type</VAR>. This returned procedure returns an object suitable for -being a <VAR>key</VAR> argument in the functions whose descriptions follow. -<P> - -Any 2 arguments of the supported type passed to the returned function -which are not <CODE>equal?</CODE> must result in returned values which are not -<CODE>equal?</CODE>. -</P> -</DL> -<P> - -<A NAME="IDX1016"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-list-keyifier</B> <I>key-dimension types</I> -<DD>The list of symbols <VAR>types</VAR> must have at least <VAR>key-dimension</VAR> -elements. Returns a procedure which accepts a list of length -<VAR>key-dimension</VAR> and whose types must corresopond to the types named -by <VAR>types</VAR>. This returned procedure combines the elements of its -list argument into an object suitable for being a <VAR>key</VAR> argument in -the functions whose descriptions follow. -<P> - -Any 2 lists of supported types (which must at least include symbols and -non-negative integers) passed to the returned function which are not -<CODE>equal?</CODE> must result in returned values which are not -<CODE>equal?</CODE>. -</P> -</DL> -<P> - -<A NAME="IDX1017"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-key-extractor</B> <I>key-dimension types column-number</I> -<DD>Returns a procedure which accepts objects produced by application of the -result of <CODE>(make-list-keyifier <VAR>key-dimension</VAR> <VAR>types</VAR>)</CODE>. -This procedure returns a <VAR>key</VAR> which is <CODE>equal?</CODE> to the -<VAR>column-number</VAR>th element of the list which was passed to create -<VAR>composite-key</VAR>. The list <VAR>types</VAR> must have at least -<VAR>key-dimension</VAR> elements. -</DL> -<P> - -<A NAME="IDX1018"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-key->list</B> <I>key-dimension types</I> -<DD>Returns a procedure which accepts objects produced by application of -the result of <CODE>(make-list-keyifier <VAR>key-dimension</VAR> -<VAR>types</VAR>)</CODE>. This procedure returns a list of <VAR>key</VAR>s which are -elementwise <CODE>equal?</CODE> to the list which was passed to create -<VAR>composite-key</VAR>. -</DL> -<P> - -<A NAME="Base Record Operations"></A> -<HR SIZE="6"> -<A NAME="SEC171"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC170"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC172"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.2.1.5 Base Record Operations </H4> -<!--docid::SEC171::--> -<P> - -In the following functions, the <VAR>key</VAR> argument can always be assumed -to be the value returned by a call to a <EM>keyify</EM> routine. -</P> -<P> - -<A NAME="IDX1019"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>present?</B> <I>handle key</I> -<DD>Returns a non-<CODE>#f</CODE> value if there is a row associated with -<VAR>key</VAR> in the table opened in <VAR>handle</VAR> and <CODE>#f</CODE> otherwise. -</DL> -<P> - -<A NAME="IDX1020"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-getter</B> <I>key-dimension types</I> -<DD>Returns a procedure which takes arguments <VAR>handle</VAR> and <VAR>key</VAR>. -This procedure returns a list of the non-primary values of the relation -(in the base table opened in <VAR>handle</VAR>) whose primary key is -<VAR>key</VAR> if it exists, and <CODE>#f</CODE> otherwise. -</DL> -<P> - -<CODE>make-getter-1</CODE> is a new operation. The relational-database -module works with older base-table implementations by using -<CODE>make-getter</CODE>. -</P> -<P> - -<A NAME="IDX1021"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-getter-1</B> <I>key-dimension types index</I> -<DD>Returns a procedure which takes arguments <VAR>handle</VAR> and <VAR>key</VAR>. -This procedure returns the value of the <VAR>index</VAR>th field (in the -base table opened in <VAR>handle</VAR>) whose primary key is <VAR>key</VAR> if -it exists, and <CODE>#f</CODE> otherwise. -<P> - -<VAR>index</VAR> must be larger than <VAR>key-dimension</VAR>. -</P> -</DL> -<P> - -<A NAME="IDX1022"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-putter</B> <I>key-dimension types</I> -<DD>Returns a procedure which takes arguments <VAR>handle</VAR> and <VAR>key</VAR> and -<VAR>value-list</VAR>. This procedure associates the primary key <VAR>key</VAR> -with the values in <VAR>value-list</VAR> (in the base table opened in -<VAR>handle</VAR>) and returns an unspecified value. -</DL> -<P> - -<A NAME="IDX1023"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>delete</B> <I>handle key</I> -<DD>Removes the row associated with <VAR>key</VAR> from the table opened in -<VAR>handle</VAR>. An unspecified value is returned. -</DL> -<P> - -<A NAME="Match Keys"></A> -<HR SIZE="6"> -<A NAME="SEC172"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC171"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC173"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.2.1.6 Match Keys </H4> -<!--docid::SEC172::--> -<P> - -<A NAME="IDX1024"></A> -<A NAME="IDX1025"></A> -<A NAME="IDX1026"></A> -A <VAR>match-keys</VAR> argument is a list of length equal to -the number of primary keys. The <VAR>match-keys</VAR> restrict the actions -of the table command to those records whose primary keys all satisfy the -corresponding element of the <VAR>match-keys</VAR> list. The elements and -their actions are: -</P> -<P> - -<BLOCKQUOTE> -<DL COMPACT> -<DT><CODE>#f</CODE> -<DD>The false value matches any key in the corresponding position. -<DT>an object of type procedure -<DD>This procedure must take a single argument, the key in the corresponding -position. Any key for which the procedure returns a non-false value is -a match; Any key for which the procedure returns a <CODE>#f</CODE> is not. -<DT>other values -<DD>Any other value matches only those keys <CODE>equal?</CODE> to it. -</DL> -</BLOCKQUOTE> -<P> - -<A NAME="Aggregate Base Operations"></A> -<HR SIZE="6"> -<A NAME="SEC173"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC172"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC174"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.2.1.7 Aggregate Base Operations </H4> -<!--docid::SEC173::--> -<P> - -The <VAR>key-dimension</VAR> and <VAR>column-types</VAR> arguments are needed to -decode the composite-keys for matching with <VAR>match-keys</VAR>. -</P> -<P> - -<A NAME="IDX1027"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>delete*</B> <I>handle key-dimension column-types match-keys</I> -<DD>Removes all rows which satisfy <VAR>match-keys</VAR> from the table opened in -<VAR>handle</VAR>. An unspecified value is returned. -</DL> -<P> - -<A NAME="IDX1028"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>for-each-key</B> <I>handle procedure key-dimension column-types match-keys</I> -<DD>Calls <VAR>procedure</VAR> once with each <VAR>key</VAR> in the table opened in -<VAR>handle</VAR> which satisfy <VAR>match-keys</VAR> in an unspecified order. -An unspecified value is returned. -</DL> -<P> - -<A NAME="IDX1029"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>map-key</B> <I>handle procedure key-dimension column-types match-keys</I> -<DD>Returns a list of the values returned by calling <VAR>procedure</VAR> once -with each <VAR>key</VAR> in the table opened in <VAR>handle</VAR> which satisfy -<VAR>match-keys</VAR> in an unspecified order. -</DL> -<P> - -<A NAME="Base ISAM Operations"></A> -<HR SIZE="6"> -<A NAME="SEC174"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC173"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC175"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 6.2.1.8 Base ISAM Operations </H4> -<!--docid::SEC174::--> -<P> - -These operations are optional for a Base-Table implementation. -</P> -<P> - -<A NAME="IDX1030"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>ordered-for-each-key</B> <I>handle procedure key-dimension column-types match-keys</I> -<DD>Calls <VAR>procedure</VAR> once with each <VAR>key</VAR> in the table opened in -<VAR>handle</VAR> which satisfy <VAR>match-keys</VAR> in the natural order for -the types of the primary key fields of that table. An unspecified value -is returned. -</DL> -<P> - -<A NAME="IDX1031"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-nexter</B> <I>handle key-dimension column-types index</I> -<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which -returns the key-list identifying the lowest record higher than -<VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which is stored in the base-table and -which differs in column <VAR>index</VAR> or a lower indexed key; or false -if no higher record is present. -</DL> -<P> - -<A NAME="IDX1032"></A> -</P> -<DL> -<DT><U>Operation:</U> base-table <B>make-prever</B> <I>handle key-dimension column-types index</I> -<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which -returns the key-list identifying the highest record less than -<VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which is stored in the base-table and -which differs in column <VAR>index</VAR> or a lower indexed key; or false -if no higher record is present. -</DL> -<P> - -<A NAME="Catalog Representation"></A> -<HR SIZE="6"> -<A NAME="SEC175"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC174"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC176"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.2.2 Catalog Representation </H3> -<!--docid::SEC175::--> -<P> - -Each database (in an implementation) has a <EM>system catalog</EM> which -describes all the user accessible tables in that database (including -itself). -</P> -<P> - -The system catalog base table has the following fields. <CODE>PRI</CODE> -indicates a primary key for that table. -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>PRI table-name - column-limit the highest column number - coltab-name descriptor table name - bastab-id data base table identifier - user-integrity-rule - view-procedure A scheme thunk which, when called, - produces a handle for the view. coltab - and bastab are specified if and only if - view-procedure is not. -</pre></td></tr></table><P> - -Descriptors for base tables (not views) are tables (pointed to by -system catalog). Descriptor (base) tables have the fields: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>PRI column-number sequential integers from 1 - primary-key? boolean TRUE for primary key components - column-name - column-integrity-rule - domain-name -</pre></td></tr></table><P> - -A <EM>primary key</EM> is any column marked as <CODE>primary-key?</CODE> in the -corresponding descriptor table. All the <CODE>primary-key?</CODE> columns -must have lower column numbers than any non-<CODE>primary-key?</CODE> columns. -Every table must have at least one primary key. Primary keys must be -sufficient to distinguish all rows from each other in the table. All of -the system defined tables have a single primary key. -</P> -<P> - -A <EM>domain</EM> is a category describing the allowable values to occur in -a column. It is described by a (base) table with the fields: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>PRI domain-name - foreign-table - domain-integrity-rule - type-id - type-param -</pre></td></tr></table><P> - -The <EM>type-id</EM> field value is a symbol. This symbol may be used by -the underlying base table implementation in storing that field. -</P> -<P> - -If the <CODE>foreign-table</CODE> field is non-<CODE>#f</CODE> then that field names -a table from the catalog. The values for that domain must match a -primary key of the table referenced by the <VAR>type-param</VAR> (or -<CODE>#f</CODE>, if allowed). This package currently does not support -composite foreign-keys. -</P> -<P> - -The types for which support is planned are: -<TABLE><tr><td> </td><td class=example><pre> atom - symbol - string [<length>] - number [<base>] - money <currency> - date-time - boolean - - foreign-key <table-name> - expression - virtual <expression> -</pre></td></tr></table><P> - -<A NAME="Relational Database Objects"></A> -<HR SIZE="6"> -<A NAME="SEC176"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC175"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC177"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.2.3 Relational Database Objects </H3> -<!--docid::SEC176::--> -<P> - -This object-oriented interface is deprecated for typical database -applications; <A HREF="slib_6.html#SEC142">6.1.1 Using Databases</A> provides an application programmer -interface which is easier to understand and use. -</P> -<P> - -<A NAME="IDX1033"></A> -</P> -<DL> -<DT><U>Function:</U> <B>make-relational-system</B> <I>base-table-implementation</I> -<DD><P> - -Returns a procedure implementing a relational database using the -<VAR>base-table-implementation</VAR>. -</P> -<P> - -All of the operations of a base table implementation are accessed -through a procedure defined by <CODE>require</CODE>ing that implementation. -Similarly, all of the operations of the relational database -implementation are accessed through the procedure returned by -<CODE>make-relational-system</CODE>. For instance, a new relational database -could be created from the procedure returned by -<CODE>make-relational-system</CODE> by: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(require 'alist-table) -<A NAME="IDX1034"></A>(define relational-alist-system - (make-relational-system alist-table)) -(define create-alist-database - (relational-alist-system 'create-database)) -(define my-database - (create-alist-database "mydata.db")) -</pre></td></tr></table></DL> -<P> - -What follows are the descriptions of the methods available from -relational system returned by a call to <CODE>make-relational-system</CODE>. -</P> -<P> - -<A NAME="IDX1035"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-system <B>create-database</B> <I>filename</I> -<DD><P> - -Returns an open, nearly empty relational database associated with -<VAR>filename</VAR>. The only tables defined are the system catalog and -domain table. Calling the <CODE>close-database</CODE> method on this database -and possibly other operations will cause <VAR>filename</VAR> to be written -to. If <VAR>filename</VAR> is <CODE>#f</CODE> a temporary, non-disk based database -will be created if such can be supported by the underlying base table -implelentation. If the database cannot be created as specified -<CODE>#f</CODE> is returned. For the fields and layout of descriptor tables, -<A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A> -</P> -</DL> -<P> - -<A NAME="IDX1036"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-system <B>open-database</B> <I>filename mutable?</I> -<DD><P> - -Returns an open relational database associated with <VAR>filename</VAR>. If -<VAR>mutable?</VAR> is <CODE>#t</CODE>, this database will have methods capable of -effecting change to the database. If <VAR>mutable?</VAR> is <CODE>#f</CODE>, only -methods for inquiring the database will be available. Calling the -<CODE>close-database</CODE> (and possibly other) method on a <VAR>mutable?</VAR> -database will cause <VAR>filename</VAR> to be written to. If the database -cannot be opened as specified <CODE>#f</CODE> is returned. -</P> -</DL> -<P> - -<A NAME="Database Operations"></A> -<HR SIZE="6"> -<A NAME="SEC177"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC176"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.2.4 Database Operations </H3> -<!--docid::SEC177::--> -<P> - -This object-oriented interface is deprecated for typical database -applications; <A HREF="slib_6.html#SEC142">6.1.1 Using Databases</A> provides an application programmer -interface which is easier to understand and use. -</P> -<P> - -These are the descriptions of the methods available from an open -relational database. A method is retrieved from a database by calling -the database with the symbol name of the operation. For example: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define my-database - (create-alist-database "mydata.db")) -(define telephone-table-desc - ((my-database 'create-table) 'telephone-table-desc)) -</pre></td></tr></table><P> - -<A NAME="IDX1037"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>close-database</B> -<DD>Causes the relational database to be written to its associated file (if -any). If the write is successful, subsequent operations to this -database will signal an error. If the operations completed -successfully, <CODE>#t</CODE> is returned. Otherwise, <CODE>#f</CODE> is returned. -</DL> -<P> - -<A NAME="IDX1038"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>write-database</B> <I>filename</I> -<DD>Causes the relational database to be written to <VAR>filename</VAR>. If the -write is successful, also causes the database to henceforth be -associated with <VAR>filename</VAR>. Calling the <CODE>close-database</CODE> (and -possibly other) method on this database will cause <VAR>filename</VAR> to be -written to. If <VAR>filename</VAR> is <CODE>#f</CODE> this database will be -changed to a temporary, non-disk based database if such can be supported -by the underlying base table implelentation. If the operations -completed successfully, <CODE>#t</CODE> is returned. Otherwise, <CODE>#f</CODE> is -returned. -</DL> -<P> - -<A NAME="IDX1039"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>sync-database</B> -<DD>Causes any pending updates to the database file to be written out. If -the operations completed successfully, <CODE>#t</CODE> is returned. -Otherwise, <CODE>#f</CODE> is returned. -</DL> -<P> - -<A NAME="IDX1040"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>solidify-database</B> -<DD>Causes any pending updates to the database file to be written out. If -the writes completed successfully, then the database is changed to be -immutable and <CODE>#t</CODE> is returned. Otherwise, <CODE>#f</CODE> is returned. -</DL> -<P> - -<A NAME="IDX1041"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>table-exists?</B> <I>table-name</I> -<DD>Returns <CODE>#t</CODE> if <VAR>table-name</VAR> exists in the system catalog, -otherwise returns <CODE>#f</CODE>. -</DL> -<P> - -<A NAME="IDX1042"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>open-table</B> <I>table-name mutable?</I> -<DD>Returns a <EM>methods</EM> procedure for an existing relational table in -this database if it exists and can be opened in the mode indicated by -<VAR>mutable?</VAR>, otherwise returns <CODE>#f</CODE>. -</DL> -<P> - -These methods will be present only in mutable databases. -</P> -<P> - -<A NAME="IDX1043"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>delete-table</B> <I>table-name</I> -<DD>Removes and returns the <VAR>table-name</VAR> row from the system catalog if -the table or view associated with <VAR>table-name</VAR> gets removed from the -database, and <CODE>#f</CODE> otherwise. -</DL> -<P> - -<A NAME="IDX1044"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>create-table</B> <I>table-desc-name</I> -<DD>Returns a methods procedure for a new (open) relational table for -describing the columns of a new base table in this database, otherwise -returns <CODE>#f</CODE>. For the fields and layout of descriptor tables, -See section <A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A>. -<P> - -<A NAME="IDX1045"></A> -<DT><U>Operation:</U> relational-database <B>create-table</B> <I>table-name table-desc-name</I> -<DD>Returns a methods procedure for a new (open) relational table with -columns as described by <VAR>table-desc-name</VAR>, otherwise returns -<CODE>#f</CODE>. -</P> -</DL> -<P> - -<A NAME="IDX1046"></A> -</P> -<DL> -<DT><U>Operation:</U> relational-database <B>create-view</B> <I>??</I> -<DD><A NAME="IDX1047"></A> -<DT><U>Operation:</U> relational-database <B>project-table</B> <I>??</I> -<DD><A NAME="IDX1048"></A> -<DT><U>Operation:</U> relational-database <B>restrict-table</B> <I>??</I> -<DD><A NAME="IDX1049"></A> -<DT><U>Operation:</U> relational-database <B>cart-prod-tables</B> <I>??</I> -<DD>Not yet implemented. -</DL> -<P> - -<A NAME="Weight-Balanced Trees"></A> -<HR SIZE="6"> -<A NAME="SEC178"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC177"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC179"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 6.3 Weight-Balanced Trees </H2> -<!--docid::SEC178::--> -<P> - -<CODE>(require 'wt-tree)</CODE> -<A NAME="IDX1050"></A> -</P> -<P> - -<A NAME="IDX1051"></A> -<A NAME="IDX1052"></A> -<A NAME="IDX1053"></A> -<A NAME="IDX1054"></A> -Balanced binary trees are a useful data structure for maintaining large -sets of ordered objects or sets of associations whose keys are ordered. -MIT Scheme has an comprehensive implementation of weight-balanced binary -trees which has several advantages over the other data structures for -large aggregates: -</P> -<P> - -<UL> -<LI> -In addition to the usual element-level operations like insertion, -deletion and lookup, there is a full complement of collection-level -operations, like set intersection, set union and subset test, all of -which are implemented with good orders of growth in time and space. -This makes weight balanced trees ideal for rapid prototyping of -functionally derived specifications. -<P> - -</P> -<LI> -An element in a tree may be indexed by its position under the ordering -of the keys, and the ordinal position of an element may be determined, -both with reasonable efficiency. -<P> - -</P> -<LI> -Operations to find and remove minimum element make weight balanced trees -simple to use for priority queues. -<P> - -</P> -<LI> -The implementation is <EM>functional</EM> rather than <EM>imperative</EM>. -This means that operations like `inserting' an association in a tree do -not destroy the old tree, in much the same way that <CODE>(+ 1 x)</CODE> -modifies neither the constant 1 nor the value bound to <CODE>x</CODE>. The -trees are referentially transparent thus the programmer need not worry -about copying the trees. Referential transparency allows space -efficiency to be achieved by sharing subtrees. -<P> - -</UL> -<P> - -These features make weight-balanced trees suitable for a wide range of -applications, especially those that -require large numbers of sets or discrete maps. Applications that have -a few global databases and/or concentrate on element-level operations like -insertion and lookup are probably better off using hash-tables or -red-black trees. -</P> -<P> - -The <EM>size</EM> of a tree is the number of associations that it -contains. Weight balanced binary trees are balanced to keep the sizes -of the subtrees of each node within a constant factor of each other. -This ensures logarithmic times for single-path operations (like lookup -and insertion). A weight balanced tree takes space that is proportional -to the number of associations in the tree. For the current -implementation, the constant of proportionality is six words per -association. -</P> -<P> - -<A NAME="IDX1055"></A> -<A NAME="IDX1056"></A> -<A NAME="IDX1057"></A> -<A NAME="IDX1058"></A> -Weight balanced trees can be used as an implementation for either -discrete sets or discrete maps (associations). Sets are implemented by -ignoring the datum that is associated with the key. Under this scheme -if an associations exists in the tree this indicates that the key of the -association is a member of the set. Typically a value such as -<CODE>()</CODE>, <CODE>#t</CODE> or <CODE>#f</CODE> is associated with the key. -</P> -<P> - -Many operations can be viewed as computing a result that, depending on -whether the tree arguments are thought of as sets or maps, is known by -two different names. An example is <CODE>wt-tree/member?</CODE>, which, when -regarding the tree argument as a set, computes the set membership -operation, but, when regarding the tree as a discrete map, -<CODE>wt-tree/member?</CODE> is the predicate testing if the map is defined at -an element in its domain. Most names in this package have been chosen -based on interpreting the trees as sets, hence the name -<CODE>wt-tree/member?</CODE> rather than <CODE>wt-tree/defined-at?</CODE>. -</P> -<P> - -<A NAME="IDX1059"></A> -<A NAME="IDX1060"></A> -The weight balanced tree implementation is a run-time-loadable option. -To use weight balanced trees, execute -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(load-option 'wt-tree) -</pre></td></tr></table><A NAME="IDX1061"></A> -<P> - -once before calling any of the procedures defined here. -</P> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC179">6.3.1 Construction of Weight-Balanced Trees</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC180">6.3.2 Basic Operations on Weight-Balanced Trees</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC181">6.3.3 Advanced Operations on Weight-Balanced Trees</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC182">6.3.4 Indexing Operations on Weight-Balanced Trees</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> -</TABLE> -<P> - -<A NAME="Construction of Weight-Balanced Trees"></A> -<HR SIZE="6"> -<A NAME="SEC179"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC180"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.3.1 Construction of Weight-Balanced Trees </H3> -<!--docid::SEC179::--> -<P> - -Binary trees require there to be a total order on the keys used to -arrange the elements in the tree. Weight balanced trees are organized -by <EM>types</EM>, where the type is an object encapsulating the ordering -relation. Creating a tree is a two-stage process. First a tree type -must be created from the predicate which gives the ordering. The tree -type is then used for making trees, either empty or singleton trees or -trees from other aggregate structures like association lists. Once -created, a tree `knows' its type and the type is used to test -compatibility between trees in operations taking two trees. Usually a -small number of tree types are created at the beginning of a program and -used many times throughout the program's execution. -</P> -<P> - -<A NAME="IDX1062"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>make-wt-tree-type</B> <I>key<?</I> -<DD>This procedure creates and returns a new tree type based on the ordering -predicate <VAR>key<?</VAR>. -<VAR>Key<?</VAR> must be a total ordering, having the property that for all -key values <CODE>a</CODE>, <CODE>b</CODE> and <CODE>c</CODE>: -<P> - -<TABLE><tr><td> </td><td class=example><pre>(key<? a a) => #f -(and (key<? a b) (key<? b a)) => #f -(if (and (key<? a b) (key<? b c)) - (key<? a c) - #t) => #t -</pre></td></tr></table><P> - -Two key values are assumed to be equal if neither is less than the other -by <VAR>key<?</VAR>. -</P> -<P> - -Each call to <CODE>make-wt-tree-type</CODE> returns a distinct value, and -trees are only compatible if their tree types are <CODE>eq?</CODE>. A -consequence is that trees that are intended to be used in binary tree -operations must all be created with a tree type originating from the -same call to <CODE>make-wt-tree-type</CODE>. -</P> -</DL> -<P> - -<A NAME="IDX1063"></A> -</P> -<DL> -<DT><U>variable+:</U> <B>number-wt-type</B> -<DD>A standard tree type for trees with numeric keys. <CODE>Number-wt-type</CODE> -could have been defined by -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define number-wt-type (make-wt-tree-type <)) -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX1064"></A> -</P> -<DL> -<DT><U>variable+:</U> <B>string-wt-type</B> -<DD>A standard tree type for trees with string keys. <CODE>String-wt-type</CODE> -could have been defined by -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define string-wt-type (make-wt-tree-type string<?)) -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX1065"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>make-wt-tree</B> <I>wt-tree-type</I> -<DD>This procedure creates and returns a newly allocated weight balanced -tree. The tree is empty, i.e. it contains no associations. -<VAR>Wt-tree-type</VAR> is a weight balanced tree type obtained by calling -<CODE>make-wt-tree-type</CODE>; the returned tree has this type. -</DL> -<P> - -<A NAME="IDX1066"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>singleton-wt-tree</B> <I>wt-tree-type key datum</I> -<DD>This procedure creates and returns a newly allocated weight balanced -tree. The tree contains a single association, that of <VAR>datum</VAR> with -<VAR>key</VAR>. <VAR>Wt-tree-type</VAR> is a weight balanced tree type obtained -by calling <CODE>make-wt-tree-type</CODE>; the returned tree has this type. -</DL> -<P> - -<A NAME="IDX1067"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>alist->wt-tree</B> <I>tree-type alist</I> -<DD>Returns a newly allocated weight-balanced tree that contains the same -associations as <VAR>alist</VAR>. This procedure is equivalent to: -<P> - -<TABLE><tr><td> </td><td class=example><pre>(lambda (type alist) - (let ((tree (make-wt-tree type))) - (for-each (lambda (association) - (wt-tree/add! tree - (car association) - (cdr association))) - alist) - tree)) -</pre></td></tr></table></DL> -<P> - -<A NAME="Basic Operations on Weight-Balanced Trees"></A> -<HR SIZE="6"> -<A NAME="SEC180"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC179"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC181"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.3.2 Basic Operations on Weight-Balanced Trees </H3> -<!--docid::SEC180::--> -<P> - -This section describes the basic tree operations on weight balanced -trees. These operations are the usual tree operations for insertion, -deletion and lookup, some predicates and a procedure for determining the -number of associations in a tree. -</P> -<P> - -<A NAME="IDX1068"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/empty?</B> <I>wt-tree</I> -<DD>Returns <CODE>#t</CODE> if <VAR>wt-tree</VAR> contains no associations, otherwise -returns <CODE>#f</CODE>. -</DL> -<P> - -<A NAME="IDX1069"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/size</B> <I>wt-tree</I> -<DD>Returns the number of associations in <VAR>wt-tree</VAR>, an exact -non-negative integer. This operation takes constant time. -</DL> -<P> - -<A NAME="IDX1070"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/add</B> <I>wt-tree key datum</I> -<DD>Returns a new tree containing all the associations in <VAR>wt-tree</VAR> and -the association of <VAR>datum</VAR> with <VAR>key</VAR>. If <VAR>wt-tree</VAR> already -had an association for <VAR>key</VAR>, the new association overrides the old. -The average and worst-case times required by this operation are -proportional to the logarithm of the number of associations in -<VAR>wt-tree</VAR>. -</DL> -<P> - -<A NAME="IDX1071"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/add!</B> <I>wt-tree key datum</I> -<DD>Associates <VAR>datum</VAR> with <VAR>key</VAR> in <VAR>wt-tree</VAR> and returns an -unspecified value. If <VAR>wt-tree</VAR> already has an association for -<VAR>key</VAR>, that association is replaced. The average and worst-case -times required by this operation are proportional to the logarithm of -the number of associations in <VAR>wt-tree</VAR>. -</DL> -<P> - -<A NAME="IDX1072"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/member?</B> <I>key wt-tree</I> -<DD>Returns <CODE>#t</CODE> if <VAR>wt-tree</VAR> contains an association for -<VAR>key</VAR>, otherwise returns <CODE>#f</CODE>. The average and worst-case -times required by this operation are proportional to the logarithm of -the number of associations in <VAR>wt-tree</VAR>. -</DL> -<P> - -<A NAME="IDX1073"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/lookup</B> <I>wt-tree key default</I> -<DD>Returns the datum associated with <VAR>key</VAR> in <VAR>wt-tree</VAR>. If -<VAR>wt-tree</VAR> doesn't contain an association for <VAR>key</VAR>, -<VAR>default</VAR> is returned. The average and worst-case times required by -this operation are proportional to the logarithm of the number of -associations in <VAR>wt-tree</VAR>. -</DL> -<P> - -<A NAME="IDX1074"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/delete</B> <I>wt-tree key</I> -<DD>Returns a new tree containing all the associations in <VAR>wt-tree</VAR>, -except that if <VAR>wt-tree</VAR> contains an association for <VAR>key</VAR>, it -is removed from the result. The average and worst-case times required -by this operation are proportional to the logarithm of the number of -associations in <VAR>wt-tree</VAR>. -</DL> -<P> - -<A NAME="IDX1075"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/delete!</B> <I>wt-tree key</I> -<DD>If <VAR>wt-tree</VAR> contains an association for <VAR>key</VAR> the association -is removed. Returns an unspecified value. The average and worst-case -times required by this operation are proportional to the logarithm of -the number of associations in <VAR>wt-tree</VAR>. -</DL> -<P> - -<A NAME="Advanced Operations on Weight-Balanced Trees"></A> -<HR SIZE="6"> -<A NAME="SEC181"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC180"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC182"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.3.3 Advanced Operations on Weight-Balanced Trees </H3> -<!--docid::SEC181::--> -<P> - -In the following the <EM>size</EM> of a tree is the number of associations -that the tree contains, and a <EM>smaller</EM> tree contains fewer -associations. -</P> -<P> - -<A NAME="IDX1076"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/split<</B> <I>wt-tree bound</I> -<DD>Returns a new tree containing all and only the associations in -<VAR>wt-tree</VAR> which have a key that is less than <VAR>bound</VAR> in the -ordering relation of the tree type of <VAR>wt-tree</VAR>. The average and -worst-case times required by this operation are proportional to the -logarithm of the size of <VAR>wt-tree</VAR>. -</DL> -<P> - -<A NAME="IDX1077"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/split></B> <I>wt-tree bound</I> -<DD>Returns a new tree containing all and only the associations in -<VAR>wt-tree</VAR> which have a key that is greater than <VAR>bound</VAR> in the -ordering relation of the tree type of <VAR>wt-tree</VAR>. The average and -worst-case times required by this operation are proportional to the -logarithm of size of <VAR>wt-tree</VAR>. -</DL> -<P> - -<A NAME="IDX1078"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/union</B> <I>wt-tree-1 wt-tree-2</I> -<DD>Returns a new tree containing all the associations from both trees. -This operation is asymmetric: when both trees have an association for -the same key, the returned tree associates the datum from <VAR>wt-tree-2</VAR> -with the key. Thus if the trees are viewed as discrete maps then -<CODE>wt-tree/union</CODE> computes the map override of <VAR>wt-tree-1</VAR> by -<VAR>wt-tree-2</VAR>. If the trees are viewed as sets the result is the set -union of the arguments. -The worst-case time required by this operation -is proportional to the sum of the sizes of both trees. -If the minimum key of one tree is greater than the maximum key of -the other tree then the time required is at worst proportional to -the logarithm of the size of the larger tree. -</DL> -<P> - -<A NAME="IDX1079"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/intersection</B> <I>wt-tree-1 wt-tree-2</I> -<DD>Returns a new tree containing all and only those associations from -<VAR>wt-tree-1</VAR> which have keys appearing as the key of an association -in <VAR>wt-tree-2</VAR>. Thus the associated data in the result are those -from <VAR>wt-tree-1</VAR>. If the trees are being used as sets the result is -the set intersection of the arguments. As a discrete map operation, -<CODE>wt-tree/intersection</CODE> computes the domain restriction of -<VAR>wt-tree-1</VAR> to (the domain of) <VAR>wt-tree-2</VAR>. -The time required by this operation is never worse that proportional to -the sum of the sizes of the trees. -</DL> -<P> - -<A NAME="IDX1080"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/difference</B> <I>wt-tree-1 wt-tree-2</I> -<DD>Returns a new tree containing all and only those associations from -<VAR>wt-tree-1</VAR> which have keys that <EM>do not</EM> appear as the key of -an association in <VAR>wt-tree-2</VAR>. If the trees are viewed as sets the -result is the asymmetric set difference of the arguments. As a discrete -map operation, it computes the domain restriction of <VAR>wt-tree-1</VAR> to -the complement of (the domain of) <VAR>wt-tree-2</VAR>. -The time required by this operation is never worse that proportional to -the sum of the sizes of the trees. -</DL> -<P> - -<A NAME="IDX1081"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/subset?</B> <I>wt-tree-1 wt-tree-2</I> -<DD>Returns <CODE>#t</CODE> iff the key of each association in <VAR>wt-tree-1</VAR> is -the key of some association in <VAR>wt-tree-2</VAR>, otherwise returns <CODE>#f</CODE>. -Viewed as a set operation, <CODE>wt-tree/subset?</CODE> is the improper subset -predicate. -A proper subset predicate can be constructed: -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define (proper-subset? s1 s2) - (and (wt-tree/subset? s1 s2) - (< (wt-tree/size s1) (wt-tree/size s2)))) -</pre></td></tr></table><P> - -As a discrete map operation, <CODE>wt-tree/subset?</CODE> is the subset -test on the domain(s) of the map(s). In the worst-case the time -required by this operation is proportional to the size of -<VAR>wt-tree-1</VAR>. -</P> -</DL> -<P> - -<A NAME="IDX1082"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/set-equal?</B> <I>wt-tree-1 wt-tree-2</I> -<DD>Returns <CODE>#t</CODE> iff for every association in <VAR>wt-tree-1</VAR> there is -an association in <VAR>wt-tree-2</VAR> that has the same key, and <EM>vice -versa</EM>. -<P> - -Viewing the arguments as sets <CODE>wt-tree/set-equal?</CODE> is the set -equality predicate. As a map operation it determines if two maps are -defined on the same domain. -</P> -<P> - -This procedure is equivalent to -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(lambda (wt-tree-1 wt-tree-2) - (and (wt-tree/subset? wt-tree-1 wt-tree-2 - (wt-tree/subset? wt-tree-2 wt-tree-1))) -</pre></td></tr></table><P> - -In the worst-case the time required by this operation is proportional to -the size of the smaller tree. -</P> -</DL> -<P> - -<A NAME="IDX1083"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/fold</B> <I>combiner initial wt-tree</I> -<DD>This procedure reduces <VAR>wt-tree</VAR> by combining all the associations, -using an reverse in-order traversal, so the associations are visited in -reverse order. <VAR>Combiner</VAR> is a procedure of three arguments: a key, -a datum and the accumulated result so far. Provided <VAR>combiner</VAR> -takes time bounded by a constant, <CODE>wt-tree/fold</CODE> takes time -proportional to the size of <VAR>wt-tree</VAR>. -<P> - -A sorted association list can be derived simply: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(wt-tree/fold (lambda (key datum list) - (cons (cons key datum) list)) - '() - <VAR>wt-tree</VAR>)) -</pre></td></tr></table><P> - -The data in the associations can be summed like this: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(wt-tree/fold (lambda (key datum sum) (+ sum datum)) - 0 - <VAR>wt-tree</VAR>) -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX1084"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/for-each</B> <I>action wt-tree</I> -<DD>This procedure traverses the tree in-order, applying <VAR>action</VAR> to -each association. -The associations are processed in increasing order of their keys. -<VAR>Action</VAR> is a procedure of two arguments which take the key and -datum respectively of the association. -Provided <VAR>action</VAR> takes time bounded by a constant, -<CODE>wt-tree/for-each</CODE> takes time proportional to in the size of -<VAR>wt-tree</VAR>. -The example prints the tree: -<P> - -<TABLE><tr><td> </td><td class=example><pre>(wt-tree/for-each (lambda (key value) - (display (list key value))) - <VAR>wt-tree</VAR>)) -</pre></td></tr></table></DL> -<P> - -<A NAME="Indexing Operations on Weight-Balanced Trees"></A> -<HR SIZE="6"> -<A NAME="SEC182"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC181"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 6.3.4 Indexing Operations on Weight-Balanced Trees </H3> -<!--docid::SEC182::--> -<P> - -Weight balanced trees support operations that view the tree as sorted -sequence of associations. Elements of the sequence can be accessed by -position, and the position of an element in the sequence can be -determined, both in logarthmic time. -</P> -<P> - -<A NAME="IDX1085"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/index</B> <I>wt-tree index</I> -<DD><A NAME="IDX1086"></A> -<DT><U>procedure+:</U> <B>wt-tree/index-datum</B> <I>wt-tree index</I> -<DD><A NAME="IDX1087"></A> -<DT><U>procedure+:</U> <B>wt-tree/index-pair</B> <I>wt-tree index</I> -<DD>Returns the 0-based <VAR>index</VAR>th association of <VAR>wt-tree</VAR> in the -sorted sequence under the tree's ordering relation on the keys. -<CODE>wt-tree/index</CODE> returns the <VAR>index</VAR>th key, -<CODE>wt-tree/index-datum</CODE> returns the datum associated with the -<VAR>index</VAR>th key and <CODE>wt-tree/index-pair</CODE> returns a new pair -<CODE>(<VAR>key</VAR> . <VAR>datum</VAR>)</CODE> which is the <CODE>cons</CODE> of the -<VAR>index</VAR>th key and its datum. The average and worst-case times -required by this operation are proportional to the logarithm of the -number of associations in the tree. -<P> - -These operations signal an error if the tree is empty, if -<VAR>index</VAR><CODE><0</CODE>, or if <VAR>index</VAR> is greater than or equal to the -number of associations in the tree. -</P> -<P> - -Indexing can be used to find the median and maximum keys in the tree as -follows: -</P> -</DL> -<P> - -<TABLE><tr><td> </td><td class=example><pre>median: (wt-tree/index <VAR>wt-tree</VAR> (quotient (wt-tree/size <VAR>wt-tree</VAR>) 2)) - -maximum: (wt-tree/index <VAR>wt-tree</VAR> (-1+ (wt-tree/size <VAR>wt-tree</VAR>))) -</pre></td></tr></table><P> - -<A NAME="IDX1088"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/rank</B> <I>wt-tree key</I> -<DD>Determines the 0-based position of <VAR>key</VAR> in the sorted sequence of -the keys under the tree's ordering relation, or <CODE>#f</CODE> if the tree -has no association with for <VAR>key</VAR>. This procedure returns either an -exact non-negative integer or <CODE>#f</CODE>. The average and worst-case -times required by this operation are proportional to the logarithm of -the number of associations in the tree. -</DL> -<P> - -<A NAME="IDX1089"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/min</B> <I>wt-tree</I> -<DD><A NAME="IDX1090"></A> -<DT><U>procedure+:</U> <B>wt-tree/min-datum</B> <I>wt-tree</I> -<DD><A NAME="IDX1091"></A> -<DT><U>procedure+:</U> <B>wt-tree/min-pair</B> <I>wt-tree</I> -<DD>Returns the association of <VAR>wt-tree</VAR> that has the least key under -the tree's ordering relation. <CODE>wt-tree/min</CODE> returns the least key, -<CODE>wt-tree/min-datum</CODE> returns the datum associated with the least key -and <CODE>wt-tree/min-pair</CODE> returns a new pair <CODE>(key . datum)</CODE> -which is the <CODE>cons</CODE> of the minimum key and its datum. The average -and worst-case times required by this operation are proportional to the -logarithm of the number of associations in the tree. -<P> - -These operations signal an error if the tree is empty. -They could be written -<TABLE><tr><td> </td><td class=example><pre>(define (wt-tree/min tree) (wt-tree/index tree 0)) -(define (wt-tree/min-datum tree) (wt-tree/index-datum tree 0)) -(define (wt-tree/min-pair tree) (wt-tree/index-pair tree 0)) -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX1092"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/delete-min</B> <I>wt-tree</I> -<DD>Returns a new tree containing all of the associations in <VAR>wt-tree</VAR> -except the association with the least key under the <VAR>wt-tree</VAR>'s -ordering relation. An error is signalled if the tree is empty. The -average and worst-case times required by this operation are proportional -to the logarithm of the number of associations in the tree. This -operation is equivalent to -<P> - -<TABLE><tr><td> </td><td class=example><pre>(wt-tree/delete <VAR>wt-tree</VAR> (wt-tree/min <VAR>wt-tree</VAR>)) -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX1093"></A> -</P> -<DL> -<DT><U>procedure+:</U> <B>wt-tree/delete-min!</B> <I>wt-tree</I> -<DD>Removes the association with the least key under the <VAR>wt-tree</VAR>'s -ordering relation. An error is signalled if the tree is empty. The -average and worst-case times required by this operation are proportional -to the logarithm of the number of associations in the tree. This -operation is equivalent to -<P> - -<TABLE><tr><td> </td><td class=example><pre>(wt-tree/delete! <VAR>wt-tree</VAR> (wt-tree/min <VAR>wt-tree</VAR>)) -</pre></td></tr></table></DL> -<P> - -<A NAME="Other Packages"></A> -<HR SIZE="6"> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<BR> -<FONT SIZE="-1"> -This document was generated -by <I>Steve Langasek</I> on <I>January, 10 2005</I> -using <A HREF="http://texi2html.cvshome.org"><I>texi2html</I></A> -</FONT> - -</BODY> -</HTML> |