428 lines
12 KiB
Plaintext
428 lines
12 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 -u -r1.7 autogen.sh
|
|
--- autogen.sh 12 Feb 2002 16:26:05 -0000 1.7
|
|
+++ autogen.sh 20 Mar 2003 16:01:57 -0000
|
|
@@ -2,7 +2,7 @@
|
|
|
|
autoheader &&
|
|
autoconf &&
|
|
-./configure &&
|
|
+./configure --with-iODBC=/usr/lib &&
|
|
touch scsh/*.c &&
|
|
touch build/filenames.scm &&
|
|
rm -f scheme48.image cig/cig.image scsh/scsh.image &&
|
|
@@ -12,5 +12,4 @@
|
|
make i-know-what-i-am-doing &&
|
|
make c/scheme48.h&&
|
|
make linker &&
|
|
-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 -u -r1.27 configure.in
|
|
--- configure.in 13 Dec 2002 15:22:13 -0000 1.27
|
|
+++ configure.in 20 Mar 2003 16:01:57 -0000
|
|
@@ -394,7 +394,30 @@
|
|
AC_SUBST(LIBS)
|
|
AC_SUBST(TMPDIR)
|
|
|
|
-
|
|
+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
|
|
+
|
|
AC_CONFIG_FILES(Makefile scsh/endian.scm scsh-config)
|
|
AC_CONFIG_COMMANDS([scsh-config+x],[chmod +x scsh-config])
|
|
AC_OUTPUT
|
|
Index: Makefile.in
|
|
===================================================================
|
|
RCS file: /cvsroot/scsh/scsh-0.6/Makefile.in,v
|
|
retrieving revision 1.59
|
|
diff -u -r1.59 Makefile.in
|
|
--- Makefile.in 13 Jan 2003 06:17:49 -0000 1.59
|
|
+++ Makefile.in 20 Mar 2003 16:01:57 -0000
|
|
@@ -8,8 +8,8 @@
|
|
VPATH = @srcdir@
|
|
CC = @CC@
|
|
DEFS = @DEFS@
|
|
-LIBS = @LIBS@
|
|
-CFLAGS = @CFLAGS@
|
|
+LIBS = @LIBS@ @odbc_libs@
|
|
+CFLAGS = @CFLAGS@ @odbc_includes@
|
|
INSTALL = @INSTALL@
|
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
INSTALL_DATA = @INSTALL_DATA@
|
|
@@ -47,7 +47,8 @@
|
|
# BUILD_RUNNABLE has to be Scheme 48 0.53. This is used for builds directly
|
|
# out of the CVS repository.
|
|
# We cannot use Scsh here since -i is not understood.
|
|
-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
|
|
RUNNABLE = scsh
|
|
MANPAGE = $(RUNNABLE).$(manext)
|
|
LIB = $(libdir)/$(RUNNABLE)
|
|
@@ -133,7 +134,7 @@
|
|
scsh/userinfo1.o \
|
|
scsh/sighandlers1.o \
|
|
scsh/libscsh.o \
|
|
- scsh/md5.o
|
|
+ scsh/md5.o
|
|
|
|
SCSH_INITIALIZERS = s48_init_syslog s48_init_posix_regexp \
|
|
s48_init_userinfo s48_init_sighandlers \
|
|
@@ -169,16 +170,23 @@
|
|
# External code to include in the VM
|
|
# After changing any of these you should delete `scheme48vm' and remake it.
|
|
|
|
-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)
|
|
EXTERNAL_INITIALIZERS = $(ADDITIONAL_INITIALIZER) $(SOCKET_INITIALIZERS) \
|
|
$(LOOKUP_INITIALIZERS) \
|
|
$(SCSH_INITIALIZERS) $(SRFI_INITIALIZERS) \
|
|
+ $(ODBC_INITIALIZERS) \
|
|
s48_init_cig
|
|
|
|
|
|
# Rules for any external code.
|
|
|
|
+scsh/odbc/odbc.o: scsh/odbc/odbc.h
|
|
+
|
|
+ODBC_OBJECTS = scsh/odbc/odbc.o
|
|
+ODBC_INITIALIZERS = s48_init_odbc
|
|
+
|
|
# Socket rules
|
|
|
|
c/unix/socket.o: c/scheme48.h c/fd-io.h c/event.h
|
|
@@ -835,7 +843,8 @@
|
|
scsh/rx/re-high.scm \
|
|
scsh/rx/regexp.scm \
|
|
scsh/rx/re-low.scm \
|
|
- scsh/rx/regress.scm
|
|
+ scsh/rx/regress.scm \
|
|
+ scsh/odbc/odbc.scm
|
|
# scsh/dbm.scm db.scm ndbm.scm
|
|
# jcontrol
|
|
|
|
|
|
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 -u -r1.59 scsh-package.scm
|
|
--- scsh-package.scm 25 Feb 2003 12:58:37 -0000 1.59
|
|
+++ scsh-package.scm 20 Mar 2003 16:03:38 -0000
|
|
@@ -597,3 +597,21 @@
|
|
signals
|
|
srfi-9)
|
|
(files srfi-19))
|
|
+
|
|
+;;; 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 -u -r1.53 scsh-interfaces.scm
|
|
--- scsh-interfaces.scm 25 Feb 2003 12:58:37 -0000 1.53
|
|
+++ scsh-interfaces.scm 20 Mar 2003 16:03:39 -0000
|
|
@@ -1166,13 +1166,13 @@
|
|
(export crypt))
|
|
|
|
(define-interface uname-interface
|
|
- (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))
|
|
|
|
(define-interface md5-interface
|
|
(export make-md5-context
|
|
@@ -1275,3 +1275,92 @@
|
|
;; Date to string/string to date converters.
|
|
date->string
|
|
string->date))
|
|
+
|
|
+;;; 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> |