db: fix #:group contract, fix sqlite headers
This commit is contained in:
parent
e6433084f3
commit
15e3640191
|
@ -71,3 +71,10 @@ Misc
|
|||
- connection-pool-lease-evt
|
||||
- when is it useful in practice?
|
||||
- would make it easier to handle timeouts...
|
||||
|
||||
- on insert, return last inserted id
|
||||
- postgresql: parse CommandComplete msg tag
|
||||
- mysql: in ok-packet (what conditions, though?)
|
||||
- sqlite3: sqlite3_last_insert_rowid(), use sqlite3_changes() to see if insert succeeded,
|
||||
but still need to tell if stmt was even insert (parse sql?)
|
||||
- odbc: ???
|
||||
|
|
|
@ -104,7 +104,9 @@
|
|||
[query-exec
|
||||
(->* (connection? statement?) () #:rest list? any)]
|
||||
[query-rows
|
||||
(->* (connection? statement?) () #:rest list? (listof vector?))]
|
||||
(->* (connection? statement?)
|
||||
(#:group (or/c (vectorof string?) (listof (vectorof string?))))
|
||||
#:rest list? (listof vector?))]
|
||||
[query-list
|
||||
(->* (connection? statement?) () #:rest list? list?)]
|
||||
[query-row
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
(let* ([sql (compose-statement 'query-rows c sql args 'rows)]
|
||||
[result (query/rows c 'query-rows sql #f)]
|
||||
[result
|
||||
(cond [(pair? group-fields-list)
|
||||
(cond [(not (null? group-fields-list))
|
||||
(group-rows-result* 'query-rows result group-fields-list
|
||||
(not (memq 'preserve-null-rows group-mode))
|
||||
(memq 'list group-mode))]
|
||||
|
|
|
@ -37,14 +37,13 @@
|
|||
(define/override (connected?) (and -db #t))
|
||||
|
||||
(define/public (query fsym stmt)
|
||||
(let-values ([(stmt* info rows)
|
||||
(let-values ([(stmt* result)
|
||||
(call-with-lock fsym
|
||||
(lambda ()
|
||||
(check-valid-tx-status fsym)
|
||||
(query1 fsym stmt)))])
|
||||
(statement:after-exec stmt)
|
||||
(cond [(pair? info) (rows-result info rows)]
|
||||
[else (simple-result '())])))
|
||||
result))
|
||||
|
||||
(define/private (query1 fsym stmt)
|
||||
(let* ([stmt (cond [(string? stmt)
|
||||
|
@ -64,12 +63,23 @@
|
|||
(load-param fsym db stmt i param))
|
||||
(let* ([info
|
||||
(for/list ([i (in-range (sqlite3_column_count stmt))])
|
||||
`((name ,(sqlite3_column_name stmt i))
|
||||
(decltype ,(sqlite3_column_decltype stmt i))))]
|
||||
`((name . ,(sqlite3_column_name stmt i))
|
||||
(decltype . ,(sqlite3_column_decltype stmt i))))]
|
||||
[rows (step* fsym db stmt)])
|
||||
(HANDLE fsym (sqlite3_reset stmt))
|
||||
(HANDLE fsym (sqlite3_clear_bindings stmt))
|
||||
(values stmt info rows)))))
|
||||
(values stmt
|
||||
(cond [(pair? info)
|
||||
(rows-result info rows)]
|
||||
[else
|
||||
(let ([changes (sqlite3_changes db)])
|
||||
(cond [(and (positive? changes)
|
||||
#f ;; Note: currently disabled
|
||||
#| FIXME: statement was INSERT stmt |#)
|
||||
(simple-result
|
||||
(list (cons 'last-insert-rowid
|
||||
(sqlite3_last_insert_rowid db))))]
|
||||
[else (simple-result '())]))]))))))
|
||||
|
||||
(define/private (load-param fsym db stmt i param)
|
||||
(HANDLE fsym
|
||||
|
@ -203,7 +213,7 @@
|
|||
(let ([db (get-db fsym)])
|
||||
(when (get-tx-status db)
|
||||
(error/already-in-tx fsym))
|
||||
(let-values ([(stmt* _info _rows)
|
||||
(let-values ([(stmt* _result)
|
||||
(query1 fsym "BEGIN TRANSACTION")])
|
||||
stmt*))))])
|
||||
(statement:after-exec stmt)
|
||||
|
@ -217,7 +227,7 @@
|
|||
(unless (eq? mode 'rollback)
|
||||
(check-valid-tx-status fsym))
|
||||
(when (get-tx-status db)
|
||||
(let-values ([(stmt* _info _rows)
|
||||
(let-values ([(stmt* _result)
|
||||
(case mode
|
||||
((commit)
|
||||
(query1 fsym "COMMIT TRANSACTION"))
|
||||
|
@ -235,14 +245,11 @@
|
|||
;; schema ignored, because sqlite doesn't support
|
||||
(string-append "SELECT tbl_name from sqlite_master "
|
||||
"WHERE type = 'table' or type = 'view'")])
|
||||
(let-values ([(stmt rows)
|
||||
(let-values ([(stmt result)
|
||||
(call-with-lock fsym
|
||||
(lambda ()
|
||||
(let-values ([(stmt _info rows)
|
||||
(query1 fsym stmt)])
|
||||
(values stmt rows))))])
|
||||
(lambda () (query1 fsym stmt)))])
|
||||
(statement:after-exec stmt)
|
||||
(for/list ([row (in-list rows)])
|
||||
(for/list ([row (in-list (rows-result-rows result))])
|
||||
(vector-ref row 0)))))
|
||||
|
||||
;; ----
|
||||
|
|
|
@ -140,6 +140,14 @@
|
|||
(_fun _sqlite3_statement
|
||||
-> _string))
|
||||
|
||||
(define-sqlite sqlite3_changes
|
||||
(_fun _sqlite3_database
|
||||
-> _int))
|
||||
|
||||
(define-sqlite sqlite3_last_insert_rowid
|
||||
(_fun _sqlite3_database
|
||||
-> _int))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
#|
|
||||
|
|
|
@ -26,17 +26,15 @@ native client library is required.}
|
|||
|
||||
@item{@bold{@as-index{@hyperlink["http://www.sqlite.org"]{SQLite}} version
|
||||
3.} The SQLite native client library is required; see
|
||||
@secref["sqlite3-native-libs"].}
|
||||
@secref["sqlite3-requirements"].}
|
||||
|
||||
@item{@bold{@as-index{ODBC}.} An ODBC Driver Manager and appropriate
|
||||
ODBC drivers are required; see @secref["odbc-native-libs"]. The
|
||||
following additional database systems are known to work with this
|
||||
library's ODBC support (see @secref["odbc-status"] for details):
|
||||
@itemlist[
|
||||
@item{@bold{@as-index{@hyperlink["http://www.oracle.com"]{Oracle}}}}
|
||||
@item{@bold{@as-index{@hyperlink["http://www.ibm.com/software/data/db2/"]{DB2}}}}
|
||||
@item{@bold{@as-index{@hyperlink["http://www.microsoft.com/sqlserver/"]{SQL Server}}}}
|
||||
]}
|
||||
ODBC drivers are required; see @secref["odbc-requirements"]. The
|
||||
following database systems are known to work with this library via
|
||||
ODBC (see @secref["odbc-status"] for details):
|
||||
@bold{@as-index{@hyperlink["http://www.ibm.com/software/data/db2/"]{DB2}}},
|
||||
@bold{@as-index{@hyperlink["http://www.oracle.com"]{Oracle}}}, and
|
||||
@bold{@as-index{@hyperlink["http://www.microsoft.com/sqlserver/"]{SQL Server}}}.}
|
||||
]
|
||||
|
||||
The query operations are functional in spirit: queries return results
|
||||
|
|
|
@ -4,25 +4,27 @@
|
|||
scribble/struct
|
||||
racket/sandbox
|
||||
"config.rkt"
|
||||
(for-label db))
|
||||
(for-label db
|
||||
setup/dirs))
|
||||
|
||||
@title[#:tag "notes"]{Notes}
|
||||
|
||||
This section describes miscellaneous issues.
|
||||
This section discusses issues related to specific database systems.
|
||||
|
||||
|
||||
@section[#:tag "connecting-to-server"]{Local Sockets for PostgreSQL and MySQL Servers}
|
||||
|
||||
PostgreSQL and MySQL servers are sometimes configured by default to
|
||||
listen only on local sockets (also called ``unix domain
|
||||
sockets''). This library provides support for communication over local
|
||||
sockets, but only on Linux (x86 and x86-64) and Mac OS X. If local
|
||||
socket communication is not available, the server must be reconfigured
|
||||
to listen on a TCP port.
|
||||
sockets on Linux (x86 and x86-64) and Mac OS X. If local socket
|
||||
communication is not available, the server must be reconfigured to
|
||||
listen on a TCP port.
|
||||
|
||||
The socket file for a PostgreSQL server is located in the directory
|
||||
specified by the @tt{unix_socket_directory} variable in the
|
||||
@tt{postgresql.conf} server configuration file. For example, on
|
||||
Ubuntu 10.10 running PostgreSQL 8.4, the socket directory is
|
||||
Ubuntu 11.04 running PostgreSQL 8.4, the socket directory is
|
||||
@tt{/var/run/postgresql} and the socket file is
|
||||
@tt{/var/run/postgresql/.s.PGSQL.5432}. Common socket paths may be
|
||||
searched automatically using the @racket[postgresql-guess-socket-path]
|
||||
|
@ -30,20 +32,19 @@ function.
|
|||
|
||||
The socket file for a MySQL server is located at the path specified by
|
||||
the @tt{socket} variable in the @tt{my.cnf} configuration file. For
|
||||
example, on Ubuntu 10.10 running MySQL 5.1, the socket is located at
|
||||
example, on Ubuntu 11.04 running MySQL 5.1, the socket is located at
|
||||
@tt{/var/run/mysqld/mysqld.sock}. Common socket paths for MySQL can be
|
||||
searched using the @racket[mysql-guess-socket-path] function.
|
||||
|
||||
|
||||
@section{Database Character Encodings}
|
||||
@section{PostgreSQL Database Character Encoding}
|
||||
|
||||
In most cases, a PostgreSQL or MySQL database's character encoding is
|
||||
irrelevant, since the connect function always requests translation to
|
||||
Unicode (UTF-8) when creating a connection. If a PostgreSQL database's
|
||||
character encoding is @tt{SQL_ASCII}, however, PostgreSQL will not
|
||||
honor the connection encoding; it will instead send untranslated
|
||||
octets, which will cause corrupt data or internal errors in the client
|
||||
connection.
|
||||
In most cases, a database's character encoding is irrelevant, since
|
||||
the connect function always requests translation to Unicode (UTF-8)
|
||||
when creating a connection. If a PostgreSQL database's character
|
||||
encoding is @tt{SQL_ASCII}, however, PostgreSQL will not honor the
|
||||
connection encoding; it will instead send untranslated octets, which
|
||||
will cause corrupt data or internal errors in the client connection.
|
||||
|
||||
To convert a PostgreSQL database from @tt{SQL_ASCII} to something
|
||||
sensible, @tt{pg_dump} the database, recode the dump file (using a
|
||||
|
@ -51,31 +52,17 @@ utility such as @tt{iconv}), create a new database with the desired
|
|||
encoding, and @tt{pg_restore} from the recoded dump file.
|
||||
|
||||
|
||||
@section{Prepared Query Parameter Types}
|
||||
|
||||
Different database systems vary in their handling of query parameter
|
||||
types. For example, consider the following parameterized SQL
|
||||
statement:
|
||||
|
||||
@tt{SELECT 1 + ?;}
|
||||
|
||||
PostgreSQL reports an expected type of @tt{integer} for the parameter and
|
||||
will not accept other types. MySQL and SQLite, in contrast, report no
|
||||
useful parameter type information, and ODBC connections vary in
|
||||
behavior based on the driver, the data source configuration, and the
|
||||
connection parameters (see @secref["odbc-status"] for specific notes).
|
||||
|
||||
|
||||
@section{PostgreSQL Authentication}
|
||||
|
||||
PostgreSQL supports a large variety of authentication mechanisms,
|
||||
controlled by the @tt{pg_hba.conf} server configuration file. This
|
||||
library currently supports only cleartext and md5-hashed passwords,
|
||||
and it does not send cleartext passwords unless explicitly ordered to
|
||||
(see @racket[postgresql-connect]). These correspond to the @tt{md5}
|
||||
and @tt{password} authentication methods in the parlance of
|
||||
PostgreSQL supports a large variety of
|
||||
@hyperlink["http://www.postgresql.org/docs/8.4/static/auth-pg-hba-conf.html"]{authentication
|
||||
mechanisms}, controlled by the @tt{pg_hba.conf} server configuration
|
||||
file. This library currently supports only cleartext and md5-hashed
|
||||
passwords, and it does not send cleartext passwords unless explicitly
|
||||
ordered to (see @racket[postgresql-connect]). These correspond to the
|
||||
@tt{md5} and @tt{password} authentication methods in the parlance of
|
||||
@tt{pg_hba.conf}, respectively. On Linux, @tt{ident} authentication is
|
||||
automatically supported for unix domain sockets (but not TCP). The
|
||||
automatically supported for local sockets, but not TCP sockets. The
|
||||
@tt{gss}, @tt{sspi}, @tt{krb5}, @tt{pam}, and @tt{ldap} methods are
|
||||
not supported.
|
||||
|
||||
|
@ -89,36 +76,69 @@ plugins}. The only plugin currently supported by this library is
|
|||
password authentication mechanism used since version 4.1.
|
||||
|
||||
|
||||
@section[#:tag "sqlite3-native-libs"]{SQLite Native Library}
|
||||
@section[#:tag "sqlite3-requirements"]{SQLite Requirements}
|
||||
|
||||
SQLite support requires the appropriate native library, specifically
|
||||
@tt{libsqlite3.so.0} on Unix or @tt{sqlite3.dll} on Windows.
|
||||
SQLite support requires the appropriate native library.
|
||||
|
||||
@itemlist[
|
||||
|
||||
@item{On Windows, the library is @tt{sqlite3.dll}. It can be obtained
|
||||
from @hyperlink["http://www.sqlite.org/download.html"]{the SQLite
|
||||
download page}; the DLL file should be extracted and placed into one
|
||||
of the directories produced by
|
||||
@racketblock[(begin (require setup/dirs) (get-lib-search-dirs))]}
|
||||
|
||||
@item{On Mac OS X, the library is @tt{libsqlite3.0.dylib}, which is
|
||||
included (in @tt{/usr/lib}) in Mac OS X version 10.4 onwards.}
|
||||
|
||||
@item{On Linux, the library is @tt{libsqlite3.so.0}. It is included in
|
||||
the @tt{libsqlite3-0} package in Debian/Ubuntu and in the @tt{sqlite}
|
||||
package in Red Hat.}
|
||||
]
|
||||
|
||||
|
||||
@section[#:tag "odbc-native-libs"]{ODBC Native Libraries}
|
||||
@section[#:tag "odbc-requirements"]{ODBC Requirements}
|
||||
|
||||
ODBC support requires the appropriate native library, specifically
|
||||
@tt{libodbc.so.1} (from unixODBC; iODBC is not supported) on Unix or
|
||||
@tt{odbc32.dll} on Windows. In addition, the appropriate ODBC Drivers
|
||||
must be installed and any Data Sources configured.
|
||||
ODBC requires the appropriate driver manager native library as well as
|
||||
driver native libraries for each database system you want use ODBC to
|
||||
connect to.
|
||||
|
||||
@itemlist[
|
||||
|
||||
@item{On Windows, the driver manager is @tt{odbc32.dll}, which is
|
||||
included automatically with Windows.}
|
||||
|
||||
@item{On Mac OS X, the driver manager is @tt{libiodbc.2.dylib}
|
||||
(@hyperlink["http://www.iodbc.org"]{iODBC}), which is included (in
|
||||
@tt{/usr/lib}) in Mac OS X version 10.2 onwards.}
|
||||
|
||||
@item{On Linux, the driver manager is @tt{libodbc.so.1}
|
||||
(@hyperlink["http://www.unixodbc.org"]{unixODBC}---iODBC is not
|
||||
supported). It is available from the @tt{unixodbc} package in
|
||||
Debian/Ubuntu and in the @tt{unixODBC} package in Red Hat.}
|
||||
]
|
||||
|
||||
In addition, you must install the appropriate ODBC Drivers and
|
||||
configure Data Sources. Refer to the ODBC documentation for the
|
||||
specific database system for more information.
|
||||
|
||||
|
||||
@section[#:tag "odbc-status"]{ODBC Support Status}
|
||||
@section[#:tag "odbc-status"]{ODBC Status}
|
||||
|
||||
ODBC support is experimental. This library is compatible only with
|
||||
ODBC 3.x Driver Managers. The behavior of ODBC connections can vary
|
||||
widely depending on the driver in use and even the configuration of a
|
||||
particular data source.
|
||||
ODBC support is experimental. The behavior of ODBC connections can
|
||||
vary widely depending on the driver in use and even the configuration
|
||||
of a particular data source.
|
||||
|
||||
The following sections describe the configurations that this library
|
||||
has been tested with. The platform @bold{win32} means Windows Vista on
|
||||
a 32-bit processor and @bold{linux} means Ubuntu 11.04 and unixODBC on
|
||||
both x86 (32-bit) and x86-64 processors, unless otherwise
|
||||
specified. The iODBC Driver Manager is not supported.
|
||||
has been tested with.
|
||||
|
||||
Reports of success or failure on other platforms or with other drivers
|
||||
would be appreciated.
|
||||
|
||||
@;{
|
||||
** There's no reason to actually use the following drivers. They're just
|
||||
** useful for testing ODBC support.
|
||||
|
||||
@subsection{PostgreSQL ODBC Driver}
|
||||
|
||||
The PostgreSQL ODBC driver version 09.00.0300 has been tested on
|
||||
|
@ -149,15 +169,18 @@ Furthermore, this driver interprets the declared types of columns
|
|||
strictly, replacing nonconforming values in query results with
|
||||
@tt{NULL}. All computed columns, even those with explicit @tt{CAST}s,
|
||||
seem to be returned as @tt{text}.
|
||||
}
|
||||
|
||||
@subsection{DB2 ODBC Driver}
|
||||
|
||||
The driver from IBM DB2 Express-C v9.7 has been tested on @bold{linux}
|
||||
The driver from IBM DB2 Express-C v9.7 has been tested on Ubuntu 11.04
|
||||
(32-bit only).
|
||||
|
||||
For a typical installation where the instance resides at
|
||||
@tt{/home/db2inst1}, set the following option in the Driver
|
||||
configuration: @tt{Driver = /home/db2inst1/sqllib/lib32/libdb2.so}.
|
||||
configuration: @tt{Driver =
|
||||
/home/db2inst1/sqllib/lib32/libdb2.so}. (The path would presumably be
|
||||
different for a 64-bit installation.)
|
||||
|
||||
The DB2 driver does not seem to accept a separate argument for the
|
||||
database to connect to; it must be the same as the Data Source name.
|
||||
|
@ -165,7 +188,7 @@ database to connect to; it must be the same as the Data Source name.
|
|||
@subsection{Oracle ODBC Driver}
|
||||
|
||||
The driver from Oracle Database 10g Release 2 Express Edition has been
|
||||
tested on @bold{linux} (32-bit only).
|
||||
tested on Ubuntu 11.04 (32-bit only).
|
||||
|
||||
It seems the @tt{ORACLE_HOME} and @tt{LD_LIBRARY_PATH} environment
|
||||
variables must be set according to the @tt{oracle_env.{csh,sh}} script
|
||||
|
@ -185,5 +208,5 @@ Maybe Oracle bug? See:
|
|||
|
||||
@subsection{SQL Server ODBC Driver}
|
||||
|
||||
Basic SQL Server support has been verified on @bold{win32}, but the
|
||||
automated test suite has not yet been adapted and run.
|
||||
Basic SQL Server support has been verified on Windows (32-bit only),
|
||||
but the automated test suite has not yet been adapted and run.
|
||||
|
|
Loading…
Reference in New Issue
Block a user