
Loading `db/sqlite3' no longer raises an exception if the SQLite library isn't found. Instead, `sqlite3-connect' raises an exception, while `sqlite3-available?' reports whether it will work. The dynamic test allows the documentation-help system to continue to work if SQLite3 is not available. Currently, though, `raco setup' still insists on using SQLite3 to build the database of documented tags.
766 lines
29 KiB
Racket
766 lines
29 KiB
Racket
#lang scribble/doc
|
|
@(require scribble/manual
|
|
scribble/eval
|
|
scribble/struct
|
|
racket/sandbox
|
|
racket/runtime-path
|
|
"config.rkt"
|
|
(for-label db
|
|
openssl))
|
|
|
|
|
|
@(define-runtime-path log-file "log-for-connect.rktd")
|
|
@(define the-eval (make-pg-eval log-file #t))
|
|
|
|
@title[#:tag "connect"]{Connections}
|
|
|
|
This section describes functions for creating connections as well as
|
|
administrative functions for managing connections.
|
|
|
|
@section[#:tag "creating-connections"]{Base Connections}
|
|
|
|
@declare-exporting[db]
|
|
|
|
There are four kinds of base connection, and they are divided into two
|
|
groups: @deftech{wire-based connections} and @deftech{FFI-based
|
|
connections}. PostgreSQL and MySQL connections are wire-based, and
|
|
SQLite and ODBC connections are FFI-based. See also
|
|
@secref["ffi-concurrency"].
|
|
|
|
Base connections are made using the following functions.
|
|
|
|
@defproc[(postgresql-connect [#:user user string?]
|
|
[#:database database string?]
|
|
[#:server server string? "localhost"]
|
|
[#:port port exact-positive-integer? 5432]
|
|
[#:socket socket (or/c path-string? 'guess #f) #f]
|
|
[#:password password (or/c string? #f) #f]
|
|
[#:allow-cleartext-password? allow-cleartext-password?
|
|
boolean? #f]
|
|
[#:ssl ssl (or/c 'yes 'optional 'no) 'no]
|
|
[#:ssl-context ssl-context ssl-client-context?
|
|
(ssl-make-client-context 'sslv3)]
|
|
[#:notice-handler notice-handler
|
|
(or/c 'output 'error output-port?
|
|
(-> string? string? any))
|
|
void]
|
|
[#:notification-handler notification-handler
|
|
(or/c 'output 'error output-port?
|
|
(-> string? any))
|
|
void])
|
|
connection?]{
|
|
|
|
Creates a connection to a PostgreSQL server. Only the
|
|
@racket[database] and @racket[user] arguments are mandatory.
|
|
|
|
By default, the connection is made via TCP to @racket["localhost"]
|
|
at port @racket[5432]. To make a different TCP connection, provide
|
|
one or both of the @racket[server] and @racket[port] arguments.
|
|
|
|
To connect via a local socket, specify the socket path as the
|
|
@racket[socket] argument. You must not supply the @racket[socket]
|
|
argument if you have also supplied either of the TCP arguments. See
|
|
also @secref{connecting-to-server} for notes on socket
|
|
paths. Supplying a @racket[socket] argument of @racket['guess] is
|
|
the same as supplying @racket[(postgresql-guess-socket-path)].
|
|
Sockets are only available under Linux (x86) and Mac OS X.
|
|
|
|
If the server requests password authentication, the
|
|
@racket[password] argument must be present; otherwise an exception
|
|
is raised. If the server does not request password authentication,
|
|
the @racket[password] argument is ignored and may be omitted. A
|
|
connection normally only sends password hashes (using the @tt{md5}
|
|
authentication method). If the server requests a password sent as
|
|
cleartext (un-hashed), the connection is aborted unless
|
|
@racket[allow-cleartext-password?] is true.
|
|
|
|
If the @racket[ssl] argument is either @racket['yes] or
|
|
@racket['optional], the connection attempts to negotiate an SSL
|
|
connection. If the server refuses SSL, the connection raises an
|
|
exception if @racket[ssl] was set to @racket['yes] or continues with
|
|
an unencrypted connection if @racket[ssl] was set to
|
|
@racket['optional]. By default, SSL provides encryption but does not
|
|
verify the identity of the server (see
|
|
@hyperlink["http://www.postgresql.org/docs/9.0/static/libpq-ssl.html"]{this
|
|
explanation}). Host verification can be required via the
|
|
@racket[ssl-context] argument; see @racket[ssl-set-verify!]. Some
|
|
servers use SSL certificates to authenticate clients; see
|
|
@racket[ssl-load-certificate-chain!] and
|
|
@racket[ssl-load-private-key!]. SSL may only be used with TCP
|
|
connections, not with local sockets.
|
|
|
|
The @racket[notice-handler] is called on notice messages
|
|
received asynchronously from the server. A common example is notice
|
|
of an index created automatically for a table's primary key. The
|
|
@racket[notice-handler] function takes two string arguments: the
|
|
condition's SQLSTATE and a message. The
|
|
@racket[notification-handler] is called in response to an event
|
|
notification (see the @tt{LISTEN} and @tt{NOTIFY} statements); its
|
|
argument is the name of the event as a string. An output port may be
|
|
supplied instead of a procedure, in which case a message is printed
|
|
to the given port. Finally, the symbol @racket['output] causes the
|
|
message to be printed to the current output port, and
|
|
@racket['error] causes the message to be printed to the current
|
|
error port.
|
|
|
|
If the connection cannot be made, an exception is raised.
|
|
|
|
@fake-examples[
|
|
[(postgresql-connect #:server "db.mysite.com"
|
|
#:port 5432
|
|
#:database "webappdb"
|
|
#:user "webapp"
|
|
#:password "ultra5ecret")
|
|
(new connection%)]
|
|
[(postgresql-connect #:user "me"
|
|
#:database "me"
|
|
#:password "icecream")
|
|
(new connection%)]
|
|
[(postgresql-connect @code:comment{Typical socket path}
|
|
#:socket "/var/run/postgresql/.s.PGSQL.5432"
|
|
#:user "me"
|
|
#:database "me")
|
|
(new connection%)]
|
|
[(postgresql-connect #:socket 'guess (code:comment "or (postgresql-guess-socket-path)")
|
|
#:user "me"
|
|
#:database "me")
|
|
(new connection%)]]
|
|
}
|
|
|
|
@defproc[(postgresql-guess-socket-path)
|
|
path-string?]{
|
|
|
|
Attempts to guess the path for the socket based on conventional
|
|
locations. This function returns the first such path that exists in
|
|
the filesystem. It does not check that the path is a socket file,
|
|
nor that the path is connected to a PostgreSQL server.
|
|
|
|
If none of the attempted paths exist, an exception is raised.
|
|
}
|
|
|
|
@defproc[(mysql-connect [#:user user string?]
|
|
[#:database database (or/c string? #f) #f]
|
|
[#:server server string? "localhost"]
|
|
[#:port port exact-positive-integer? 3306]
|
|
[#:socket socket (or/c path-string? #f) #f]
|
|
[#:ssl ssl (or/c 'yes 'optional 'no) 'no]
|
|
[#:ssl-context ssl-context ssl-client-context?
|
|
(ssl-make-client-context 'tls)]
|
|
[#:password password (or/c string? #f) #f]
|
|
[#:notice-handler notice-handler
|
|
(or/c 'output 'error output-port?
|
|
(-> exact-nonnegative-integer? string? any))
|
|
void])
|
|
connection?]{
|
|
|
|
Creates a connection to a MySQL server. If @racket[database] is
|
|
@racket[#f], the connection is established without setting the
|
|
current database; it should be subsequently set with the @tt{USE}
|
|
SQL command.
|
|
|
|
The meaning of the other keyword arguments is similar to those of
|
|
the @racket[postgresql-connect] function, except that the first
|
|
argument to a @racket[notice-handler] function is a MySQL-specific
|
|
integer code rather than a SQLSTATE string, and a @racket[socket]
|
|
argument of @racket['guess] is the same as supplying
|
|
@racket[(mysql-guess-socket-path)].
|
|
|
|
If the connection cannot be made, an exception is raised.
|
|
|
|
@fake-examples[
|
|
[(mysql-connect #:server "db.mysite.com"
|
|
#:port 3306
|
|
#:database "webappdb"
|
|
#:user "webapp"
|
|
#:password "ultra5ecret")
|
|
(new connection%)]
|
|
[(mysql-connect #:user "me"
|
|
#:database "me"
|
|
#:password "icecream")
|
|
(new connection%)]
|
|
[(mysql-connect @code:comment{Typical socket path}
|
|
#:socket "/var/run/mysqld/mysqld.sock"
|
|
#:user "me"
|
|
#:database "me")
|
|
(new connection%)]
|
|
[(mysql-connect #:socket (mysql-guess-socket-path)
|
|
#:user "me"
|
|
#:database "me")
|
|
(new connection%)]]
|
|
}
|
|
|
|
@defproc[(mysql-guess-socket-path)
|
|
path-string?]{
|
|
|
|
Attempts to guess the path for the socket based on conventional
|
|
locations. This function returns the first such path that exists in
|
|
the filesystem. It does not check that the path is a socket file,
|
|
nor that the path is connected to a MySQL server.
|
|
|
|
If none of the attempted paths exist, an exception is raised.
|
|
}
|
|
|
|
@defproc[(sqlite3-connect
|
|
[#:database database (or/c path-string? 'memory 'temporary)]
|
|
[#:mode mode (or/c 'read-only 'read/write 'create) 'read/write]
|
|
[#:busy-retry-limit busy-retry-limit
|
|
(or/c exact-nonnegative-integer? +inf.0) 10]
|
|
[#:busy-retry-delay busy-retry-delay
|
|
(and/c rational? (not/c negative?)) 0.1]
|
|
[#:use-place use-place boolean? #f])
|
|
connection?]{
|
|
|
|
Opens the SQLite database at the file named by @racket[database], if
|
|
@racket[database] is a string or path. If @racket[database] is
|
|
@racket['temporary], a private disk-based database is created. If
|
|
@racket[database] is @racket['memory], a private memory-based
|
|
database is created.
|
|
|
|
If @racket[mode] is @racket['read-only], the database is opened in
|
|
read-only mode. If @racket[mode] is @racket['read/write] (the
|
|
default), the database is opened for reading and writing (if
|
|
filesystem permissions permit). The @racket['create] mode is like
|
|
@racket['read/write], except that if the given file does not exist,
|
|
it is created as a new database.
|
|
|
|
SQLite uses @hyperlink["http://www.sqlite.org/lockingv3.html"]{coarse-grained
|
|
locking}, and many internal operations fail with the
|
|
@tt{SQLITE_BUSY} condition when a lock cannot be acquired. When an
|
|
internal operation fails because the database is busy, the
|
|
connection sleeps for @racket[busy-retry-delay] seconds and retries
|
|
the operation, up to @racket[busy-retry-limit] additional times. If
|
|
@racket[busy-retry-limit] is @racket[0], the operation is only
|
|
attempted once. If after @racket[busy-retry-limit] retries the
|
|
operation still does not succeed, an exception is raised.
|
|
|
|
If @racket[use-place] is true, the actual connection is created in
|
|
a distinct @tech/reference{place} for database connections and a
|
|
proxy is returned; see @secref["ffi-concurrency"].
|
|
|
|
If the connection cannot be made, an exception is raised.
|
|
|
|
@fake-examples[
|
|
[(sqlite3-connect #:database "/path/to/my.db")
|
|
(new connection%)]
|
|
[(sqlite3-connect #:database "relpath/to/my.db"
|
|
#:mode 'create)
|
|
(new connection%)]]
|
|
}
|
|
|
|
|
|
@defproc[(sqlite3-available?) boolean?]{
|
|
|
|
Reports whether the SQLite native library is found, in which case
|
|
@racket[sqlite3-connect] works, otherwise it raises an exception.}
|
|
|
|
|
|
@defproc[(odbc-connect [#:dsn dsn string?]
|
|
[#:user user (or/c string? #f) #f]
|
|
[#:password password (or/c string? #f) #f]
|
|
[#:notice-handler notice-handler
|
|
(or/c output-port? 'output 'error
|
|
(-> string? string? any))
|
|
void]
|
|
[#:strict-parameter-types? strict-parameter-types? boolean? #f]
|
|
[#:character-mode character-mode
|
|
(or/c 'wchar 'utf-8 'latin-1)
|
|
'wchar]
|
|
[#:use-place use-place boolean? #f])
|
|
connection?]{
|
|
|
|
Creates a connection to the ODBC Data Source named @racket[dsn]. The
|
|
@racket[user] and @racket[password] arguments are optional, since
|
|
that information may be incorporated into the data source
|
|
definition, or it might not be relevant to the data source's driver.
|
|
The @racket[notice-handler] argument behaves the same as in
|
|
@racket[postgresql-connect].
|
|
|
|
If @racket[strict-parameter-types?] is true, then the connection
|
|
attempts to determine and enforce specific types for query
|
|
parameters. See @secref["odbc-types"] for more details.
|
|
|
|
By default, connections use ODBC's @tt{SQL_C_WCHAR}-based character
|
|
encoding (as UTF-16) to send and receive Unicode character
|
|
data. Unfortunately, some drivers' support for this method is
|
|
buggy. To use @tt{SQL_C_CHAR} instead, set @racket[character-mode]
|
|
to @racket['utf-8] or @racket['latin-1], depending on which encoding
|
|
the driver uses.
|
|
|
|
See @secref["odbc-status"] for notes on specific ODBC drivers and
|
|
recommendations for connection options.
|
|
|
|
If @racket[use-place] is true, the actual connection is created in
|
|
a distinct @tech/reference{place} for database connections and a
|
|
proxy is returned; see @secref["ffi-concurrency"].
|
|
|
|
If the connection cannot be made, an exception is raised.
|
|
}
|
|
|
|
@defproc[(odbc-driver-connect [connection-string string?]
|
|
[#:notice-handler notice-handler
|
|
(or/c output-port? 'output 'error
|
|
(-> string? string? any))
|
|
void]
|
|
[#:strict-parameter-types? strict-parameter-types? boolean? #f]
|
|
[#:character-mode character-mode
|
|
(or/c 'wchar 'utf-8 'latin-1)
|
|
'wchar]
|
|
[#:use-place use-place boolean? #f])
|
|
connection?]{
|
|
|
|
Creates a connection using an ODBC connection string containing a
|
|
sequence of keyword and value connection parameters. The syntax of
|
|
connection strings is described in
|
|
@hyperlink["http://msdn.microsoft.com/en-us/library/ms715433%28v=VS.85%29.aspx"]{SQLDriverConnect}
|
|
(see Comments section); supported attributes depend on the
|
|
driver. The other arguments are the same as in @racket[odbc-connect].
|
|
|
|
If the connection cannot be made, an exception is raised.
|
|
}
|
|
|
|
@defproc[(odbc-data-sources)
|
|
(listof (list/c string? string?))]{
|
|
|
|
Returns a list of known ODBC Data Sources. Each data souce is
|
|
represented by a list of two strings; the first string is the name
|
|
of the data source, and the second is the name of its associated
|
|
driver.
|
|
}
|
|
|
|
@defproc[(odbc-drivers)
|
|
(listof (cons/c string? any/c))]{
|
|
|
|
Returns a list of known ODBC Drivers. Each driver is represented by
|
|
a list, the first element of which is the name of the driver. The
|
|
contents of the rest of each entry is currently undefined.
|
|
}
|
|
|
|
|
|
@;{============================================================}
|
|
|
|
@section{Connection Pooling}
|
|
|
|
@declare-exporting[db db/base #:use-sources (db/base)]
|
|
|
|
Creating a database connection can be a costly operation; it may
|
|
involve steps such as process creation and SSL negotiation. A
|
|
@deftech{connection pool} helps reduce connection costs by reusing
|
|
connections.
|
|
|
|
@defproc[(connection-pool
|
|
[connect (-> connection?)]
|
|
[#:max-connections max-connections (or/c (integer-in 1 10000) +inf.0) +inf.0]
|
|
[#:max-idle-connections max-idle-connections (or/c (integer-in 1 10000) +inf.0) 10])
|
|
connection-pool?]{
|
|
|
|
Creates a @tech{connection pool}. The pool consists of up to
|
|
@racket[max-connections], divided between leased connections and up to
|
|
@racket[max-idle-connections] idle connections. The pool uses
|
|
@racket[connect] to create new connections when needed. The
|
|
@racket[connect] function is called with the same
|
|
@racket[current-custodian] value as when the connection pool was
|
|
created, and it must return a fresh connection each time it is called.
|
|
|
|
@examples[#:eval the-eval
|
|
(eval:alts
|
|
(define pool
|
|
(connection-pool
|
|
(lambda () (displayln "connecting!") (sqlite3-connect ....))
|
|
#:max-idle-connections 1))
|
|
(define pool
|
|
(connection-pool
|
|
(lambda () (displayln "connecting!") (sqlite3-connect #:database 'memory)))))
|
|
(define c1 (connection-pool-lease pool))
|
|
(define c2 (connection-pool-lease pool))
|
|
(disconnect c1)
|
|
(code:line (define c3 (connection-pool-lease pool)) (code:comment "reuses actual conn. from c1"))
|
|
]
|
|
|
|
See also @racket[virtual-connection] for a mechanism that eliminates
|
|
the need to explicitly call @racket[connection-pool-lease] and
|
|
@racket[disconnect].
|
|
}
|
|
|
|
@defproc[(connection-pool? [x any/c]) boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[x] is a connection pool, @racket[#f]
|
|
otherwise.
|
|
}
|
|
|
|
@defproc[(connection-pool-lease
|
|
[pool connection-pool?]
|
|
[release (or/c evt? custodian?) (current-thread)])
|
|
connection?]{
|
|
|
|
Obtains a connection from the connection pool, using an existing idle
|
|
connection in @racket[pool] if one is available. If no idle connection
|
|
is available and the pool contains fewer than its maximum allowed
|
|
connections, a new connection is created; otherwise an exception is
|
|
raised.
|
|
|
|
Calling @racket[disconnect] on the connection obtained causes the
|
|
connection to be released back to the connection pool. The connection
|
|
is also released if @racket[release] becomes available, if it is a
|
|
synchronizable event, or if @racket[release] is shutdown, if it is a
|
|
custodian. The default for @racket[release] is the current thread, so
|
|
the resulting connection is released when the thread that requested it
|
|
terminates.
|
|
|
|
When a connection is released, it is kept as an idle connection if
|
|
@racket[pool]'s idle connection limit would not be exceeded;
|
|
otherwise, it is disconnected. In either case, if the connection is in
|
|
a transaction, the transaction is rolled back.
|
|
}
|
|
|
|
|
|
@;{========================================}
|
|
|
|
@section{Virtual Connections}
|
|
|
|
@declare-exporting[db db/base #:use-sources (db/base)]
|
|
|
|
A @deftech{virtual connection} creates actual connections on demand and
|
|
automatically releases them when they are no longer needed.
|
|
|
|
@defproc[(virtual-connection
|
|
[connect (or/c (-> connection?) connection-pool?)]
|
|
#| [#:timeout timeout (and/c real? positive?) +inf.0] |#)
|
|
connection?]{
|
|
|
|
Creates a @tech{virtual connection} that creates actual connections on
|
|
demand using the @racket[connect] function, or by calling
|
|
@racket[(connection-pool-lease connect)] if @racket[connect] is a
|
|
@tech{connection pool}. If @racket[connect] is a function, it is
|
|
called with the same @racket[current-custodian] value as when the
|
|
virtual connection was created.
|
|
|
|
A virtual connection encapsulates a mapping
|
|
of threads to actual connections. When a query function is called with
|
|
a virtual connection, the current thread's associated actual
|
|
connection is used to execute the query. If there is no actual
|
|
connection associated with the current thread, one is obtained by
|
|
calling @racket[connect]. An actual connection is disconnected when
|
|
its associated thread dies.
|
|
|
|
Virtual connections are especially useful in contexts such as web
|
|
servlets (see @secref["intro-servlets"]), where each request is
|
|
handled in a fresh thread. A single global virtual connection can be
|
|
defined, freeing each servlet request from explicitly opening and
|
|
closing its own connections. In particular, a @tech{virtual
|
|
connection} backed by a @tech{connection pool} combines convenience
|
|
with efficiency:
|
|
|
|
@racketblock[
|
|
(define the-connection
|
|
(virtual-connection (connection-pool (lambda () ....))))
|
|
]
|
|
|
|
The resulting virtual connection leases a connection from the pool on
|
|
demand for each servlet request thread and releases it when the thread
|
|
terminates (that is, when the request has been handled).
|
|
|
|
When given a connection produced by @racket[virtual-connection],
|
|
@racket[connected?] indicates whether there is an actual connection
|
|
associated with the current thread. Likewise, @racket[disconnect]
|
|
causes the current actual connection associated with the thread (if
|
|
there is one) to be disconnected, but the connection will be recreated
|
|
if a query function is executed.
|
|
|
|
@examples[#:eval the-eval
|
|
(eval:alts
|
|
(define c
|
|
(virtual-connection
|
|
(lambda ()
|
|
(printf "connecting!\n")
|
|
(postgresql-connect ....))))
|
|
(define c
|
|
(virtual-connection
|
|
(lambda ()
|
|
(printf "connecting!\n")
|
|
(dsn-connect 'db-scribble-env)))))
|
|
(connected? c)
|
|
(query-value c "select 1")
|
|
(connected? c)
|
|
(void (thread (lambda () (displayln (query-value c "select 2")))))
|
|
(disconnect c)
|
|
(connected? c)
|
|
(query-value c "select 3")
|
|
]
|
|
|
|
Connections produced by @racket[virtual-connection] may not be used
|
|
with the @racket[prepare] function. However, they may still be used to
|
|
execute parameterized queries expressed as strings or encapsulated via
|
|
@racket[virtual-statement].
|
|
|
|
@examples[#:eval the-eval
|
|
(prepare c "select 2 + $1")
|
|
(query-value c "select 2 + $1" 2)
|
|
(define pst (virtual-statement "select 2 + $1"))
|
|
(query-value c pst 3)
|
|
]
|
|
}
|
|
|
|
@(the-eval '(begin (set! c #f) (set! pst #f)))
|
|
|
|
@;{========================================}
|
|
|
|
@section[#:tag "kill-safe"]{Kill-safe Connections}
|
|
|
|
@declare-exporting[db db/base #:use-sources (db/base)]
|
|
|
|
@defproc[(kill-safe-connection [c connection?])
|
|
connection?]{
|
|
|
|
Creates a proxy for connection @racket[c]. All queries performed
|
|
through the proxy are kill-safe; that is, if a thread is killed during
|
|
a call to a query function such as @racket[query], the connection will
|
|
not become locked or damaged. (Connections are normally thread-safe but
|
|
not kill-safe.)
|
|
|
|
Note: A kill-safe connection whose underlying connection uses ports to
|
|
communicate with a database server is not protected from a custodian
|
|
shutting down its ports.
|
|
}
|
|
|
|
@;{========================================}
|
|
|
|
@section{Data Source Names}
|
|
|
|
@declare-exporting[db db/base #:use-sources (db/base)]
|
|
|
|
A DSN (data source name) is a symbol associated with a connection
|
|
specification in a DSN file. They are inspired by, but distinct from,
|
|
ODBC's DSNs.
|
|
|
|
@defstruct*[data-source
|
|
([connector (or/c 'postgresql 'mysql 'sqlite3 'odbc)]
|
|
[args list?]
|
|
[extensions (listof (list/c symbol? any/c))])
|
|
#:mutable]{
|
|
|
|
Represents a data source. The @racket[connector] field determines
|
|
which connection function is used to create the connection. The
|
|
@racket[args] field is a partial list of arguments passed to the
|
|
connection function; additional arguments may be added when
|
|
@racket[dsn-connect] is called. The @racket[extensions] field
|
|
contains additional information about a connection; for example,
|
|
this library's testing framework uses it to store SQL dialect
|
|
flags.
|
|
|
|
Data sources can also be created using the
|
|
@racket[postgresql-data-source], etc auxiliary functions.
|
|
}
|
|
|
|
@defproc[(dsn-connect [dsn (or/c symbol? data-source?)]
|
|
[#:dsn-file dsn-file path-string? (current-dsn-file)]
|
|
[arg any/c] ...
|
|
[#:<kw> kw-arg any/c] ...)
|
|
connection?]{
|
|
|
|
Makes a connection using the connection information associated with
|
|
@racket[dsn] in @racket[dsn-file]. The given @racket[arg]s and
|
|
@racket[kw-arg]s are added to those specified by @racket[dsn] to
|
|
form the complete arguments supplied to the connect function.
|
|
|
|
If @racket[dsn-file] does not exist, or if it contains no entry
|
|
for @racket[dsn], an exception is raised. If @racket[dsn] is a
|
|
@racket[data-source], then @racket[dsn-file] is ignored.
|
|
|
|
@fake-examples[
|
|
[(put-dsn 'pg
|
|
(postgresql-data-source #:user "me"
|
|
#:database "mydb"
|
|
#:password "icecream"))
|
|
(void)]
|
|
[(dsn-connect 'pg)
|
|
(new connection%)]
|
|
[(dsn-connect 'pg #:notice-handler (lambda (code msg) ....))
|
|
(new connection%)]
|
|
]
|
|
}
|
|
|
|
@defparam[current-dsn-file x path-string?]{
|
|
|
|
A parameter holding the location of the default DSN file. The
|
|
initial value is a file located immediately within
|
|
@racket[(find-system-path 'prefs-dir)].
|
|
}
|
|
|
|
@defproc[(get-dsn [dsn symbol?]
|
|
[default any/c #f]
|
|
[#:dsn-file dsn-file path-string? (current-dsn-file)])
|
|
(or/c data-source? any/c)]{
|
|
|
|
Returns the @racket[data-source] associated with @racket[dsn] in
|
|
@racket[dsn-file].
|
|
|
|
If @racket[dsn-file] does not exist, an exception is raised. If
|
|
@racket[dsn-file] does not have an entry for @racket[dsn],
|
|
@racket[default] is called if it is a function or returned
|
|
otherwise.
|
|
}
|
|
|
|
@defproc[(put-dsn [dsn symbol?]
|
|
[ds (or/c data-source? #f)]
|
|
[#:dsn-file dsn-file path-string? (current-dsn-file)])
|
|
void?]{
|
|
|
|
Associates @racket[dsn] with the given data source @racket[ds] in
|
|
@racket[dsn-file], replacing the previous association, if one
|
|
exists.
|
|
}
|
|
|
|
@(define absent @italic{absent})
|
|
|
|
@deftogether[[
|
|
@defproc[(postgresql-data-source
|
|
[#:user user string? @#,absent]
|
|
[#:database database string? @#,absent]
|
|
[#:server server string? @#,absent]
|
|
[#:port port exact-positive-integer? @#,absent]
|
|
[#:socket socket (or/c path-string? 'guess #f) @#,absent]
|
|
[#:password password (or/c string? #f) @#,absent]
|
|
[#:allow-cleartext-password? allow-cleartext-password? boolean? @#,absent]
|
|
[#:ssl ssl (or/c 'yes 'optional 'no) @#,absent]
|
|
[#:notice-handler notice-handler (or/c 'output 'error) @#,absent]
|
|
[#:notification-handler notification-handler (or/c 'output 'error) @#,absent])
|
|
data-source?]
|
|
@defproc[(mysql-data-source
|
|
[#:user user string? @#,absent]
|
|
[#:database database (or/c string? #f) @#,absent]
|
|
[#:server server string? @#,absent]
|
|
[#:port port exact-positive-integer? @#,absent]
|
|
[#:socket socket (or/c path-string? 'guess #f) @#,absent]
|
|
[#:ssl ssl (or/c 'yes 'optional 'no) @#,absent]
|
|
[#:password password (or/c string? #f) @#,absent]
|
|
[#:notice-handler notice-handler (or/c 'output 'error) @#,absent])
|
|
data-source?]
|
|
@defproc[(sqlite3-data-source
|
|
[#:database database (or/c path-string? 'memory 'temporary) @#,absent]
|
|
[#:mode mode (or/c 'read-only 'read/write 'create) @#,absent]
|
|
[#:busy-retry-limit busy-retry-limit
|
|
(or/c exact-nonnegative-integer? +inf.0) @#,absent]
|
|
[#:busy-retry-delay busy-retry-delay
|
|
(and/c rational? (not/c negative?)) @#,absent]
|
|
[#:use-place use-place boolean? @#,absent])
|
|
data-source?]
|
|
@defproc[(odbc-data-source
|
|
[#:dsn dsn (or/c string? #f) @#,absent]
|
|
[#:database database (or/c string? #f) @#,absent]
|
|
[#:user user (or/c string? #f) @#,absent]
|
|
[#:password password (or/c string? #f) @#,absent]
|
|
[#:notice-handler notice-handler (or/c 'output 'error) @#,absent]
|
|
[#:strict-parameter-types? strict-parameter-types? boolean? @#,absent]
|
|
[#:character-mode character-mode (or/c 'wchar 'utf-8 'latin-1) @#,absent])
|
|
data-source?]]]{
|
|
|
|
Analogues of @racket[postgresql-connect], @racket[mysql-connect],
|
|
@racket[sqlite3-connect], and @racket[odbc-connect], respectively,
|
|
that return a @racket[data-source] describing the (partial)
|
|
connection information. All arguments are optional, even those that
|
|
are mandatory in the corresponding connection function; the missing
|
|
arguments must be supplied when @racket[dsn-connect] is called.
|
|
}
|
|
|
|
|
|
@;{============================================================}
|
|
|
|
@section[#:tag "managing-connections"]{Managing Connections}
|
|
|
|
@declare-exporting[db db/base #:use-sources (db/base)]
|
|
|
|
@defproc[(connection? [x any/c])
|
|
boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[x] is a connection, @racket[#f] otherwise.
|
|
}
|
|
|
|
@defproc[(disconnect [connection connection?])
|
|
void?]{
|
|
Closes the connection.
|
|
}
|
|
|
|
@defproc[(connected? [connection connection?])
|
|
boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[connection] is connected, @racket[#f]
|
|
otherwise.
|
|
}
|
|
|
|
@defproc[(connection-dbsystem [connection connection?])
|
|
dbsystem?]{
|
|
|
|
Gets an object encapsulating information about the database system of
|
|
@racket[connection].
|
|
}
|
|
|
|
@defproc[(dbsystem? [x any/c])
|
|
boolean?]{
|
|
|
|
Predicate for objects representing database systems.
|
|
}
|
|
|
|
@defproc[(dbsystem-name [sys dbsystem?])
|
|
symbol?]{
|
|
|
|
Returns a symbol that identifies the database system. Currently one of the
|
|
following:
|
|
@itemize[
|
|
@item[@racket['postgresql]]
|
|
@item[@racket['mysql]]
|
|
@item[@racket['sqlite3]]
|
|
@item[@racket['odbc]]
|
|
]
|
|
}
|
|
|
|
@defproc[(dbsystem-supported-types [sys dbsystem?])
|
|
(listof symbol?)]{
|
|
|
|
Returns a list of symbols identifying types supported by the database
|
|
system. See @secref["db-types"].
|
|
}
|
|
|
|
|
|
@section{System-specific Modules}
|
|
|
|
The @racketmodname[db] module exports all of the
|
|
functions listed in this manual except those described in
|
|
@secref["util"]. The database system-specific connection modules are
|
|
loaded lazily to avoid unnecessary dependencies on foreign libraries.
|
|
|
|
The following modules provide subsets of the bindings described in
|
|
this manual.
|
|
|
|
@defmodule*/no-declare[(db/base)]
|
|
|
|
Provides all generic connection operations (those described in
|
|
@secref{managing-connections} and @secref{query-api}) and SQL data
|
|
support (@secref{sql-types}).
|
|
|
|
@defmodule*/no-declare[(db/postgresql)]
|
|
|
|
Provides only @racket[postgresql-connect] and
|
|
@racket[postgresql-guess-socket-path].
|
|
|
|
@defmodule*/no-declare[(db/mysql)]
|
|
|
|
Provides only @racket[mysql-connect] and
|
|
@racket[mysql-guess-socket-path].
|
|
|
|
@defmodule*/no-declare[(db/sqlite3)]
|
|
|
|
Provides @racket[sqlite3-connect] plus @racket[sqlite3-available?]. When
|
|
the SQLite native library cannot be found, @racket[sqlite3-connect]
|
|
raises an exception.
|
|
|
|
@defmodule*/no-declare[(db/odbc)]
|
|
|
|
Provides only @racket[odbc-connect], @racket[odbc-driver-connect],
|
|
@racket[odbc-data-sources], and @racket[odbc-drivers]. In contrast to
|
|
@racketmodname[db], this module immediately attempts to
|
|
load the ODBC native library when required, and it raises an exception
|
|
if it cannot be found.
|
|
|
|
|
|
@(close-eval the-eval)
|