364 lines
9.7 KiB
Plaintext
364 lines
9.7 KiB
Plaintext
|
ODBC support for scsh 0.6.x
|
||
|
===========================
|
||
|
|
||
|
This directory contains bindings to Unix ODBC libraries, which make it
|
||
|
possible to call any ODBC functions from scsh directly. At the moment
|
||
|
ODBC support is not part of the scsh distribution, since ODBC support
|
||
|
is in an early stage of development -- to put it another way, it's for
|
||
|
thrill seekers only! The code is complete, but needs testing. So,
|
||
|
please let us know if you find a bug. ODBC supports also lacks some
|
||
|
documentation.
|
||
|
|
||
|
1. Building scsh with ODBC support
|
||
|
|
||
|
I recommend to use the scsh version from CVS. However, it might work
|
||
|
with scsh-releases 0.6.1 or newer to. Be sure to have a ODBC
|
||
|
implementation for Unix, like unixODBC or iODBC -- both seem to work
|
||
|
fine. Apply the following patch:
|
||
|
|
||
|
Index: autogen.sh
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/scsh/scsh-0.6/autogen.sh,v
|
||
|
retrieving revision 1.7
|
||
|
diff -r1.7 autogen.sh
|
||
|
5c5
|
||
|
< ./configure &&
|
||
|
---
|
||
|
> ./configure --with-iODBC=/usr/lib &&
|
||
|
15,16c15
|
||
|
< make build/initial.image &&
|
||
|
< make distclean
|
||
|
---
|
||
|
> make build/initial.image
|
||
|
Index: configure.in
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/scsh/scsh-0.6/configure.in,v
|
||
|
retrieving revision 1.27
|
||
|
diff -r1.27 configure.in
|
||
|
397c397,420
|
||
|
<
|
||
|
---
|
||
|
> AC_ARG_WITH(unixODBC,
|
||
|
> [ --with-unixODBC=DIR Support for unixODBC ],
|
||
|
> [ with_unixodbc=$withval ],
|
||
|
> [ with_unixodbc=no ]
|
||
|
> )
|
||
|
> if test "$with_unixodbc" != no; then
|
||
|
> odbc_includes="-I$with_unixodbc/include"
|
||
|
> odbc_libs="-lodbc -L$with_unixodbc/lib"
|
||
|
> AC_SUBST(odbc_includes)
|
||
|
> AC_SUBST(odbc_libs)
|
||
|
> fi
|
||
|
>
|
||
|
> AC_ARG_WITH(iODBC,
|
||
|
> [ --with-iODBC=DIR Support for iODBC ],
|
||
|
> [ with_iodbc=$with_iodbc ],
|
||
|
> [ with_iodbc=no ]
|
||
|
> )
|
||
|
> if test "$with_iodbc" != no; then
|
||
|
> odbc_includes="-I$with_iodbc/include"
|
||
|
> odbc_libs="-liodbc -L$with_iodbc/lib"
|
||
|
> AC_SUBST(odbc_includes)
|
||
|
> AC_SUBST(odbc_libs)
|
||
|
> fi
|
||
|
>
|
||
|
Index: Makefile.in
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/scsh/scsh-0.6/Makefile.in,v
|
||
|
retrieving revision 1.59
|
||
|
diff -r1.59 Makefile.in
|
||
|
11,12c11,12
|
||
|
< LIBS = @LIBS@
|
||
|
< CFLAGS = @CFLAGS@
|
||
|
---
|
||
|
> LIBS = @LIBS@ @odbc_libs@
|
||
|
> CFLAGS = @CFLAGS@ @odbc_includes@
|
||
|
50c50,51
|
||
|
< BUILD_RUNNABLE = /afs/wsi/i386_fbsd32/bin/scheme48
|
||
|
---
|
||
|
> BUILD_RUNNABLE = /afs/wsi/ppc_macx55/scheme48-0.53/bin/scheme48
|
||
|
> #BUILD_RUNNABLE = /afs/wsi/ppc_macx55/scheme48-0.53/bin/scheme48
|
||
|
136c137
|
||
|
< scsh/md5.o
|
||
|
---
|
||
|
> scsh/md5.o
|
||
|
172,173c173,175
|
||
|
< EXTERNAL_OBJECTS = $(SOCKET_OBJECTS) $(LOOKUP_OBJECTS)
|
||
|
< EXTERNAL_FLAGS = $(SOCKET_FLAGS)
|
||
|
---
|
||
|
> EXTERNAL_OBJECTS = $(SOCKET_OBJECTS) $(LOOKUP_OBJECTS) $(ODBC_OBJECTS)
|
||
|
> EXTERNAL_FLAGS = $(SOCKET_FLAGS) $(ODBC_FLAGS)
|
||
|
> EXTERNAL_LDFLAGS = $(SOCKET_LD_FLAGS) $(ODBC_LD_FLAGS)
|
||
|
176a179
|
||
|
> $(ODBC_INITIALIZERS) \
|
||
|
181a185,189
|
||
|
> scsh/odbc/odbc.o: scsh/odbc/odbc.h
|
||
|
>
|
||
|
> ODBC_OBJECTS = scsh/odbc/odbc.o
|
||
|
> ODBC_INITIALIZERS = s48_init_odbc
|
||
|
>
|
||
|
838c846,847
|
||
|
< scsh/rx/regress.scm
|
||
|
---
|
||
|
> scsh/rx/regress.scm \
|
||
|
> scsh/odbc/odbc.scm
|
||
|
|
||
|
This will add some rules to Makefile and add two options to configure:
|
||
|
--with-iODBC=PATH and --with-unixODBC=PATH.
|
||
|
|
||
|
This patch will add a module odbc to the package configuration. With
|
||
|
this patch, it's possible to type ,open odbc at the scsh prompt to
|
||
|
load all the beautiful ODBC functions into scsh:
|
||
|
|
||
|
Index: scsh-package.scm
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/scsh/scsh-0.6/scsh/scsh-package.scm,v
|
||
|
retrieving revision 1.59
|
||
|
diff -r1.59 scsh-package.scm
|
||
|
599a600,617
|
||
|
>
|
||
|
> ;;; ODBC stuff
|
||
|
>
|
||
|
> (define-structure odbc-data-types odbc-data-types-interface
|
||
|
> (open
|
||
|
> scheme define-structure
|
||
|
> external-calls)
|
||
|
> (files (odbc odbc-types)))
|
||
|
>
|
||
|
> (define-structure odbc odbc-interface
|
||
|
> (open
|
||
|
> scheme define-record-types
|
||
|
> external-calls
|
||
|
> scsh-utilities
|
||
|
> conditions signals)
|
||
|
> (files (odbc odbc)
|
||
|
> (odbc odbc-bindcol)))
|
||
|
>
|
||
|
Index: scsh-interfaces.scm
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/scsh/scsh-0.6/scsh/scsh-interfaces.scm,v
|
||
|
retrieving revision 1.53
|
||
|
diff -r1.53 scsh-interfaces.scm
|
||
|
1169,1175c1169,1175
|
||
|
< (export uname
|
||
|
< uname:os-name
|
||
|
< uname:node-name
|
||
|
< uname:release
|
||
|
< uname:version
|
||
|
< uname:machine
|
||
|
< type/uname))
|
||
|
---
|
||
|
> (export uname
|
||
|
> uname:os-name
|
||
|
> uname:node-name
|
||
|
> uname:release
|
||
|
> uname:version
|
||
|
> uname:machine
|
||
|
> type/uname))
|
||
|
1277a1278,1366
|
||
|
>
|
||
|
> ;;; ODBC stuff
|
||
|
> (define-interface odbc-data-types-interface
|
||
|
> (export
|
||
|
>
|
||
|
> make-sql-date
|
||
|
> sql-date?
|
||
|
> sql-date-year
|
||
|
> sql-date-month
|
||
|
> sql-date-day
|
||
|
>
|
||
|
> make-sql-time
|
||
|
> sql-time?
|
||
|
> sql-time-hour
|
||
|
> sql-time-minute
|
||
|
> sql-time-second
|
||
|
>
|
||
|
> make-sql-timestamp
|
||
|
> sql-timestamp?
|
||
|
> sql-timestamp-year
|
||
|
> sql-timestamp-month
|
||
|
> sql-timestamp-day
|
||
|
> sql-timestamp-hour
|
||
|
> sql-timestamp-minute
|
||
|
> sql-timestamp-second
|
||
|
> sql-timestamp-fraction
|
||
|
>
|
||
|
> make-sql-numeric
|
||
|
> sql-numeric?
|
||
|
> sql-numeric-precision
|
||
|
> sql-numeric-scale
|
||
|
> sql-numeric-sign
|
||
|
> sql-numeric-value))
|
||
|
>
|
||
|
> (define-interface odbc-interface
|
||
|
> (export
|
||
|
> odbc-handle?
|
||
|
> environment-handle?
|
||
|
> connection-handle?
|
||
|
> statement-handle?
|
||
|
> descriptor-handle?
|
||
|
>
|
||
|
> odbc-alloc-environment-handle
|
||
|
> odbc-alloc-connection-handle
|
||
|
> odbc-alloc-statement-handle
|
||
|
> odbc-sql-connect
|
||
|
>
|
||
|
> odbc-sql-data-sources
|
||
|
> odbc-sql-drivers
|
||
|
> odbc-sql-get-info-int
|
||
|
> odbc-sql-get-info-string
|
||
|
> odbc-sql-get-func
|
||
|
> odbc-sql-get-type-info
|
||
|
>
|
||
|
> odbc-sql-set-connect-attr-int
|
||
|
> odbc-sql-set-connect-attr-string
|
||
|
> odbc-sql-get-connect-attr-string
|
||
|
> odbc-sql-get-connect-attr-int
|
||
|
> odbc-sql-set-env-attr-int
|
||
|
> odbc-sql-get-env-attr-int
|
||
|
> odbc-sql-set-stmt-attr-int
|
||
|
> odbc-sql-get-stmt-attr-int
|
||
|
>
|
||
|
> odbc-sql-prepare
|
||
|
> odbc-sql-bind-parameter-exec-out
|
||
|
> odbc-sql-get-cursor-name
|
||
|
> odbc-sql-set-cursor-name
|
||
|
>
|
||
|
> odbc-sql-execute
|
||
|
> odbc-sql-execute-direct
|
||
|
>
|
||
|
> odbc-sql-row-count
|
||
|
> odbc-sql-get-data
|
||
|
> odbc-sql-fetch
|
||
|
>
|
||
|
> odbc-sql-free-statement
|
||
|
> odbc-sql-close-cursor
|
||
|
> odbc-sql-cancel
|
||
|
> odbc-sql-num-result-cols
|
||
|
> odbc-sql-describe-col
|
||
|
>
|
||
|
> odbc-sql-disconnect
|
||
|
> odbc-sql-free-handle
|
||
|
>
|
||
|
> odbc-buffer-exceeded?
|
||
|
> signal-buffer-exceeded
|
||
|
> odbc-unbound-column?
|
||
|
> signal-unbound-column
|
||
|
> odbc-sql-bindcol))
|
||
|
|
||
|
Now it's time to build scsh. Edit the call to configure in autgen.sh to
|
||
|
your needs, e.g.:
|
||
|
|
||
|
./configure --with-iODBC=/usr/local &&
|
||
|
|
||
|
Don't forget the && at the end of line! Now, run autogen.sh to build
|
||
|
the VM and all that stuff. Run make to build scsh. If the build
|
||
|
suceeds, tap yourself on the shoulder, that's important, it might the
|
||
|
last sense of achievement from now on.
|
||
|
|
||
|
2. Running scsh with ODBC support
|
||
|
|
||
|
Type ./scshvm -i scsh/scsh.image -- that's it!
|
||
|
|
||
|
3. How do I use ODBC support?
|
||
|
|
||
|
If you installed the odbc-module-patch, simply type ,open odbc. If you
|
||
|
have installed dynamic ODBC libraries make sure your system can find
|
||
|
them, e.g. put the path in your LD_LIBRARY_PATH. This should look like
|
||
|
this:
|
||
|
|
||
|
[knauel@jimi scsh-0.6.cvs] ./scshvm -i scsh/scsh.image
|
||
|
Welcome to scsh 0.6.3 (Health Reform)
|
||
|
Type ,? for help.
|
||
|
> ,open odbc
|
||
|
Load structure odbc (y/n)? y
|
||
|
[odbc ./scsh/odbc/odbc-bindcol.scm ./scsh/odbc/odbc.scm]
|
||
|
> ,exit
|
||
|
|
||
|
This is an example entry for ~/.odbc.ini:
|
||
|
|
||
|
[test]
|
||
|
DSN = mysql1
|
||
|
Driver = /afs/informatik.uni-tuebingen.de/pu/src/build/knauel/i386_fbsd43/lib/libmyodbc3.so
|
||
|
Server = localhost
|
||
|
Port = 3306
|
||
|
User = odbc
|
||
|
Password= geheim
|
||
|
TraceFile= stderr
|
||
|
Trace = on
|
||
|
|
||
|
It may be necessary to help your ODBC driver manager to find that file
|
||
|
be setting the environment variable ODBCINI.
|
||
|
|
||
|
Let's see what data sources are known to the system:
|
||
|
|
||
|
(let* ((env-handle (odbc-alloc-environment-handle))
|
||
|
(data-sources (odbc-sql-data-sources env-handle)))
|
||
|
(for-each
|
||
|
(lambda (pair)
|
||
|
(display "data source: ")
|
||
|
(display (car pair))
|
||
|
(newline)
|
||
|
(display "using driver: ")
|
||
|
(display (cdr pair))
|
||
|
(newline))
|
||
|
data-sources))
|
||
|
|
||
|
Don't worry about freeing handles -- this will happen automatically
|
||
|
when the scheme variable gets garbage collected.
|
||
|
|
||
|
This example shows how you can read the information from ODBC's
|
||
|
diag-recs in case an error occurs, which is to happen very likely:
|
||
|
|
||
|
(define (display-errors handle)
|
||
|
(let ((recs (odbc-sql-get-diag-recs handle)))
|
||
|
(if (not (null? recs))
|
||
|
(for-each (lambda (rec)
|
||
|
(newline)
|
||
|
(display "state: ")
|
||
|
(display (odbc-diag-sql-state rec))
|
||
|
(newline)
|
||
|
(display "native error: ")
|
||
|
(display (odbc-diag-native-error rec))
|
||
|
(newline)
|
||
|
(display "message: ")
|
||
|
(display (odbc-diag-message rec))
|
||
|
(newline))
|
||
|
recs)
|
||
|
(begin
|
||
|
(display "No error messages (so far ;-)")
|
||
|
(newline)))))
|
||
|
|
||
|
Not let's read some stuff from the database! Say we have a database
|
||
|
with four columns a through d, where a,b,c are integer columns and d
|
||
|
is text. Using the fancy odbc-sql-bindcol functions that's pretty
|
||
|
easy:
|
||
|
|
||
|
(define env-handle
|
||
|
(odbc-alloc-environment-handle))
|
||
|
|
||
|
(define conn-handle
|
||
|
(odbc-alloc-connection-handle env-handle))
|
||
|
|
||
|
(odbc-sql-connect conn-handle "test" "odbc" "geheim")
|
||
|
|
||
|
(define stmt-handle (odbc-alloc-statement-handle conn-handle))
|
||
|
|
||
|
(odbc-sql-execute-direct stmt-handle "select * from abc")
|
||
|
|
||
|
(define col-a (odbc-sql-bindcol stmt-handle 1 sql-type-c-long 1))
|
||
|
(define col-b (odbc-sql-bindcol stmt-handle 2 sql-type-c-long 1))
|
||
|
(define col-c (odbc-sql-bindcol stmt-handle 3 sql-type-c-long 1))
|
||
|
(define col-d (odbc-sql-bindcol stmt-handle 4 sql-type-c-char 400))
|
||
|
|
||
|
(let lp ((retcode (odbc-sql-fetch stmt-handle))
|
||
|
(result '()))
|
||
|
(if (equal? retcode sql-no-data)
|
||
|
result
|
||
|
(lp (odbc-sql-fetch stmt-handle)
|
||
|
(cons (list (col-a) (col-b) (col-c) (col-d)) result))))
|
||
|
|
||
|
Please let me know, if you find some bugs. I hereby promise to
|
||
|
complete the documentation as soon as possible!
|
||
|
|
||
|
Eric Knauel <knauel@informatik.uni-tuebingen.de>
|