1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
@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}).
@defunx 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
|