@code{(require 'databases)}
@ftindex databases
@noindent
This enhancement wraps a utility layer on @code{relational-database}
which provides:
@itemize @bullet
@item
Identification of open databases by filename.
@item
Automatic sharing of open (immutable) databases.
@item
Automatic loading of base-table package when creating a database.
@item
Detection and automatic loading of the appropriate base-table package
when opening a database.
@item
Table and data definition from Scheme lists.
@end itemize
@subsubheading Database Sharing
@noindent
@dfn{Auto-sharing} refers to a call to the procedure
@cindex Auto-sharing
@code{open-database} returning an already open database (procedure),
rather than opening the database file a second time.
@quotation
@emph{Note:} Databases returned by @code{open-database} do not include
wrappers applied by packages like @ref{Embedded Commands}. But
wrapped databases do work as arguments to these functions.
@end quotation
@noindent
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.
@noindent
This next set of procedures mirror the whole-database methods in
@ref{Database Operations}. Except for @code{create-database}, each
procedure will accept either a filename or database procedure for its
first argument.
@defun create-database filename base-table-type
@var{filename} should be a string naming a file; or @code{#f}. @var{base-table-type} must be a
symbol naming a feature which can be passed to @code{require}. @code{create-database}
returns a new, open relational database (with base-table type @var{base-table-type})
associated with @var{filename}, or a new ephemeral database if @var{filename} is @code{#f}.
@code{create-database} is the only run-time use of require in SLIB
which crosses module boundaries. When @var{base-table-type} is @code{require}d by @code{create-database}; it
adds an association of @var{base-table-type} with its @dfn{relational-system} procedure
@cindex relational-system
to @var{mdbm:*databases*}.
alist-table is the default base-table type:
@example
(require 'databases)
(define my-rdb (create-database "my.db" 'alist-table))
@end example
@end defun
@noindent
Only @code{alist-table} and base-table modules which have been
@code{require}d will dispatch correctly from the
@code{open-database} procedures. Therefore, either pass two
arguments to @code{open-database}, or require the base-table of your
database file uses before calling @code{open-database} with one
argument.
@deffn {Procedure} open-database! rdb base-table-type
Returns @emph{mutable} open relational database or #f.
@end deffn
@defun open-database rdb base-table-type
Returns an open relational database associated with @var{rdb}. The
database will be opened with base-table type @var{base-table-type}).
@end defun
@defun open-database rdb
Returns an open relational database associated with @var{rdb}.
@code{open-database} will attempt to deduce the correct base-table-type.
@end defun
@defun write-database rdb filename
Writes the mutable relational-database @var{rdb} to @var{filename}.
@end defun
@defun sync-database rdb
Writes the mutable relational-database @var{rdb} to the filename it was
opened with.
@end defun
@defun solidify-database rdb
Syncs @var{rdb} and makes it immutable.
@end defun
@defun close-database rdb
@var{rdb} will only be closed when the count of @code{open-database} - @code{close-database}
calls for @var{rdb} (and its filename) is 0. @code{close-database} returns #t if successful;
and #f otherwise.
@end defun
@defun mdbm:report
Prints a table of open database files. The columns are the
base-table type, number of opens, @samp{!} for mutable, the
filename, and the lock certificate (if locked).
@end defun
@example
(mdbm:report)
@print{}
alist-table 003 /usr/local/lib/slib/clrnamdb.scm
alist-table 001 ! sdram.db jaffer@@aubrey.jaffer.3166:1038628199
@end example
@subsubheading Opening Tables
@defun open-table rdb table-name
@var{rdb} must be a relational database and @var{table-name} a symbol.
@code{open-table} returns a "methods" procedure for an existing relational table in
@var{rdb} if it exists and can be opened for reading, otherwise returns
@code{#f}.
@end defun
@deffn {Procedure} open-table! rdb table-name
@var{rdb} must be a relational database and @var{table-name} a symbol.
@code{open-table!} returns a "methods" procedure for an existing relational table in
@var{rdb} if it exists and can be opened in mutable mode, otherwise returns
@code{#f}.
@end deffn
@subsubheading Defining Tables
@defun define-domains rdb row5 @dots{}
Adds the domain rows @var{row5} @dots{} to the @samp{*domains-data*} table
in @var{rdb}. The format of the row is given in @ref{Catalog Representation}.
@example
(define-domains rdb '(permittivity #f complex? c64 #f))
@end example
@end defun
@defun add-domain rdb row5
Use @code{define-domains} instead.
@end defun
@defun define-tables rdb spec-0 @dots{}
Adds tables as specified in @var{spec-0} @dots{} to the open
relational-database @var{rdb}. Each @var{spec} has the form:
@lisp
(@r{<name>} @r{<descriptor-name>} @r{<descriptor-name>} @r{<rows>})
@end lisp
or
@lisp
(@r{<name>} @r{<primary-key-fields>} @r{<other-fields>} @r{<rows>})
@end lisp
where @r{<name>} is the table name, @r{<descriptor-name>} is the symbol
name of a descriptor table, @r{<primary-key-fields>} and
@r{<other-fields>} describe the primary keys and other fields
respectively, and @r{<rows>} is a list of data rows to be added to the
table.
@r{<primary-key-fields>} and @r{<other-fields>} are lists of field
descriptors of the form:
@lisp
(@r{<column-name>} @r{<domain>})
@end lisp
or
@lisp
(@r{<column-name>} @r{<domain>} @r{<column-integrity-rule>})
@end lisp
where @r{<column-name>} is the column name, @r{<domain>} is the domain
of the column, and @r{<column-integrity-rule>} is an expression whose
value is a procedure of one argument (which returns @code{#f} to signal
an error).
If @r{<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} @dots{}) single
key field table, a foreign-key domain will be created for it.
@end defun
@subsubheading Listing Tables
@defun list-table-definition rdb table-name
If symbol @var{table-name} exists in the open relational-database
@var{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 @code{list-table-definition}, when passed as an
argument to @code{define-tables}, will recreate the table.
@end defun