Christoph Wernhard
db-class
, live-db-class
and snapshot-db-class
CLOS-DB is a database interface for the Common Lisp Object System.
At the definition of classes with the metaclass
live-db-class
or snapshot-db-class
(live db classes resp. snapshot db classes), a
database correspondence can be specified.
Valid superclasses of db classes are classes with the metaclass
standard-class
and other db classes, where the database
correspondence is inherited.
Instances of db classes can be created for given database related object identifiers (e.g. relational key values). Creation of many instances of a class corresponding to a single such object identifier can be suppressed: the instances are then identified by their class and the object identifier. Instances of db classes can also be created (or identified) setwise corresponding to a given search condition and as members of a given class (instances of the class and its subclasses).
An instance of a live db class at each point of time represents the database in its actual state: database updates, that are executed whenever a slot is written, can be specified; slots and object identities can be invalidated to reflect changes in the database (the data corresponding to the instance then are loaded from the database anew); subobjects can be lazily created.
An instance of a snapshot db class represents a ``snapshot'' of the database at a certain point of time. No database updates can be associated with snaphot db instances, they can not be invalidated and subobjects may not be created lazily.
Instances of live db classes as well as snapshot db classes can have ``normal'' slots without database correspondence. Instances of live db classes can have ``snapshot'' slots which represent the database at a certain point of time.
The connection to relational databases is implemented using Database Representatives, a lower level database interface that makes relational databases accessible through interpreters for database queries and commands. This lower level interface remains visible in the CLOS-DB programmer interface.
CLOS-DB can be portably implemented using the CLOS Metaobject Protocol AMOP [AMOP].
db-class
, live-db-class
and snapshot-db-class
The metaclasses live-db-class
and
snapshot-db-class
are subclasses of
standard-class.
db-class
, also a subclass of
standard-class
, is an abstract (i.e. not intended to be
initialized) superclass of live-db-class
and
snapshot-db-class.
In the following we call instances of live-db-class
live db classes, instances of snapshot-db-class
snapshot db classes and instances of either one of both
metaclasses db classes. Instances of db classes, live db classes and
snapshot db classes are called db instances, live db
instances or snapshot db instances respectively.
Db classes have a database correspondence associated with them. At their definition a mapping between the class and databases can be specified.
The class t
, instances of standard-class
and db classes are valid superclasses of db classes. Db
classes are valid subclasses of db classes.
The class db-object
is an abstract superclass of each
db class, live-db-object
of each live db class and
snapshot-db-object
of each snapshot db class. These
abstract superclasses are automatically added to the set of
superclasses of a db class. In the class precedence list of a given db
class they are preceded by the user specified superclasses of the
given db class, live-db-object
and
snapshot-db-object
precede db-object
and
db-object
precedes standard-object.
def-db-class
For technical reasons db classes have to be defined by the the
def-db-class
macro, which is similar to the defclass
macro.
The evaluation or execution of a def-db-class
form that
defines a db class involves no database access.
[Class Option]
db-connection
db-connection-type db-connection-arguments
This class option is accepted by db classes and is used to specify
a database object (e.g. a relation of a relational database) as
corresponding to the class. The db-connection-type argument
specifies the kind of database connection: the keyword
:relational
stands for a connection to a relational
database as described in section 3. Which
arguments are accepted as db-connection-arguments depends on
db-connection-type.
[Class Option]
abstract-member-class
boolean
This class option is accepted by db classes and is used in
connection with the make-member[-xxx]
and
identify-member[-xxx]
functions. See section
2.7.
This slot option is accepted by live db classes only and is used to specifiy database updates that should be executed when the slot is written. See section 5.1.
[Slot Option]
invalidateable
boolean
This slot option is accepted by live db classes only and is used to specify whether slots are invalidateable. See section 6.
An instance of a db class corresponds to values for a fixed set of attributes (e.g. a relational database tuple) together with an object identifier (e.g. relational key attribute values) which are offered by the database object corresponding to the class (e.g. a relational database relation).
The attribute values corresponding to an instance are called its instance tuple, the object identifier its key value. The instance tuple of an instance may change over time, where its key value remains constant.
At definition of a db class, a mapping from instance tuples into slot values can be specified:
Within the db-connection
class option a variable for each
attribute of the instance tuples is declared. These attribute
variables can be used occuring freely in the initforms of slots
with :instance
allocation. At evaluation of those initforms,
they are bound to the respective values from the instance tuple.
More precisely, the evaluation of such an initform
initformis, as if the following form were
evaluated in the lexical environment of the def-db-class
form that defined the initform:
(funcall #'(lambda (var1...varn) initform)
value1...valuen)
where var1...varn are the attribute variables refered by initform and value1... valuen are the corresponding attribute values in the instance tuple.
Storing of an instance (see section 4) means for the class to keep an association of the instances' key value to the instance.
[Generic Function]
unstore-all-instances-from-class
class
This generic function effects, that all instances stored by class are unstored from class, which means that the associations (kept by the class) of key values to instances are abandoned.
Unstored instances are free to be garbage collected if there are no
other references to them. Subsequent calls of the identify-
functions start anew to store instances, the unstored instances then
are like instances directly created by a
make-instance/member[-xxx]
function.
class is a db class object or a symbol that names a db class.
[Primary Method]
unstore-all-instances-from-class
(class db-class) instance
This Method implements the behavior specified for the generic function.
[Primary Method]
unstore-all-instances-from-class
(class symbol) instance
This method invokes unstore-all-instances-from-class
on
(find-class class).
The make-member[-xxx] and identify-member[-xxx] functions create resp. identify members of a given class, i.e. instances of the class and its subclasses.
For that purpose they use the member classes of a given class: This is the set containing all classes among the given class and its subclasses whose class option abstract-member-class
is false.
The class option abstractmemberclass defaults to false.
A correspondence of a db class to a relational database is defined
by a db-connnection
class option of the following form:
(db-connection :relational [[?relational-db-connection-argument]]) relational-db-connection-argument ::= :db database-representative | :key-attributes ({key-attribute}*) | :attributes ({attribute-specifier}*) | :from ({range-variable-specifier}*) | :where search-condition} | :include-subclass-members boolean attribute-specifier ::= variable | (variable column-expression [null-value-form [typespecifier]]) range-variable-specifier ::= relation | (relation rangevariable)
key-attribute, column-expression, relation, range-variable and search-condition contain expressions in a database language. search-condition must be a string, the other arguments can be strings or symbols where the symbol-name is used.
For the SQL database language, the syntactical categories of the
db-connection
option correspond as follows (syntactical categories of
SQL after [Date87]):
key-attribute ::= column-qualifier.column column-expression ::= scalar-exp relation ::= table range-variable ::= range-variable search-condition ::= search-condition
A relational db connection defined for a db class is inherited. The effective relation is the database relation effectively corresponding to a db class with relational db connection. It consists of a tuple including as subtuples 1. a key value and 2. an instance tuple for each key value for which instances of the class can be created.
The effective relation is determined by a database, a set of range variables over relations from the database, a set of attributes from them, a search condition, and a sequence of key attributes: it is the projection on the attributes and key attributes of the product of the range variables, restricted by the search condition.
Certain arguments to the relational db-connection
option are
given as expressions in the database language. They are concatenated
by the system to larger expressions in the database language, hence
they form a ``database identifier scope'' within which the
``database identifiers'' (i.e. names of relations, attributes,
range variables etc.) contained in the arguments are visible to each
other. Such a ``database identifier scope'' includes all the
db-connection
options of a db class and its superclasses.
A class whose db-connection
option specifies a relational db
connection must not appear together with a class whose
db-connection
option specifies another type of db connection in
the class precedence list of any db class.
The database languages (see Database
Representatives) used by all the db-connection
options of the classes in any class precedence list of a db class must
be the same (or at least compatible).
The effective relation corresponding to a db class is determined as follows:
All the db-connection
options of the class and its
superclasses are ordered from most specific to least specific
according to the order in the class' class precedence list.
The database representative used by the db class is the value of
the :db argument in the most specific db-connection
option that contains one.
It is an error if none of the db-connection
options contains
a :db argument. The argument of :db is a symbol that is
defined as database representative (at the time of evaluation or
execution of the def-db-class
form).
During the evaluation of an initform and during evaluation of the
argument form of a
slot option, the value of the
db-update
*default-database-representative*
variable is bound to the
database representative used by the class.
A tuple in the effective relation is uniquely identified by the values of a set of key attributes in the tuple. A set of key attributes with a total ordering on it forms the sequence of key attributes.
The sequences of key attributes, specified as lists of attribute
names by the :key-attributes argument of all of the
db-connection
options must be ``matchable'':
Their length must be the same and the respective nth attributes in
each sequence must be type compatible. Since they are
``unified'' (see The Search
Condition below), any one of them is good as the sequence of key
attributes of the effective relation.
If none of the db-connection
options contains a
:key-attributes argument, the set of attributes of the
effective relation with an unspecified ordering is used as sequence of
key attributes.
The set of attributes of the effective relation is the union of the
sets of attributes specified by the :attributes argument
in all the db-connection
options.
The argument of :attributes is a list of attribute specifiers, where each attribute specifier can be a list as specified above (see section 3.1):
When forms containing attribute variables are evaluated, the attribute variables are bound to the respective database literals in their standard conversion form (see Database Representatives).
def-db-class
form that defined it as value.
null-value-form defaults to the keyword symbol
:null-value. null-value-form is evaluated only
once during the evaluation resp. execution of the
def-db-class
form that defined it.
As short form an attribute specifier can be a single attribute variable whose symbol-name is used like the column-expression argument.
The set of range variables of the effective relation is the union of the set of range variables specified by the :from argument in all the db-connection
options.
The argument of :from is a list of range variable specifiers, where each range variable specifier is a twoelement list containing a relation name and a range variable. The range variable then is defined to range over the relation.
As short form, a range variable specifier can be a relation name -- a range variable with the same name over the relation is defined.
The membership condition of the effective relation restricts the product over the set of range variables such that it contains a single tuple for each key value for which members of the class (i.e. instances of the class or of one of its subclasses) can be created.
The membership condition is the conjunction of:
db-connection
options.
db-connection
options are equal.
The search condition of a db-class
depends on the value of :include-subclass-members in the
most specific db-connection
option:
While instance creation in pure CLOS coincides with the
establishing of references to instances and is connected with the
allocation of individual instances of given classes, the database
correspondence of db-class
es places different aspects
into the foreground.
A single db instance, corresponding to a given key value, is
created by make-instance
, with the key value supplied as value of the
obligatory initarg db-key.
A set of db instances, whose instance tuples satisfy a given
database search condition, is created by make-instance-list
and
make-instance-lstream.
make-instance-list
returns an ``eager'' representation of the set as list of
instances, where make-instance-lstream
returns a
``lazy'' representation as ``lstream'', an object that
can be manipulated analogously to Common Lisp input streams (see
Database Representatives).
identify-instance
identifies a db instance by its class and
key value: The first call of identify-instance
for a given db
class and key value actually creates the instance which then is stored
by its class. Subsequent calls of identify-instance
on the same
class and key value then return the stored instance.
identify-instance
can be used in place of
make-instance
and like an instance name. It can serve to
transfer referential sharing of representations from the database into
the object system and to cache db instances.
See also section 2.6.
make-member
returns a member of a given class (i.e. an
instance of that class or of a subclass of it) for a given key value.
A prerequisite for member creation is, that for no two subclasses (more precisely member classes (see section 2.7)) of the given class, instance tuples corresponding to the same key value exist.
See also section 2.7 and the description of the :include-subclass-members argument to the db-connection class option (for relational db connections).
identify-member
, identify-instance-list
,
identify-instance-lstream
, make-member-list
,
make-member-lstream
, identify-member-list
,
and identify-member-lstream
combine singular instance
creation for given key values, setwise instance creation, instance
identification and member creation.
The setwise identify-
functions can be used to ``load'' instances which may be used afterwards by the application.
The setwise -member-
functions return the union of instances
of the given class and its relevant subclasses (the given class'
member classes) whose instance tuples satisfy the search condition.
make-instance (class db-class) &rest initargs &key db-key
When called by programs, the db-key initarg, which specifies
a key value, must be supplied. An instance tuple corresponding to the
key value and the class' db connection is retrieved and a new instance
of the class for the instance tuple is created and returned. The new
instance is created by calling the next method make-instance
(standard-class)
on class, initargs and further
implementation specific initargs.
For a classes with relational db connection db-key can be a
list of objects or a single object which matches with the class'
sequence of key attributes: If db-key is a cons, it must have
the same length as the sequence of key attributes. If there is only a
single key attribute, db-key can be a single object (an atom)
corresponding to that attribute. The db-literal
function,
called on the nth element of the list (resp. on the single object)
must yield a print representation of a proper value for the nth (resp.
single) key attribute.
When the retrieval of the instance tuple fails because no instance
tuple corresponding to db-key and the class' db connection
exists, no-instance-tuple
is invoked as follows:
(apply #'no-instance-tuple class 'nil 'make-instance
initargs)
Functions for instance creation and identification which are
implemented using make-instance
may call
make-instance
on implementation specific initargs. When
certain such initargs are supplied, this method immediately invokes
the next method (usually make-instance (standard-class)
)
on the original arguments.
identify-instance class &rest initargs &key db-key &allow-other-keys
When called by programs, the db-key initarg, which specifies a key value, must be supplied.
If the class does not already store an instance for the key value,
make-instance
is called on the original arguments. When
make-instance
returns an instance of the class, the
instance is stored by the class for the key value. The values returned
by make-instance
are returned.
If the class already stores an instance for the key value, then, if
the class is a live db class and the instances' existence
is valid or the class is a snapshot db class,
reinitialize-stored-instance
is called on the instance
and initargs and the instance is returned.
If the class is a live db class and the stored instances'
existence is invalid,
reinitialize-stored-instance
is called on an instance as
described in section 6.4 and initargs
and that instance is returned. The identification of such an instance
may fail because the instance tuple corresponding to the key value
does not exist in the database. In this case no-instance-tuple
is invoked as follows (where instance is the stored instance with
invalid existence):
(apply #'no-instance-tuple class instance
'identify-instance initargs)
The arguments of identify-instance
are identical to
those of make-instance.
Functions which are implemented using
identify-instance
may call identify-instance
with implementation specific initargs, such that when these are passed
to make-instance
, make-instance (db-class)
immediately calls the next method.
make-member class &rest initargs &key db-key &allow-other-keys
The db-key initarg, which specifies a key value, must be supplied.
Until it succeeds, this generic function attempts for each class
among the member classes of the given class to retrieve an instance
tuple which corresponds to the key value and the respective member
class' db connection. A new instance is created by calling
make-instance
on the member class for which the instance
tuple has been retrieved, initargs and implementation specific
initargs (such that make-instance (db-cl ass)
immediately
calls the next method). The value of make-instance
(the
newly created instance) is returned.
The arguments of make-member
are identical to those of
make-instance.
If for none of the member classes an instance tuple can be
retrieved, no-instance-tuple
is invoked as follows:
(apply #'no-instance-tuple class 'nil 'make-member
initargs)
identify-member class &rest initargs &key db-key &allow-other-keys
This generic function combines identify-instance
and
make-member.
The db-key initarg, which specifies a key value, must be supplied.
identify-member
proceeds as follows:
If one of the class' member classes stores an instance (if the
class is a live db class: with valid existence or with
invalid existence but with its instance tuple existing in
the database. In the latter case the stored instance with invalid
existence is replaced by an instance as described in section 6.4.) for the key value,
reinitializ-estored-instance
is called on the instance
and initargs and the instance is returned.
Otherwise, until it succeeds, identify-member
attempts
for each class among the member classes of the given class to retrieve
an instance tuple which corresponds to the key value and the
respective member class' db connection. A new instance is created by
calling make-instance
on the member class for which the
instance tuple has been retrieved, initargs and implementation
specific initargs (such that make-instance (db-class)
immediately calls the next method). The newly created instance is
stored by its class for the key value and returned.
The arguments of identify-member
are identical to
those of make-instance.
If (after no stored instance has been found) for none of the member
classes an instance tuple can be retrieved,
no-instance-tuple
is invoked as follows:
(apply #'no-instance-tuple class 'nil 'identify-member
initargs)
make-instance-list class &key :db-cond :order-by :max-no-of-elements :initargs
For each instance tuple corresponding to the class' db connection
that satisfies the search condition :db-cond, this generic
function creates a new instance by calling make-instance
on the
class, :initargs and implementation specific initargs (such
that make-instance (db-class)
immediately calls the next
method).
A list that contains the newly created instances is constructed and returned.
nil.
A search condition can be given as a string or a nonempty list. If
it is a list, a string is used, which is obtained from the list in the
same way as described for the query argument of the
db-query-xxx
functions (see Database
Representatives). If :db-cond is nil
, no search
condition (i.e. a ``true'' search condition) is used.
:db-cond defaults to nil.
The search condition is included into the ``database identifier scope'' of the class' db connection.
For a relational db connection that uses the SQL database language, the search condition has the syntactical category (after [Date87]) search-condition.
nil.
An ordering specification can be given as a string or a nonempty
list. If it is a list, a string is used, which is obtained from the
list in the same way as described for the query argument of the
db-query-xxx
functions (see Database Representatives). If
:order-by is an ordering specification, the instances are
returned in the specified ordering. If :order-by is nil
,
the instances are returned in an arbitrary ordering.
:order-by defaults to nil.
The ordering specification is included into the ``database identifier scope'' of the class' db connection.
For a relational db connection that uses the SQL database language, the ordering specifier has the syntactical category (after [Date87]) ordering-spec-commalist.
nil
or an integer >= 0.
If :max-no-of-elements is an integer, at most :max-no-of-elements of the instance tuples satisfying the search condition are considered.
If :max-no-of-elements is nil
, all instance tuples satisfying the search condition are considered.
:max-no-of-elements defaults to nil.
make-instance-lstream class &key :db-cond :order-by :buffering :initargs
This generic function behaves like make-instance-list
,
except that
it constructs and returns an lstream containing the
instances instead of a list.
The arguments of make-instance-lstream
are identical to
those of make-instance-list, with exception of
:max-no-of-elements and :buffering.
nil
or an integer > 0.
If :buffering is an integer the system tries to actually produce the elements of the lstream chunks of :buffering elements, which can improve performance.
:buffering defaults to nil.
identify-instance-list class &key :db-cond :order-by :max-no-of-elements :initargs
This generic function behaves like make-instance-list
,
except that instead of creating an instance, it identifies an instance
by calling identify-instance
on the class, :initargs and
implementation specific initargs (such that make-instance
(db-class)
, when called by identify-instance
, immediately
calls the next method) for each instance tuple satisfying the search
condition.
The arguments of identify-instance-list
are identical to
those of make-instance-list.
identify-instance-lstream class &key :db-cond :order-by :buffering :initargs
This generic function behaves like
identify-instance-list
,
except that it constructs and returns an lstream containing the
instances instead of a list.
The arguments of identify-instance-lstream
are identical
to those of make-instance-lstream.
make-member-list class &key :db-cond :order-by :max-no-of-elements :initargs
This generic function constructs and returns a list of instances by
concatenating the results of calling make-instance-list
on each
member class of class and :initargs where the
:max-no-of-elements initarg (if it is an integer) is
decremented after each call to make-instance-list
by the number
of actually created instances.
The arguments of make-member-list
are identical to those of
make-instance-list.
make-member-lstream class &key :db-cond :order-by :buffering :initargs
This generic function behaves analogous to make-member-list, except that it constructs and returns an lstream containing the instances.
The resulting lstream gets its elements from
``sublstreams'' which are constructed by calling
make-instance-lstream
on the member classes of class and
:initargs. Until there are no more member classes, at retrieval of an
element from the resulting lstream a new
sub-lstream is constructed at the first retrieval and
whenever the previously constructed sub-lstream is
exhausted.
The arguments of make-member-lstream
are identical to
those of make-instance-lstream.
identify-member-list class &key :db-cond :order-by :max-no-of-elements :initargs
This generic function behaves like make-member-list
,
except that it calls identify-instance-list
instead of
make-instance-list
on each member class of class and
:initargs (with :max-no-of-elements appropriately decremented).
The arguments of identify-member-list
are identical to those
of make-instance-list.
identify-member-lstream class &key :db-cond :order-by :buffering :initargs
This generic function behaves like
make-member-lstream
, except that the elements of the
resulting lstream are obtained by calling
identify-instance
lstream on the member classes and
:initargs instead of make-instance-lstream.
The arguments of make-member-lstream
are identical to
those of make-instance-lstream.
The following methods implement the specified behaviors of their
generic functions. Methods, whose class argument is specialized on
symbol invoke their generic function on (find-class
class)
and initargs resp. args.
identify-instance (class live-db-class) &rest initargs &key db-key
identify-instance (class snapshot-db-class) &rest initargs &key db-key[Primary Method]
identify-instance (class symbol) &rest initargs[Primary Method]
make-member (class db-class) &rest initargs &key db-key[Primary Method]
make-member (class symbol) &rest initargs[Primary Method]
identify-member (class live-db-class) &rest initargs &key db-key[Primary Method]
identify-member (class snapshot-db-class) &rest initargs &key db-key[Primary Method]
identify-member (class symbol) &rest initargs[Primary Method]
make-instance-list (class db-class) &key :db-cond :order-by :max-no-of-elements :initargs[Primary Method]
make-instance-list (class symbol) &rest args[Primary Method]
make-instance-lstream (class db-class) &key :db-cond :order-by :buffering[Primary Method]
make-instance-lstream (class db-class) &rest args
For each of the other generic functions for setwise instance/member
creation/identification there are methods with the same signature as specified
above for make-instance-list
and
make-instance-lstream
respectively.
[Generic Function]
reinitialize-stored-instance instance &rest initargs
This generic function is called by identify-instance
and
identify-member
to reinitialize stored instances.
The value returned by reinitialize-stored-instance
is ignored.
[Primary Method]
reinitialize-stored-instance
(instance db-object) &rest initargs
This method calls reinitialize-instance
on instance and
initargs. Programs can override this method.
[Generic Function]
no-instance-tuple class instance situation &rest args
This generic function may be called during evaluation of
make-instance
, identify-instance
, make-member
,
identify-member
, slot-value
and shared-initialize.
The values returned by methods for this function get returned as the values of the original function invocation.
[Primary Method]
no-instance-tuple
(class t) (instance t) (situation t) &rest args
This method signals an error.
The db-update
slot option for live db classes allows specify
database updates to be associated with the slot.
The database updates associated with a slot are determined by the argument
of the db-update
slot option in the most specific slot specifier
for that slot that contains one:
If this argument is nil
or if no slot specifier contains a
db-update
slot option, no database updates are associated with
the slot.
Otherwise, if the argument is a non-nil form, whenever the slot is written
(unless due to the initializion according to its initform) the database is
updated (after the new slot value is stored) in the following way: The
argument of the db-update
slot option is evaluated analogously to
initforms with proper attribute variables (see below) in the lexical
environment of the def-db-class
form that defined it. The value
obtained, which must be a four-place function, is called on the slot value of
the slot, the class of the instance, the instance and the effective
slot-definition metaobject corresponding to the slot.
Remark: It is not specified, when the values of the attribute variables
used for evaluating the argument form of a db-update
slot option
are retrieved from the database. However, this should not be a problem: The
intendend purpose of attribute variables in the slot option is to manage
relationships represented in relations that use alternate keys [Date90] instead of the key attributes specified for
the effective relation of some given class. The values of attribute variables
containing an alternate key to the effective relation never change for a given
instance.
db-update
Slot Option
[Function]
update-attributes
&key :attributes :relation :where :db
This function is intended to be used within the db-update
slot
option of db classes with relational db connection.
It returns a four-place function with the parameters: new-value class instance slot.
The arguments of update-attibutes are a set of attributes, a relation, a search condition and a database-representative.
The function returned by update-attributes
defaults these arguments
and effects that in the tuples from the relation which satisfy the search
condition the attributes are updated to the values specified by the
new-value argument.
The specified attributes must be from the relation specified by :relation.
If :attributes is a nonempty list, new-value must be a list with the same length. The new value of the nth attribute is the results of calling db-literal on the nth element of new-value (and the database-representative-language of the database-representative specified by :db). If :attributes is an non-nil atom, new-value must be a single object, db-literal called on the object (and, as above, the database-representative-language) is the new value of the attribute.
If :attributes is the empty list or unspecified, no database updates
are effected by the function resulting from update-attributes.
:relation defaults to the relation specified as :from
argument of the db-connection
option of the class, that defines
the db-update
slot option. If :from doesn't specify a
single relation, :relation has to be supplied.
:where defaults to a search condition, that equates the key
attributes specified by the :key-attributes argument of the
db-connection
option of the class, that defines the
db-update
slot option, with the key values of the instance (only
the attribute names of the attributes specified as :key-attributes are used,
not their qualifying range variables). If :key-attributes is unspecified
:where has to be supplied.
:db defaults to the database-representative usesd for the effective relation of class.
For the SQL database language the syntactical categories (after [Date87]) of specifiers in the database language are as follows: relation specifier: table, attribute specifier: column, search condition: search-condition.
[Function]
adjust-relation &key :attributes :relation
:self-key-attributes :self-key-values :db
This function is intended to be used within the db-update
slot
option of db classes with relational db connection. It can serve to map a slot
representing a set into a database relation.
It returns a four-place function with the parameters: new-values class instance slot.
The arguments of adjust-relation
are a set of attributes, a
relation, a set of attributes called self-key attributes, a
set of values for them called self-key values and a
database-representative.
The function returned by adjust-relation
defaults these arguments
and effects that the relation is modified by deleting the additional
tuples from the relation and afterwards inserting the missing
tuples into the relation (attributes of the relation not included in the
set of arguments get the null value), where:
The specified attributes must be from the relation specified by :relation.
If :attributes is a nonempty list, new-values must be a list
of sublists with the same length as :attributes. The values used for
comparing with database literals and inserting into the database for the nth
attribute are the results of calling db-literal
on the respective nth
element in a sublist (and the database-representative-language of the
database-representative specified by :db).
If :attributes is an non-nil atom, new-values must be a list of single objects, the results of calling db-literal on each of these objects (and, as above, the database-representative-language) are used for comparing and inserting.
If :attributes is the empty list or unspecified, no database updates
are effected by the function resulting from adjust-relation
.
:relation must be supplied.
The specified attributes must be from the relation specified by :relation.
:self-key-attributes defaults to the key attributes specified by the
:key-attributes argument of the db-connection
option of
the class, that defines the db-update
slot option (as list of
attribute specifiers, where only the attribute names of the attributes
specified as :key-attributes are used, not their qualifying range
variables). If :key-attributes is unspecified
:self-key-attributes has to be supplied.
The values used for comparing with database literals and inserting into the database for the single (resp. nth) self-key attribute are obtained by calling db-literal on :self-key-values (resp. the nth element of :self-key-values) (and the database-representative-language of the database-representative specified by :db).
:self-key-values defaults to the key value (as a list of objects) of the instance.
:db defaults to the database-representative usesd for the effective relation of class.
For the SQL database language the syntactical categories (after [Date87]) of specifiers in the database language are as follows: relation specifier: table, attribute specifier: column.
This function is similar to the adjust-relation
function, except
that:
The values of the self-key attributes of tuples with the same values for the attributes as a missing tuple are set to the self-key values.
Invalidateable slots actually combine two concepts: instantiation of the components of composite objects on demand and re-retrieval of information from the database.
Slots of live db instances with allocation :instance
can be
invalidateable.
Whether a slot is invalidateable is controlled by the most specific slot specifier for the slot:
invalidateable
slot option or a true invalidateable
slot option, the slot is invalidateable.
invalidateable
slot option, the slot is not
invalidateable.
An invalidateable
slot at any point of time is either
valid which means that it stores its actual value, or
invalid which means that it stores no value or an obsolete value.
An invalid slot with an initform appears as bound to the result of evaluating its initform anew. At reading, the slot is validated: its initform is evaluated and stored. At the evaluation of the initform it is ensured, that the values of the attribute variables occuring in the initform were retrieved from the database after the invalidation of the slot.
An invalid slot without an initform appears as unbound.
A valid slot is accessed as usual.
Writing an invalid slot makes it valid.
shared-initialize
does not initialize any invalidateable slots
indicated by the slotnames argument according to their initforms. These slots
initially are invalid.
A live db instance must have a corresponding tuple in the database, tuples however can be deleted.
Invalidating all slots of an instance implicitely (i.e. by
make-invalid
called on a slotset argument obtained
by calling slotset
on :all-slots
or on
another keyword with t
as slotnames argument)
invalidates the so-called existence of the instance.
Live db instances with invalid existence must not be
used. If there is a stored (see section 4.1)
instance with invalid existence for a given class and
key-value, the identify-
functions however return and store an
instance (which may be identical (eq
) to the instance with
invalid existence or not) whose non-invalidateable slots
take over the values from the instance with invalid
existence.
At the creation of an instance it is ensured, that a corresponding instance tuple exists in the database. The functions for instance creation and identification never return instances with invalid existence.
If the revalidation of a slot (entailed by a call to
slot-value
) fails because because the instance's instance tuple
no longer exists in the database (this might happen if the database
has changed without a corresponding invalidation of the live db
instances), the handler generic function no-instance-tuple
is
called as follows:
(no-instance-tuple (classof object) object 'slot-value
slot-name)
[Function]
make-invalid &optional slotset
This function effects that existences or the invalidateable slots in the set of slots specified by slotset become invalid as described in section 6.4.
(slotset :all-slots).
[Function]
slotset
keyword &rest args
This function returns a slotset object, an object
which specifies a set of slots. The make-invalid
generic
function takes such an object as argument.
The set of slots specified by the slotset is determined by the keyword argument (which is a keyword symbol) and, depending on keyword, further arguments. The following arguments are accepted:
:all-slots
slotset
specifies the
set of all slots.
:slots-of-instances-of-class class
[slot-names]
slot-names is a list of slot names or the symbol t
,
which is the default value and indicates all slots.
The slotset specifies the set of all slots indicated by slot-names of all instances of the class.
:slots-of-instances instances
[slot-names]
slot-names is a list of slot names or the symbol t
,
which is the default value and indicates all slots.
The slotset specifies the set of slots indicated by slot-names of the instances.
:slots instance-slotname-pairs
The slotset specifies the set of slots which contains for each instance-slotname pair the respective slot of the instance.
[Function]
(setf single-db-user) new-value
These functions maintain a flag that indicates whether the database is used by multiple users or exclusively by the Lisp session.
single-db-user
returns the value of the flag, (setf
single-db-user)
assigns new-value as the value of the flag.
The default setting of the flag is false.
If the flag is set from true to false, db-rollback
is called
(after the flag has received its new value). The behavior of the
db-commit
and db-rollback
functions depends on the value
of single-db-user
(see below).
[Standard Class]
clos-db-setup
The default value of the *setup*
variable (after loading
CLOS-DB) is an instance of clos-db-setup
.
clos-db-setup
is a subclass of
database-representatives-setup
. Programs may create subclasses
of clos-db-setup
and bind *setup*
to it. The
results are undefined if programs override any methods specified in
this document which specialize on clos-db-setup.
The following methods extend the behavior of the db-commit,
db-rollback
, open-database-representative
and
close-database-representative
functions specified in Database Representatives:
[After
Method]
db-commit-using-setup (setup
clos-db-setup)
If the single-db-user
flag is false, this method calls make-invalid on a slotset
object obtained by (slotset
:all-slots
).
The results are undefined if afterwards elements are retrieved from lstreams previously returned by a function specified in this document or in Database Representatives.
[After
Method]
db-rollback-using-setup (setup
clos-db-setup) &rest args
If the single-db-user
flag is false, this method calls
make-invalid
on a slotset object obtained by
(slotset :all-slots).
The results are undefined if afterwards elements are retrieved from lstreams previously returned by a function specified in this document or in Database Representatives.
Unless the database representative is already closed this method
calls make-invalid
on a slotset object obtained by
(slotset :all-slots).
The results are undefined if afterwards elements are retrieved from lstreams connected to the database representative (i.e. lstreams that may contain instances of classes which uses the database representative for their effective relation) which were previously returned by a function specified in this document or in Database Representatives.
This index also includes methods presented apart from their generic function specification.
abstract-member-class
class option
adjust-relation
function
adjust-relation-update-insert-nullify
function
clos-db-setup
standard class
close-database-representative-using-setup (clos-db-setup)
before method
db-class
metaclass
db-commit-using-setup (clos-db-setup)
before method
db-connection
class option
db-object
standard class
db-rollback-using-setup (clos-db-setup)
before method
db-update
slot option
def-db-class
macro
identify-instance
generic function
identify-instance-list
generic function
identify-instance-lstream
generic function
identify-member
generic function
identify-member-list
generic function
identify-member-lstream
generic function
invalidateable
slot option
live-db-class
metaclass
live-db-object
standard class
make-instance
(class db-class)
primary method
make-instance-list
generic function
make-instance-lstream
generic function
make-invalid
function
make-member
generic function
make-member-list
generic function
make-member-lstream
generic function
no-instance-tuple
generic function
reinitialize-stored-instance
generic function
(setf single-db-user)
function
single-db-user
function
slotset
function
snapshot-db-class
metaclass
snapshot-db-object
standard class
unstore-all-instances-from-class
generic function
update-attributes
function