Next: Relational Infrastructure, Previous: Database Packages, Up: Database Packages [Contents][Index]
(require 'relational-database)
This package implements a database system inspired by the Relational Model (E. F. Codd, A Relational Model of Data for Large Shared Data Banks). An SLIB relational database implementation can be created from any Base Table implementation.
Why relational database? For motivations and design issues see
http://people.csail.mit.edu/jaffer/DBManifesto.html.
Next: Table Operations, Previous: Relational Database, Up: Relational Database [Contents][Index]
(require 'databases)
This enhancement wraps a utility layer on relational-database
which provides:
Auto-sharing refers to a call to the procedure
open-database
returning an already open database (procedure),
rather than opening the database file a second time.
Note: Databases returned by
open-database
do not include wrappers applied by packages like Embedded Commands. But wrapped databases do work as arguments to these functions.
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.
This next set of procedures mirror the whole-database methods in
Database Operations. Except for create-database
, each
procedure will accept either a filename or database procedure for its
first argument.
filename should be a string naming a file; or #f
. base-table-type must be a
symbol naming a feature which can be passed to require
. create-database
returns a new, open relational database (with base-table type base-table-type)
associated with filename, or a new ephemeral database if filename is #f
.
create-database
is the only run-time use of require in SLIB
which crosses module boundaries. When base-table-type is require
d by create-database
; it
adds an association of base-table-type with its relational-system procedure
to mdbm:*databases*.
alist-table is the default base-table type:
(require 'databases) (define my-rdb (create-database "my.db" 'alist-table))
Only alist-table
and base-table modules which have been
require
d will dispatch correctly from the
open-database
procedures. Therefore, either pass two
arguments to open-database
, or require the base-table of your
database file uses before calling open-database
with one
argument.
Returns mutable open relational database or #f.
Returns an open relational database associated with rdb. The database will be opened with base-table type base-table-type).
Returns an open relational database associated with rdb.
open-database
will attempt to deduce the correct base-table-type.
Writes the mutable relational-database rdb to filename.
Writes the mutable relational-database rdb to the filename it was opened with.
Syncs rdb and makes it immutable.
rdb will only be closed when the count of open-database
- close-database
calls for rdb (and its filename) is 0. close-database
returns #t if successful;
and #f otherwise.
Prints a table of open database files. The columns are the base-table type, number of opens, ‘!’ for mutable, the filename, and the lock certificate (if locked).
(mdbm:report) -| alist-table 003 /usr/local/lib/slib/clrnamdb.scm alist-table 001 ! sdram.db jaffer@aubrey.jaffer.3166:1038628199
rdb must be a relational database and table-name a symbol.
open-table
returns a "methods" procedure for an existing relational table in
rdb if it exists and can be opened for reading, otherwise returns
#f
.
rdb must be a relational database and table-name a symbol.
open-table!
returns a "methods" procedure for an existing relational table in
rdb if it exists and can be opened in mutable mode, otherwise returns
#f
.
Adds the domain rows row5 … to the ‘*domains-data*’ table in rdb. The format of the row is given in Catalog Representation.
(define-domains rdb '(permittivity #f complex? c64 #f))
Use define-domains
instead.
Adds tables as specified in spec-0 … to the open relational-database rdb. Each spec has the form:
(<name> <descriptor-name> <descriptor-name> <rows>)
or
(<name> <primary-key-fields> <other-fields> <rows>)
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.
<primary-key-fields> and <other-fields> are lists of field descriptors of the form:
(<column-name> <domain>)
or
(<column-name> <domain> <column-integrity-rule>)
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 #f
to signal
an error).
If <domain> is not a defined domain name and it matches the name of this table or an already defined (in one of spec-0 …) single key field table, a foreign-key domain will be created for it.
If symbol table-name exists in the open relational-database rdb, 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.
The list returned by list-table-definition
, when passed as an
argument to define-tables
, will recreate the table.
Next: Database Interpolation, Previous: Using Databases, Up: Relational Database [Contents][Index]
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:
((plat 'get 'processor) 'djgpp) ⇒ i386
Some operations described below require primary key arguments. Primary keys arguments are denoted key1 key2 …. 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.
Returns a procedure of arguments key1 key2 … which
returns the value for the column-name column of the row associated
with primary keys key1, key2 … if that row exists in
the table, or #f
otherwise.
((plat 'get 'processor) 'djgpp) ⇒ i386 ((plat 'get 'processor) 'be-os) ⇒ #f
Next: Match-Keys, Previous: Table Operations, Up: Table Operations [Contents][Index]
The term row 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 #f
. Primary keys must not
be missing.
Adds the row row to this table. If a row for the primary key(s) specified by row already exists in this table an error is signaled. The value returned is unspecified.
(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 #\+ #\( #\space #\) #\-))) (string->list d)))) string))
Returns a procedure of one argument, row, which adds the row, row, to this table. If a row for the primary key(s) specified by row already exists in this table, it will be overwritten. The value returned is unspecified.
Returns a procedure of arguments key1 key2 … which
returns the row associated with primary keys key1, key2
… if it exists, or #f
otherwise.
((plat 'row:retrieve) 'linux) ⇒ (linux i386 linux gcc) ((plat 'row:retrieve) 'multics) ⇒ #f
Returns a procedure of arguments key1 key2 … which
removes and returns the row associated with primary keys key1,
key2 … if it exists, or #f
otherwise.
Returns a procedure of arguments key1 key2 … which deletes the row associated with primary keys key1, key2 … if it exists. The value returned is unspecified.
Next: Multi-Row Operations, Previous: Single Row Operations, Up: Table Operations [Contents][Index]
The (optional) match-key1 … 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 match-key arguments
default to #f
.
The match-key1 … restrict the actions of the table command to those records whose primary keys each satisfy the corresponding match-key argument. The arguments and their actions are:
#f
The false value matches any key in the corresponding position.
- an object of type procedure
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
#f
is not.- other values
Any other value matches only those keys
equal?
to it.
Returns a procedure of optional arguments match-key1 … which returns a list of the values for the specified column for all rows in this table. The optional match-key1 … arguments restrict actions to a subset of the table.
((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)
Next: Indexed Sequential Access Methods, Previous: Match-Keys, Up: Table Operations [Contents][Index]
Returns a procedure of optional arguments match-key1 … which returns a list of all rows in this table. The optional match-key1 … arguments restrict actions to a subset of the table. For details see See Match-Keys.
((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 -))
Returns a procedure of optional arguments match-key1 … which removes and returns a list of all rows in this table. The optional match-key1 … arguments restrict actions to a subset of the table.
Returns a procedure of optional arguments match-key1 … which Deletes all rows from this table. The optional match-key1 … 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.
Returns a procedure of arguments proc match-key1 … which calls proc with each row in this table. The optional match-key1 … arguments restrict actions to a subset of the table. For details see See Match-Keys.
Note that row:insert*
and row:update*
do not use
match-keys.
Returns a procedure of one argument, rows, which adds each row in the list of rows, rows, to this table. If a row for the primary key specified by an element of rows already exists in this table, an error is signaled. The value returned is unspecified.
Returns a procedure of one argument, rows, which adds each row in the list of rows, rows, to this table. If a row for the primary key specified by an element of rows already exists in this table, it will be overwritten. The value returned is unspecified.
Next: Sequential Index Operations, Previous: Multi-Row Operations, Up: Table Operations [Contents][Index]
Indexed Sequential Access Methods are a way of arranging database information so that records can be accessed both by key and by key sequence (ordering). ISAM is not part of Codd’s relational model.
Associative memory in B-Trees is an example of a database
implementation which can support a native key ordering. SLIB’s
alist-table
implementation uses sort
to implement
for-each-row-in-order
, but does not support isam-next
and isam-prev
.
The multi-primary-key ordering employed by these operations is the lexicographic collation of those primary-key fields in their given order. For example:
(12 a 34) < (12 a 36) < (12 b 1) < (13 a 0)
Next: Table Administration, Previous: Indexed Sequential Access Methods, Up: Table Operations [Contents][Index]
The following procedures are individually optional depending on the base-table implememtation. If an operation is not supported, then calling the table with that operation symbol will return false.
Returns a procedure of arguments proc match-key1 … which calls proc with each row in this table in the (implementation-dependent) natural, repeatable ordering for rows. The optional match-key1 … arguments restrict actions to a subset of the table. For details see See Match-Keys.
Returns a procedure of arguments key1 key2 … which returns the key-list identifying the lowest record higher than key1 key2 … which is stored in the relational-table; or false if no higher record is present.
The symbol column-name names a key field. In the list returned
by isam-next
, that field, or a field to its left, will be
changed. This allows one to skip over less significant key fields.
Returns a procedure of arguments key1 key2 … which returns the key-list identifying the highest record less than key1 key2 … which is stored in the relational-table; or false if no lower record is present.
The symbol column-name names a key field. In the list returned
by isam-next
, that field, or a field to its left, will be
changed. This allows one to skip over less significant key fields.
For example, if a table has key fields:
(col1 col2) (9 5) (9 6) (9 7) (9 8) (12 5) (12 6) (12 7)
Then:
((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)
Previous: Sequential Index Operations, Up: Table Operations [Contents][Index]
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.
Returns the number of primary keys fields in the relations in this table.
Subsequent operations to this table will signal an error.
Next: Embedded Commands, Previous: Table Operations, Up: Relational Database [Contents][Index]
(require 'database-interpolate)
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.
Table should be a relational table with one numeric primary key
field which supports the isam-prev
and isam-next
operations. column should be a symbol or exact positive integer
designating a numerically valued column of table.
interpolate-from-table
calculates and returns a value
proportionally intermediate between its values in the next and
previous key records contained in table. 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.
Next: Database Macros, Previous: Database Interpolation, Up: Relational Database [Contents][Index]
(require 'database-commands)
This enhancement wraps a utility layer on relational-database
which provides:
*commands*
table in database.
When an enhanced relational-database is called with a symbol which
matches a name in the *commands*
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.
The command *initialize*
is special. If present in the
*commands*
table, open-database
or open-database!
will return the value of the *initialize*
command. Notice that
arbitrary code can be run when the *initialize*
procedure is
automatically applied to the enhanced relational-database.
Note also that if you wish to shadow or hide from the user
relational-database methods described in Database Operations, this
can be done by a dispatch in the closure returned by the
*initialize*
expression rather than by entries in the
*commands*
table if it is desired that the underlying methods
remain accessible to code in the *commands*
table.
Next: Command Intrinsics, Previous: Embedded Commands, Up: Embedded Commands [Contents][Index]
Returns relational database rdb wrapped with additional commands defined in its *commands* table.
The relational database rdb must be mutable.
add-command-tables adds a *command* table to rdb; then
returns (wrap-command-interface rdb)
.
Adds commands to the *commands*
table as specified in
spec-0 … to the open relational-database rdb. Each
spec has the form:
((<name> <rdb>) "comment" <expression1> <expression2> …)
or
((<name> <rdb>) <expression1> <expression2> …)
where <name> is the command name, <rdb> is a formal passed the calling relational database, "comment" describes the command, and <expression1>, <expression1>, … are the body of the procedure.
define-*commands*
adds to the *commands*
table a command
<name>:
(lambda (<name> <rdb>) <expression1> <expression2> …)
Returns an open enhanced relational database associated with
filename. The database will be opened with base-table type
base-table-type) if supplied. If base-table-type is not
supplied, open-command-database
will attempt to deduce the correct
base-table-type. If the database can not be opened or if it lacks the
*commands*
table, #f
is returned.
Returns mutable open enhanced relational database …
Returns database if it is an immutable relational database; #f otherwise.
Returns database if it is a mutable relational database; #f otherwise.
Next: Define-tables Example, Previous: Database Extension, Up: Embedded Commands [Contents][Index]
Some commands are defined in all extended relational-databases. The are called just like Database Operations.
Adds domain-row to the domains table if there is no row in
the domains table associated with key (car domain-row)
and
returns #t
. Otherwise returns #f
.
For the fields and layout of the domain table, See Catalog Representation. Currently, these fields are
The following example adds 3 domains to the ‘build’ database.
‘Optstring’ is either a string or #f
. filename
is a
string and build-whats
is a symbol.
(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)))
Removes and returns the domain-name row from the domains table.
Returns a procedure to check an argument for conformance to domain domain.
Next: The *commands* Table, Previous: Command Intrinsics, Up: Embedded Commands [Contents][Index]
The following example shows a new database with the name of foo.db being created with tables describing processor families and processor/os/compiler combinations. The database is then solidified; saved and changed to immutable.
(require 'databases) (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)
Next: Command Service, Previous: Define-tables Example, Up: Embedded Commands [Contents][Index]
The table *commands*
in an enhanced relational-database has
the fields (with domains):
PRI name symbol parameters parameter-list procedure expression documentation string
The parameters
field is a foreign key (domain
parameter-list
) of the *catalog-data*
table and should
have the value of a table described by *parameter-columns*
. This
parameter-list
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
parameter-list
table has the following fields:
PRI index ordinal name symbol arity parameter-arity domain domain defaulter expression expander expression documentation string
The arity
field can take the values:
single
Requires a single parameter of the specified domain.
optional
A single parameter of the specified domain or zero parameters is acceptable.
boolean
A single boolean parameter or zero parameters (in which case #f
is substituted) is acceptable.
nary
Any number of parameters of the specified domain are acceptable. The argument passed to the command function is always a list of the parameters.
nary1
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.
The domain
field specifies the domain which a parameter or
parameters in the index
th field must satisfy.
The defaulter
field is an expression whose value is either
#f
or a procedure of one argument (the parameter-list) which
returns a list of the default value or values as appropriate.
Note that since the defaulter
procedure is called every time a
default parameter is needed for this column, sticky defaults can
be implemented using shared state with the domain-integrity-rule.
Next: Command Example, Previous: The *commands* Table, Up: Embedded Commands [Contents][Index]
Returns a procedure of 2 arguments, a (symbol) command and a call-back procedure. When this returned procedure is called, it looks up command in table table-name and calls the call-back procedure with arguments:
The command
The result of evaluating the expression in the procedure field of table-name and calling it with rdb.
A list of the official name of each parameter. Corresponds to the
name
field of the command’s parameter-table.
A list of the positive integer index of each parameter. Corresponds to
the index
field of the command’s parameter-table.
A list of the arities of each parameter. Corresponds to the
arity
field of the command’s parameter-table. For a
description of arity
see table above.
A list of the type name of each parameter. Correspnds to the
type-id
field of the contents of the domain
of the
command’s parameter-table.
A list of the defaulters for each parameter. Corresponds to
the defaulters
field of the command’s parameter-table.
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 nary
arity
parameters.
A list of lists of (alias parameter-name)
. There can be
more than one alias per parameter-name.
For information about parameters, See Parameter lists.
Previous: Command Service, Up: Embedded Commands [Contents][Index]
Here is an example of setting up a command with arguments and parsing
those arguments from a getopt
style argument list
(see Getopt).
(require 'database-commands) (require 'databases) (require 'getopt-parameters) (require 'parameters) (require 'getopt) (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" "-?"
Next: Database Browser, Previous: Embedded Commands, Up: Relational Database [Contents][Index]
(require 'within-database)
The object-oriented programming interface to SLIB relational databases has failed to support clear, understandable, and modular code-writing for database applications.
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.
within-database
, along with the ‘databases’ package,
reorganizes high-level database functions toward a more declarative
style. Using this package, one can tag database table and command
declarations for emacs:
etags -lscheme -r'/ *(define-\(command\|table\) (\([^; \t]+\)/\2/' \ source1.scm ...
Next: Within-database Example, Previous: Database Macros, Up: Database Macros [Contents][Index]
within-database
creates a lexical scope in which the commands
define-table
and define-command
create tables and
*commands*
-table entries respectively in open relational
database database. The expressions in ‘within-database’ form
are executed in order.
within-database
Returns database.
Adds to the *commands*
table a command
<name>:
(lambda (<name> <rdb>) <expression1> <expression2> …)
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.
<primary-key-fields> and <other-fields> are lists of field descriptors of the form:
(<column-name> <domain>)
or
(<column-name> <domain> <column-integrity-rule>)
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 #f
to signal
an error).
If <domain> is not a defined domain name and it matches the name of this table or an already defined (in one of spec-0 …) single key field table, a foreign-key domain will be created for it.
The relational database database must be mutable.
add-macro-support
adds a *macros*
table and
define-macro
macro to database; then database is
returned.
Adds a macro <name> to the *macros*
.
Note: within-database
creates lexical scope where not
only define-command
and define-table
, but every command
and macro are defined, ie.:
(within-database my-rdb (define-command (message rdb) (lambda (msg) (display "message: ") (display msg) (newline))) (message "Defining FOO...") ;; ... defining FOO ... (message "Defining BAR...") ;; ... defining BAR ... )
Previous: Within-database, Up: Database Macros [Contents][Index]
Here is an example of within-database
macros:
(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)
Previous: Database Macros, Up: Relational Database [Contents][Index]
(require ’database-browse)
Prints the names of all the tables in database and sets browse’s default to database.
Prints the names of all the tables in the default database.
For each record of the table named by the symbol table-name, prints a line composed of all the field values.
Opens the database named by the string pathname, prints the names of all its tables, and sets browse’s default to the database.
Sets browse’s default to database and prints the records of the table named by the symbol table-name.
Opens the database named by the string pathname and sets browse’s
default to it; browse
prints the records of the table named by
the symbol table-name.
Next: Relational Infrastructure, Previous: Database Packages, Up: Database Packages [Contents][Index]