added ODBC support

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@299 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling 1998-07-18 00:57:32 +00:00
parent c83d505a20
commit 1a6944fd74
57 changed files with 11949 additions and 283 deletions

View File

@ -24,7 +24,13 @@
#include <windows.h>
#endif
#ifdef __WXGTK__
#include <../iodbc/postgres/isqlext.h>
#include <../iodbc/postgres/odbc_funcs.h>
#include <../iodbc/postgres/odbc_types.h>
#else
#include <sqlext.h>
#endif
#include "wx/defs.h"
#include "wx/list.h"

View File

@ -16,7 +16,7 @@
#endif
#include <wx/stream.h>
#include "zlib.h"
#include "../../src/zlib/zlib.h"
class wxZlibInputStream: public wxFilterInputStream {
public:

568
install/gtk/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -695,6 +695,7 @@ DEFAULT_USE_MEM_TRACING=0
DEFAULT_USE_ZLIB=1
DEFAULT_USE_GDK_IMLIB=1
DEFAULT_USE_LIBPNG=1
DEFAULT_USE_ODBC=1
DEFAULT_USE_APPLE_IEEE=1
DEFAULT_USE_STORABLE_CLASSES=1
@ -776,6 +777,10 @@ AC_OVERRIDES(libpng,libpng,
**--with-libpng use libpng (PNG image format),
USE_LIBPNG)
AC_OVERRIDES(odbc,odbc,
**--with-odbc use iODBC,
USE_ODBC)
AC_OVERRIDES(opengl,opengl,
**--with-opengl use opengl (OpenGL or Mesa),
USE_OPENGL)
@ -921,6 +926,11 @@ if test "$USE_LIBPNG" = 1 ; then
LIBPNG="LIBPNG"
fi
ODBC=NONE
if test "$USE_ODBC" = 1 ; then
ODBC="ODBC"
fi
APPLE_IEEE=NONE
if test "$USE_APPLE_IEEE" = 1 ; then
APPLE_IEEE="APPLE_IEEE"
@ -1346,11 +1356,15 @@ dnl AC_SUBST(LIBPNG_LIBRARY)
dnl AC_SUBST(LIBPNG_LINK)
dnl ----------------------------------------------------------------
dnl search for Python
dnl search for iODBC
dnl ----------------------------------------------------------------
dnl
if test "$USE_ODBC" = 1; then
AC_DEFINE_UNQUOTED(USE_ODBC,$USE_ODBC)
fi
dnl ----------------------------------------------------------------
dnl search for ODBC
dnl search for Python
dnl ----------------------------------------------------------------
dnl ----------------------------------------------------------------

View File

@ -20,8 +20,8 @@ NONE =
# define library name
LIB_TARGET=wx_gtk
LIB_MAJOR=0
LIB_MINOR=12
LIB_MAJOR=1
LIB_MINOR=90
# define library sources
@ -48,6 +48,7 @@ LIB_CPP_SRC=\
common/memory.cpp \
common/module.cpp \
common/object.cpp \
common/odbc.cpp \
common/postscrp.cpp \
common/prntbase.cpp \
common/string.cpp \
@ -167,8 +168,24 @@ LIB_C_SRC=\
gdk_imlib/misc.c \
gdk_imlib/rend.c \
gdk_imlib/save.c \
gdk_imlib/utils.c
gdk_imlib/utils.c \
\
iodbc/dlf.c \
iodbc/dlproc.c \
iodbc/herr.c \
iodbc/henv.c \
iodbc/hdbc.c \
iodbc/hstmt.c \
iodbc/connect.c \
iodbc/prepare.c \
iodbc/execute.c \
iodbc/result.c \
iodbc/execute.c \
iodbc/fetch.c \
iodbc/info.c \
iodbc/catalog.c \
iodbc/misc.c \
iodbc/itrace.c
#define library objects
LIB_OBJ=\
@ -185,6 +202,7 @@ clean::
$(RM) -rf png
$(RM) -rf zlib
$(RM) -rf gdk_imlib
$(RM) -rf iodbc
#additional things needed for compile
ADD_COMPILE= \

View File

@ -17,7 +17,6 @@
#include <wx/stream.h>
#include <wx/zstream.h>
#include <wx/utils.h>
#include "zlib.h"
#ifdef __BORLANDC__
#pragma hdrstop

View File

@ -120,7 +120,9 @@ void wxDialog::OnApply( wxCommandEvent &WXUNUSED(event) )
void wxDialog::OnCancel( wxCommandEvent &WXUNUSED(event) )
{
if (IsModal())
{
EndModal(wxID_CANCEL);
}
else
{
SetReturnCode(wxID_CANCEL);
@ -133,14 +135,15 @@ void wxDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
if ( Validate() && TransferDataFromWindow())
{
if (IsModal())
{
EndModal(wxID_OK);
}
else
{
SetReturnCode(wxID_OK);
this->Show(FALSE);
};
};
EndModal( wxID_OK );
};
void wxDialog::OnPaint( wxPaintEvent& WXUNUSED(event) )
@ -153,7 +156,7 @@ bool wxDialog::OnClose(void)
static wxList closing;
if (closing.Member(this)) return FALSE; // no loops
closing.Append(this);
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);

View File

@ -52,6 +52,10 @@
* Use libpng
*/
#undef USE_LIBPNG
/*
* Use iODBC
*/
#undef USE_ODBC
/*
* Use Threads
*/

View File

@ -1055,10 +1055,24 @@ void wxWindow::ImplementSetSize(void)
void wxWindow::ImplementSetPosition(void)
{
if (!m_parent)
{
if (IsKindOf(CLASSINFO(wxFrame)) ||
IsKindOf(CLASSINFO(wxDialog)))
{
gtk_widget_set_uposition( m_widget, m_x, m_y );
}
else
{
printf( "wxWindow::SetSize error.\n" );
}
return;
}
if ((m_parent) && (m_parent->m_wxwindow))
gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x, m_y );
else
gtk_widget_set_uposition( m_widget, m_x, m_y );
// Don't do anything for children of wxNotebook and wxMDIChildFrame
};
void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags )

View File

@ -120,7 +120,9 @@ void wxDialog::OnApply( wxCommandEvent &WXUNUSED(event) )
void wxDialog::OnCancel( wxCommandEvent &WXUNUSED(event) )
{
if (IsModal())
{
EndModal(wxID_CANCEL);
}
else
{
SetReturnCode(wxID_CANCEL);
@ -133,14 +135,15 @@ void wxDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
if ( Validate() && TransferDataFromWindow())
{
if (IsModal())
{
EndModal(wxID_OK);
}
else
{
SetReturnCode(wxID_OK);
this->Show(FALSE);
};
};
EndModal( wxID_OK );
};
void wxDialog::OnPaint( wxPaintEvent& WXUNUSED(event) )
@ -153,7 +156,7 @@ bool wxDialog::OnClose(void)
static wxList closing;
if (closing.Member(this)) return FALSE; // no loops
closing.Append(this);
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);

View File

@ -52,6 +52,10 @@
* Use libpng
*/
#undef USE_LIBPNG
/*
* Use iODBC
*/
#undef USE_ODBC
/*
* Use Threads
*/

View File

@ -1055,10 +1055,24 @@ void wxWindow::ImplementSetSize(void)
void wxWindow::ImplementSetPosition(void)
{
if (!m_parent)
{
if (IsKindOf(CLASSINFO(wxFrame)) ||
IsKindOf(CLASSINFO(wxDialog)))
{
gtk_widget_set_uposition( m_widget, m_x, m_y );
}
else
{
printf( "wxWindow::SetSize error.\n" );
}
return;
}
if ((m_parent) && (m_parent->m_wxwindow))
gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x, m_y );
else
gtk_widget_set_uposition( m_widget, m_x, m_y );
// Don't do anything for children of wxNotebook and wxMDIChildFrame
};
void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags )

58
src/iodbc/Changes.log Normal file
View File

@ -0,0 +1,58 @@
July 30, 1995, v2.00.beta:
0. the first release and beta version.
Sep. 11, 1995, v2.10:
1. Porting to AIX 3.x and 4.x, by writing dlopen(),
dlsym(), dlclose() interface.
2. Tested on SCO OpenServer 5.x
3. Awared of that, unlike s700/s800, exported function
symbols on HP9000 s300/s400 will be prepended with
a '_' prefix by compiler(and this '_' prefix is not
automatically handled by shl_findsym()). Now, it works
fine on s300/s400.
4. Support driver ODBC call tracing.
Oct. 12, 1995, v2.11:
5. Driver's SQLNumResultCols() will automatically be
invoked in driver manager's SQLExecute(),
SQLExecDirect() and SQLParamData() after successfully
(i.e. return SQL_SUCCESS or SQL_SUCCESS_WITH_INFO )
calling of their correspondent driver functions. This
simplifies the state tracing/checking of the driver
manager a lot and allows store procedures to return
result set and also make iODBC driver manager work
properly with SELECT INTO statements which actually
don't return result sets.
6. Memory leaks are cleared.
7. Two bugs in dld.c for AIX are fixed
8. A bug of setting tracing option is fixed.
9. The driver will not be unloaded by SQLDisconnect()
but by SQLFreeConnect() or next SQLConnect()/
SQLDriverConnect()/SQLBrowsConnect() on a different
driver. This will save driver's loading time if it
has been used by a previous connection(even there
is no active connection on this driver).
10.Another three platforms are supported:
FreeBSD 2.x
Concurrent Max/OS SVR4 1.x
DG/UX 5.x
11.autoconfig and build -- shell scripts to help modifying
Config.mk and building iodbc driver manager
Nov. 12, 1995, v2.12
12.I realized that a driver manager doesn't aware of
difference between a C5 (i.e. hstmt) and a C6
(i.e. transaction) states.
13.The link flags "-lc" has been droped from Linux ELF
section of Config.mk to fix a segment fault problem.
Now, it works fine on Slackware 2.3 and Red Hat 2.0
(kernel version are 1.2.xx and 1.3.xx respectively).
14.On FreeBSD 2.x, dlsym() doesn't handle the '_' prefix
prepended to an exportting function symbol by compiler.
So, CLI_NAME_PREFIX needs to be defined as "_SQL" for
FreeBSD 2.x.
15.Some files are renamed
dld.c -> dlf.c
dld.h -> dlf.h
confg.h -> config.h
16. Fix a bug on setting tracing options.

21
src/iodbc/Config.mk Normal file
View File

@ -0,0 +1,21 @@
#
# Copyright (C) 1995 by Ke Jin <kejin@empress.com>
#
#============ Default for all system ==============
SHELL =
SHELL = /bin/sh
DLDAPI = DLDAPI_SVR4_DLFCN
DLSUFFIX= so
OUTFILE = iodbc
OBJX =
#============= Linux ELF =========================
# Slackware 2.x,(kernel 1.3.x) on i386
# Red Hat 2.x (kernel 1.2.x) on i486
#
ANSI = -ansi
CC = gcc
PIC = -fPIC
LDFLAGS = -shared
LIBS = -ldl

37
src/iodbc/IAFA-PACKAGE Normal file
View File

@ -0,0 +1,37 @@
Title: iODBC Driver Manager for Unix
Version: 2.12.0
Description: iODBC (intrinsic Open Database Connectivity) driver manager
is compatible with ODBC 2.0 specification and performs exactly
same jobs of ODBC 2.0 driver manager(i.e driver loading,
parameters and function sequence checking, driver's function
invoking, etc.). Any ODBC driver works with ODBC 2.0 driver
manager will also work with iODBC driver manager and vice versa.
Applications(which using ODBC function calls) linked with
iODBC driver manager will be able to simultaneously access
different type of data sources within one process through
suitable ODBC drivers.
Author: Jin, Ke <kejin@empress.com>
Platforms: SunOS (Sparc) 4.1.x
HP/UX (s700/s800) 9.x, 10.x
HP/UX (s300/s400) 9.x
IBM AIX 3.x, 4.x
Solaris (Sparc) 2.x
Solaris (PCx86) 2.x
SGI Irix 5.x, 6.x
NCR SVR4 3.x
UnixWare SVR4.2 1.x, 2.x
DEC Unix (OSF/1) 3.x, 4.x
FreeBSD 2.x
BSDI BSD/OS 2.x
Linux ELF 1.2.x
SCO OpenServer 5.x
Concurrent MAX/OS 1.x
DG/UX 5.x
Copying-Policy: Freely Redistributable under GNU General Public License
Keywords: ODBC, database, SQL

32
src/iodbc/Makefile Normal file
View File

@ -0,0 +1,32 @@
include Version.mk
include Config.mk
INCDIR = .
OUTDIR = $(HOME)
CFLAGS = -O $(PIC) $(ANSI) -I$(INCDIR) -D$(DLDAPI) $(CFLAGSX)\
-DVERSION=\"$(VERSION)$(EXTVER)\"
ODBCDM = $(OUTDIR)/$(OUTFILE)-$(VERSION).$(DLSUFFIX)
OBJS = dlf.o dlproc.o herr.o henv.o hdbc.o hstmt.o \
connect.o prepare.o execute.o result.o \
fetch.o info.o catalog.o misc.o itrace.o $(OBJX)
all: $(OBJS)
@echo "Generating iODBC driver manager -->" $(ODBCDM)
@\rm -f $(ODBCDM)
@$(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o $(ODBCDM)
clean:
\rm -f $(OBJS)

187
src/iodbc/README Normal file
View File

@ -0,0 +1,187 @@
0. Changes
a. I realized that a driver manager doesn't aware of
difference between a C5 (i.e. hstmt) and a C6
(i.e. transaction) states.
b. The link flags "-lc" has been removed from Linux ELF
section of Config.mk to fix a segment fault problem.
Now, it works fine on Slackware 2.3 and Red Hat 2.0
(kernel version are 1.2.xx and 1.3.xx respectively).
c. On FreeBSD 2.x, dlsym() doesn't handle the '_'
prepended before a exporting function symbol. So,
CLI_NAME_PREFIX needs to be defined as "_SQL" for
FreeBSD.
d. Some files are renamed
dld.c -> dlf.c
dld.h -> dlf.h
confg.h -> config.h
1. iODBC driver manager platform availability
iODBC driver manager has been ported to following Unix platforms:
SunOS 4.1.x Sun Sparc
HP/UX 9.x, 10.x HP9000 s700/s800
HP/UX 9.x HP9000 s300/s400
IBM AIX 3.x, 4.x IBM RS6000, PowerPC
Sun Solaris 2.x Sun Sparc, PCx86
SGI Irix SVR4 5.x, 6.x IP12 MIPS, IP22 MIPS
NCR SVR4 3.x NCR 3435
UnixWare SVR4.2 1.x, 2.x x86
DEC Unix(OSF/1) 3.x, 4.x DEC Alpha
FreeBSD 2.x x86
BSDI BSD/OS 2.x ?
Linux ELF 1.2.x, 1.3.x x86
SCO OpenServer 5.x x86
Max/OS SVR4 1.x Concurrent Maxion 9200 MP
DG/UX 5.x Aviion
Porting of iODBC driver manager to some non-unix operating systems
such as Windows family(3.x, 95, NT), OS/2 and Mac is supported but
has never compiled and tested yet :). Of cause, you need to supply
a make/build file and a short LibMain for creating the iodbc.dll.
2. How to build iODBC driver manager:
step 1. Identify your system
step 2. Run build with a suitable option
Here is an example:
%[1]: sh iodbc-2.12.shar
....
%[2]: cd iodbc-2.12
%[3]: uname -s -v -r -m
HP-UX B.10.01 A 9000/710
%[4]: ./build hp700
autoconfig hp700
make
....
Generating iODBC driver manager --> /home/kejin/iodbc-2.12.sl
3. odbc.ini( ~/.odbc.ini )
Driver manager and drivers use odbc.ini(or ~/.odbc.ini on Unix) file
or connection string when establishing a data source connection. On
Windows, odbc.ini is located in Windows directory. On unix, iODBC driver
manager(and all other ODBC drivers and driver managers I awared) looks
.odbc.ini file in real user's home directory (it could be a softlink to
the file located somewhere else). Make sure your driver will look into
the same file (or a file which is a symbolic link to the same file).
The format of odbc.ini( or ~/.odbc.ini ) is defined as:
odbc.ini(or .odbc.ini) ::= data_source_list
data_source_list ::= /* empty */
| data_source '\n' data_source_list
data_source ::= '[' data_source_name ']' '\n' data_source_desc
data_source_name ::= 'default' | [A-Za-z]*[A-Za-z0-9_]*
data_source_desc ::= /* empty */
| attrib_desc '\n' data_source_desc
addrib_desc ::= Attrib '=' attrib_value
Attrib ::= 'Driver' | 'PID' | 'UID' | driver_def_attrib
driver_def_attrib ::= [A-Za-z]*[A-Za-z0-9_]*
An example of .odbc.ini file:
[toronto_yp]
# yellow page of metro Toronto
Driver = /usr/lib/odbc/oracle.so
<....>
[toronto_wp]
# white page of metro Toronto
Driver = /usr/lib/odbc/oracle.so
<....>
[contract]
# all contract documents
Driver = /usr/lib/odbc/informix.so
<....>
[netnews]
# NNTP netnews group
Driver = /usr/lib/odbc/nnodbc.so
Server = news.empress.com
[rnd_test]
# data source for R&D test
Driver = /home/r_d/odbc/empodbc.so
URL = empodbc://rnd.empress.com:6322/rnd_test/testdb
[default]
# default to odbc gateway
Driver = /usr/lib/odbc/gateway.so
4. Tracing
iODBC driver manager traces driver's ODBC call invoked by the driver
manager. Default tracing file is ./odbc.log. Tracing option (i.e.
on/off or optional tracing file name) can be set in ~/.odbc.ini
file (under a data source section) as:
TraceFile = <optional_trace_file>
Trace = ON | On | on | 1 | OFF | Off | off | 0
If <optional_trace_file> is stderr or stdout, i.e.
TraceFile = stderr
or
TraceFile = stdout
the tracing message will go to the terminal screen(if it is available).
iODBC driver manager allows one to tune on/off tracing on selected
connection(s). Different connections can share one or use different
tracing file(s). ODBC calls on connections without tuning tracing on
will not be traced.
5. File list:
README This file
IAFA-PACKAGE Version and copyright information
Changes.log Source changes log
Version.mk Version make include file
Config.mk Config make include file
Makefile make file
config.h system config include file
isql.h ODBC 1.0 macro
isqlext.h ODBC 2.0 macro
dlf.h general dynamic loader module interface
dlf.c general dynamic loader module (mapping to svr4)
dlproc.h simple dynamic loader module interface
dlproc.c simple dynamic loader on top of dlf module
herr.h error handling module interface
herr.c error handling module
herr.ci error handling source include
henv.h environment handle interface
henv.c environment handle module
henv.ci environment handle source include
hdbc.h connection handle interface
hdbc.c connection handle module
hstmt.h statement handle interface
hstmt.c statement handle module
connect.c connect functions
prepare.c query prepare functions
execute.c query executing functions
result.c query result property functions
fetch.c query result fetch functions
info.c driver information functions
catalog.c catalog functions
misc.c miscellaneous functions
itrace.h macro
itrace.c trace function
main.c entry function used to build a share library on AIX
shrsub.exp export symbol list used on AIX
autoconfig shell script for creating Config.mk
build shell script for building iodbc driver manager

2
src/iodbc/Version.mk Normal file
View File

@ -0,0 +1,2 @@
VERSION = 2.12
EXTVER = .0

230
src/iodbc/autoconfig Executable file
View File

@ -0,0 +1,230 @@
#! /usr/bin/sh
cat > Config.tmp << '@END'
#
# Copyright (C) 1995 by Ke Jin <kejin@empress.com>
#
#============ Default for all system ==============
SHELL =
SHELL = /bin/sh
DLDAPI = DLDAPI_SVR4_DLFCN
DLSUFFIX= so
OUTFILE = iodbc
OBJX =
@END
\rm -f Makefile.tmp
cat > Makefile.tmp <<'@END'
include Version.mk
include Config.mk
@END
case $1 in
sun4)
cat >> Config.tmp << '@END'
#============ SunOS 4.1.x =========================
PIC = -pic
CC = acc
LIBS = -ldl
@END
;;
aix)
cat >> Config.tmp << '@END'
#=========== AIX 3.x 4.x ==========================
DLDAPI = DLDAPI_AIX_LOAD
ANSI = -langlvl=ansi
LDFLAGS = -H512 -T512 -bE:shrsub.exp -bM:SRE
LIBS = -lc
OBJX = main.o
DLSUFFIX= s.o
CFLAGSX = -DCLI_NAME_PREFIX=\".SQL\"
@END
;;
hp300 | hp400)
cat >> Config.tmp << '@END'
#============ HP/UX (s300/s400) 9.x 10.x ==========
DLDAPI = DLDAPI_HP_SHL
ANSI = -Aa
PIC = +z
LDFLAGS = -b
DLSUFFIX= sl
CFLAGSX = -D_INCLUDE_POSIX_SOURCE -DCLI_NAME_PREFIX=\"_SQL\"
@END
;;
hp700 | hp800)
cat >> Config.tmp << '@END'
#============ HP/UX 9000(s700/s800) 9.x 10.x ======
DLDAPI = DLDAPI_HP_SHL
ANSI = -Aa
PIC = +z
LDFLAGS = -b
LIBS = -lc -ldld
DLSUFFIX= sl
CFLAGSX = -D_INCLUDE_POSIX_SOURCE
@END
;;
solaris)
cat >> Config.tmp << '@END'
#======= Solaris 2.x, SunOS 5.x (Sparc/x86) =======
LDFLAGS = -G -z defs
LIBS = -lc -ldl -lnsl
@END
;;
ncr |gis)
cat >> Config.tmp << '@END'
#============= NCR SVR4 3.x =======================
PIC = -KPIC
LDFLAGS = -G -z defs
LIBS = -lc -ldl
@END
;;
unixware)
cat >> Config.tmp << '@END'
#========= UnixWare SVR4 1.x, 2.x =================
PIC = -KPIC
LDFLAGS = -G -z defs
LIBS = -lc -ldl
@END
;;
maxos)
cat >> Config.tmp << '@END'
#============ Concurrent Maxion MAX/OS 1.x ========
PIC = -KPIC
LDFLAGS = -G -z defs
LIBS = -lc -ldl
@END
;;
sco-opensrv | sco-osr5 )
cat >> Config.tmp << '@END'
#============ SCO OpenServer 5.x ==================
PIC = -K PIC -b elf
LDFLAGS = -G -z defs
LIBS = -lc -ldl
@END
;;
dgux)
cat >> Config.tmp << '@END'
#============ DG/UX 5.x ===========================
PIC = -K PIC
LDFLAGS = -G -z defs
LIBS = -lc -ldl
@END
;;
freebsd)
cat >> Config.tmp << '@END'
#============= FreeBSD 2.x ========================
PIC = -fPIC
CFLAGSX = -DCLI_NAME_PREFIX=\"_SQL\"
LDFLAGS = -Bshareable
LIBS = -lc
@END
\rm -f Makefile.tmp
cat > Makefile.tmp <<'@END'
.include "Version.mk"
.include "Config.mk"
@END
;;
bsd-os)
cat >> Config.tmp << '@END'
#============ BSDI BSD/OS 2.x =====================
#
# ported by: Stuart Hayton <stuey@clic.co.uk>
#
CC = gcc
LDFLAGS = -r
LDSUFFIX= o
LIBS = -lc_s.2.0 -ldl
@END
;;
linux-elf)
cat >> Config.tmp << '@END'
#============= Linux ELF =========================
# Slackware 2.x,(kernel 1.3.x) on i386
# Red Hat 2.x (kernel 1.2.x) on i486
#
ANSI = -ansi
CC = gcc
PIC = -fPIC
LDFLAGS = -shared
LIBS = -ldl
@END
;;
irix5| irix6)
cat >> Config.tmp << '@END'
#============= SGI IRIX 5.x, 6.x =================
LDFLAGS = -shared
LIBS = -lc
@END
;;
dec-osf1 | dec-unix)
cat >> Config.tmp << '@END'
#============= DEC Unix(OSF/1) 3.x, 4.x ==========
LDFLAGS = -shared
LIBS = -lc
@END
;;
*)
cat << '@END'
Usage: autoconfig <platform_opt> or
build <platform_opt>
platform_opt:
sun4 -- SunOS 4.1.x
aix -- IBM AIX 3.x, 4.x
hp300, hp400 -- HP/UX 9.x, 10.x on 9000 s300/s400
hp700, hp800 -- HP/UX 9.x, 10.x on 9000 s700/s800
solaris -- Sun Solaris 2.x, SunOS 5.x
ncr, gis -- NCR(GIS) SVR4 3.x
unixware -- Novell UnixWare 1.x, 2.x
maxos -- Concurrent MAX/OS SVR4 1.x
sco-osr5 -- SCO Open Server 5.x
dgux -- DG/UX 5.x
freebsd -- FreeBSD 2.x
bsd-os -- BSDI BSD/OS 2.x
linux-elf -- Linux ELF 1.2.x and up
irix5, irix6 -- SGI Irix 5.x, 6.x
dec-osf1 -- DEC Unix(OSF/1) 3.x, 4.x
@END
\rm -f Config.tmp
\rm -f Makefile.tmp
exit 1
;;
esac
\mv -f Config.tmp Config.mk
sed -e 's/.include.*//' -e 's/include.*//' Makefile >> Makefile.tmp
\mv -f Makefile.tmp Makefile
exit 0

9
src/iodbc/build Executable file
View File

@ -0,0 +1,9 @@
#! /bin/sh
echo autoconfig $1
if sh ./autoconfig $1
then
echo make
make
fi

1092
src/iodbc/catalog.c Normal file

File diff suppressed because it is too large Load Diff

43
src/iodbc/config.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef _LINUX_CONFIG_H
#define _LINUX_CONFIG_H
#include <linux/autoconf.h>
/*
* Defines for what uname() should return
*/
#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif
#ifndef UTS_MACHINE
#define UTS_MACHINE "unknown"
#endif
#ifndef UTS_NODENAME
#define UTS_NODENAME "(none)" /* set by sethostname() */
#endif
#ifndef UTS_DOMAINNAME
#define UTS_DOMAINNAME "(none)" /* set by setdomainname() */
#endif
/*
* The definitions for UTS_RELEASE and UTS_VERSION are now defined
* in linux/version.h, and should only be used by linux/version.c
*/
/* Shouldn't these be defined somewhere in a i386 definition? */
/* Don't touch these, unless you really know what you're doing. */
#define DEF_INITSEG 0x9000
#define DEF_SYSSEG 0x1000
#define DEF_SETUPSEG 0x9020
#define DEF_SYSSIZE 0x7F00
/* internal svga startup constants */
#define NORMAL_VGA 0xffff /* 80x25 mode */
#define EXTENDED_VGA 0xfffe /* 80x50 mode */
#define ASK_VGA 0xfffd /* ask for it at bootup */
#endif

1260
src/iodbc/connect.c Normal file

File diff suppressed because it is too large Load Diff

595
src/iodbc/dlf.c Normal file
View File

@ -0,0 +1,595 @@
/** dynamic library loader (mapping to svr4)
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include "wx/setup.h"
#include <../iodbc/dlf.h>
#include <errno.h>
#ifdef DLDAPI_DEFINED
# undef DLDAPI_DEFINED
#endif
#ifdef DLDAPI_SVR4_DLFCN
# define DLDAPI_DEFINED
static char sccsid[] = "@(#)dynamic load interface -- SVR4 dlfcn";
#endif
/*********************************
*
* HP/UX
*
*********************************/
#ifdef DLDAPI_HP_SHL
# define DLDAPI_DEFINED
# include <dl.h>
static char sccsid[] = "@(#)dynamic load interface -- HP/UX dl(shl)";
void* dlopen(char* path, int mode)
{
return (void*)shl_load((char*)(path), BIND_DEFERRED, 0L);
}
void* dlsym(void* hdll, char* sym)
{
void* symaddr = 0;
int ret;
if( ! hdll )
hdll = (void*)PROG_HANDLE;
/* Remember, a driver may export calls as function pointers
* (i.e. with type TYPE_DATA) rather than as functions
* (i.e. with type TYPE_PROCEDURE). Thus, to be safe, we
* uses TYPE_UNDEFINED to cover all of them.
*/
ret = shl_findsym((shl_t*)&hdll, sym, TYPE_UNDEFINED, &symaddr);
if( ret == -1 )
return 0;
return symaddr;
}
char* dlerror()
{
extern char* strerror();
return strerror(errno);
}
int dlclose(void* hdll)
{
return shl_unload((shl_t)hdll);
}
#endif /* end of HP/UX Seection */
/*********************************
*
* IBM AIX
*
*********************************/
#ifdef DLDAPI_AIX_LOAD
# define DLDAPI_DEFINED
# include <sys/types.h>
# include <sys/ldr.h>
# include <sys/stat.h>
# include <nlist.h>
/*
* Following id sting is a copyright mark. Removing(i.e. use the
* source code in this .c file without include it or make it not
* appear in the final object file of AIX platform) or modifing
* it without permission from original author(kejin@empress.com)
* are copyright violation.
*/
static char sccsid[]
= "@(#)dynamic load interface, Copyright(c) 1995 by Ke Jin";
# ifndef HTAB_SIZE
# define HTAB_SIZE 256
# endif
# define FACTOR 0.618039887 /* i.e. (sqrt(5) - 1)/2 */
# ifndef ENTRY_SYM
# define ENTRY_SYM ".__start" /* default entry point for aix */
# endif
typedef struct slot_s
{
char* sym;
long fdesc[3]; /* 12 bytes function descriptor */
struct slot_s* next;
} slot_t;
/* Note: on AIX, a function pointer actually points to a
* function descriptor, a 12 bytes data. The first 4 bytes
* is the virtual address of the function. The next 4 bytes
* is the virtual address of TOC (Table of Contents) of the
* object module the function belong to. The last 4 bytes
* are always 0 for C and Fortran functions. Every object
* module has an entry point (which can be specified at link
* time by -e ld option). iODBC driver manager requires ODBC
* driver shared library always use the default entry point
* (so you shouldn't use -e ld option when creating a driver
* share library). load() returns the function descriptor of
* a module's entry point. From which we can calculate function
* descriptors of other functions in the same module by using
* the fact that the load() doesn't change the relative
* offset of functions to their module entry point(i.e the
* offset in memory loaded by load() will be as same as in
* the module library file).
*/
typedef slot_t* hent_t;
typedef struct nlist nlist_t;
typedef struct stat stat_t;
typedef struct obj
{
int dev; /* device id */
int ino; /* inode number */
char* path; /* file name */
int (*pentry)(); /* entry point of this share library */
int refn; /* number of reference */
hent_t htab[HTAB_SIZE];
struct obj*
next;
} obj_t;
static char* errmsg = 0;
static void init_htab(hent_t* ht)
/* initate a hashing table */
{
int i;
for(i=0; i<HTAB_SIZE; i++)
ht[i] = (slot_t*)0;
return;
}
static void clean_htab(hent_t* ht)
/* free all slots */
{
int i;
slot_t* ent;
slot_t* tent;
for(i = 0; i< HTAB_SIZE; i++)
{
for( ent = ht[i]; ent; )
{
tent = ent->next;
free(ent->sym);
free(ent);
ent = tent;
}
ht[i] = 0;
}
return;
}
static int hash(char* sym )
{
int a, key;
double f;
if( !sym || !*sym )
return 0;
for(key=*sym;*sym;sym++)
{
key += *sym;
a = key;
key = (int)( (a<<8) + (key>>8) );
key = (key>0)? key:-key;
}
f = key*FACTOR;
a = (int)f;
return (int)((HTAB_SIZE - 1)*( f - a ));
}
static hent_t search(hent_t* htab, char* sym)
/* search hashing table to find a matched slot */
{
int key;
slot_t* ent;
key = hash(sym);
for(ent = htab[key]; ent; ent = ent->next )
{
if(!strcmp(ent->sym, sym))
return ent;
}
return 0; /* no match */
}
static void insert(hent_t* htab, slot_t* ent)
/* insert a new slot to hashing table */
{
int key;
key = hash(ent->sym);
ent->next = htab[key];
htab[key] = ent;
return;
}
static slot_t* slot_alloc(char* sym)
/* allocate a new slot with symbol */
{
slot_t* ent;
ent = (slot_t*)malloc(sizeof(slot_t));
ent->sym = (char*)malloc(strlen(sym)+1);
if( ! ent->sym )
{
free(ent);
return 0;
}
strcpy( ent->sym, sym );
return ent;
}
static obj_t* obj_list = 0;
void* dlopen(char* file, int mode )
{
stat_t st;
obj_t* pobj;
char buf[1024];
if( ! file || ! *file )
{
errno = EINVAL;
return 0;
}
errno = 0;
errmsg = 0;
#if 0
if( file[0] != '/' && file[0] != '.' )
{
for(;;)
{
sprintf(buf, "/lib/%s", file);
if( stat( buf, &st ) )
{
file = buf;
break;
}
sprintf(buf, "/usr/lib/%s", file);
if( stat( buf, &st ) )
{
file = buf;
break;
}
if( stat( file, &st ) )
break;
return 0;
}
}
else
#endif
if( stat( file, &st ) )
return 0;
for( pobj = obj_list; pobj; pobj = pobj->next )
/* find a match object */
{
if( pobj->ino == st.st_ino
&& pobj->dev == st.st_dev )
{
/* found a match. increase its
* reference count and return
* its address */
pobj->refn ++;
return pobj;
}
}
pobj = (obj_t*)malloc( sizeof(obj_t) );
if( ! pobj )
return 0;
pobj->path = (char*)malloc( strlen(file) + 1);
if( ! pobj->path )
{
free( pobj );
return 0;
}
strcpy( pobj->path, file );
pobj->dev = st.st_dev;
pobj->ino = st.st_ino;
pobj->refn = 1;
pobj->pentry = (int(*)())load(file, 0, 0);
if( ! pobj->pentry )
{
free( pobj->path );
free( pobj );
return 0;
}
init_htab(pobj->htab);
pobj->next = obj_list;
obj_list = pobj;
return pobj;
}
int dlclose(void* hobj)
{
obj_t* pobj = (obj_t*)hobj;
obj_t* tpobj;
int match = 0;
if( ! hobj )
{
errno = EINVAL;
return -1;
}
errno = 0;
errmsg = 0;
if( pobj == obj_list )
{
pobj->refn --;
if( pobj->refn )
return 0;
match = 1;
obj_list = pobj->next;
}
for( tpobj = obj_list; !match && tpobj; tpobj = tpobj->next )
{
if( tpobj->next == pobj )
{
pobj->refn --;
if( pobj->refn )
return 0;
match = 1;
tpobj->next = pobj->next;
}
}
if(match)
{
unload((void*)(pobj->pentry));
clean_htab(pobj->htab);
free(pobj->path);
free(pobj);
}
return 0;
}
char* dlerror()
{
extern char* sys_errlist[];
if( ! errmsg || ! errmsg[0] )
{
if( errno >= 0 )
return sys_errlist[errno];
return "";
}
return errmsg;
}
void* dlsym(void* hdl, char* sym)
{
nlist_t nl[3];
obj_t* pobj = (obj_t*)hdl;
slot_t* ent;
int (*fp)();
long lbuf[3];
if( !hdl || !(pobj->htab) || !sym || ! *sym )
{
errno = EINVAL;
return 0;
}
errno = 0;
errmsg = 0;
ent = search( pobj->htab, sym );
if( ent )
return ent->fdesc;
#define n_name _n._n_name
nl[0].n_name = ENTRY_SYM;
nl[1].n_name = sym;
nl[2].n_name = 0;
/* There is a potential problem here. If application
* did not pass a full path name, and changed the
* working directory after the load(), then nlist()
* will be unable to open the original shared library
* file to resolve the symbols. there are 3 ways to working
* round this: 1. convert to full pathname in driver
* manager. 2. applications always pass driver's full
* path name. 3. if driver itself don't support
* SQLGetFunctions(), call it with SQL_ALL_FUNCTIONS
* as flag immidately after SQLConnect(), SQLDriverConnect()
* and SQLBrowseConnect() to force the driver manager
* resolving all will be used symbols.
*/
if( nlist( pobj->path, nl) == -1 )
return 0;
if( ! nl[0].n_type && ! nl[0].n_value )
{
errmsg = "can't locate module entry symbol";
return 0;
}
/* Note: On AIX 3.x if the object library is not
* built with -g compiling option, .n_type field
* is always 0. While on 4.x it will be 32.
* On AIX 4.x, if the symbol is a entry point,
* n_value will be 0. However, one thing is for sure
* that if a symbol is not existance in the file,
* both .n_type and .n_value would be 0.
*/
if( ! nl[1].n_type && ! nl[1].n_value )
{
errmsg = "symbol not existance in this module";
return 0;
}
ent = slot_alloc(sym);
if( ! ent )
return 0;
/* catch it with a slot in the hashing table */
insert(pobj->htab, ent);
memcpy(ent->fdesc, pobj->pentry, sizeof(ent->fdesc));
/* now ent->fdesc[0] is the virtual address of entry point
* and ent->fdesc[1] is the TOC of the module
*/
/* let's calculate the virtual address of the symbol
* by adding a relative offset getting from the module
* file symbol table, i.e
*
* functin virtual address = entry point virtual address +
* + ( function offset in file - entry point offset in file )
*/
(ent->fdesc)[0] = (ent->fdesc)[0] +
( nl[1].n_value - nl[0].n_value );
/* return the function descriptor */
return ent->fdesc;
}
#endif /* end of IBM AIX Section */
/*********************************
*
* Windows 3.x, 95, NT
*
*********************************/
#ifdef DLDAPI_WINDOWS
# define DLDAPI_DEFINED
# include <windows.h>
void FAR* dlopen(char FAR* dll, int mode)
{
HINSTANCE hint;
if( dll == NULL )
{
return GetWindowWord( NULL, GWW_HINSTANCE );
}
hint = LoadLibrary(dll);
if( hint < HINSTANCE_ERROR )
{
return NULL;
}
return (void FAR*)hint;
}
void FAR* dlsym( void FAR* hdll, char FAR* sym )
{
return (void FAR*)GetProcAddress(hdll, sym);
}
char FAR* dlerror()
{
return 0L; /* unimplemented yet */
}
int dlclose(void FAR* hdll)
{
FreeLibrary((HINSTANCE)hdll);
}
#endif /* end of Windows family */
/***********************************
*
* other platforms
*
***********************************/
#ifdef DLDAPI_OS2
# define DLDAPI_DEFINED
/*
* DosLoadModule(), DosQueryProcAddress(), DosFreeModule(), ...
*/
#endif
#ifdef DLDAPI_MAC
# define DLDAPI_DEFINED
#endif
#ifdef DLDAPI_NEXT
# define DLDAPI_DEFINED
#endif
#ifndef DLDAPI_DEFINED
# error "dynamic load editor undefined"
#endif

35
src/iodbc/dlf.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef _DLF_H
# define _DLF_H
#define DLDAPI_SVR4_DLFCN
#ifdef __HPUX__
#define DLDAPI_HP_SHL
#endif
#ifdef __AIX__
#define DLDAPI_AIX_LOAD
#endif
# include <../iodbc/config.h>
# include <../iodbc/windows.h>
# ifdef DLDAPI_SVR4_DLFCN
# include <dlfcn.h>
# else
extern void FAR* dlopen(char FAR* path, int mode);
extern void FAR* dlsym(void FAR* hdll, char FAR* sym);
extern char FAR* dlerror();
extern int dlclose(void FAR* hdll);
# endif
# ifndef RTLD_LAZY
# define RTLD_LAZY 1
# endif
# define DLL_OPEN(dll) (void*)dlopen((char*)(path), RTLD_LAZY)
# define DLL_PROC(hdll, sym) (void*)dlsym((void*)(hdll), (char*)sym)
# define DLL_ERROR() (char*)dlerror()
# define DLL_CLOSE(hdll) dlclose((void*)(hdll))
#endif

99
src/iodbc/dlproc.c Normal file
View File

@ -0,0 +1,99 @@
/** Load driver and resolve driver's function entry point
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/itrace.h>
#include "../iodbc/henv.ci"
HPROC _iodbcdm_getproc( HDBC hdbc, int idx )
{
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
ENV_t FAR* penv;
HDLL hdll;
HPROC FAR* phproc;
if( idx <= 0 || idx > SQL_EXT_API_LAST )
/* first entry naver used */
{
return SQL_NULL_HPROC;
}
penv = (ENV_t FAR*)(pdbc->henv);
if( penv == NULL )
{
return SQL_NULL_HPROC;
}
phproc = penv->dllproc_tab + idx;
if( *phproc == SQL_NULL_HPROC )
{
int i, en_idx;
for( i=0 ; ; i++ )
{
en_idx = odbcapi_symtab[i].en_idx;
if( en_idx == en_NullProc )
{
break;
}
if( en_idx == idx )
{
*phproc = _iodbcdm_dllproc( penv->hdll,
odbcapi_symtab[i].symbol );
break;
}
}
}
return *phproc;
}
HDLL _iodbcdm_dllopen( char FAR* path )
{
return (HDLL)DLL_OPEN( path );
}
HPROC _iodbcdm_dllproc( HDLL hdll, char FAR* sym )
{
return (HPROC)DLL_PROC( hdll, sym );
}
int _iodbcdm_dllclose( HDLL hdll )
{
DLL_CLOSE( hdll );
return 0;
}
char* _iodbcdm_dllerror( )
{
return DLL_ERROR();
}

31
src/iodbc/dlproc.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef _DLPROC_H
# define _DLPROC_H
# include <../iodbc/dlf.h>
typedef RETCODE (FAR* HPROC)();
# ifdef DLDAPI_SVR4_DLFCN
# include <dlfcn.h>
typedef void* HDLL;
# endif
# ifdef DLDAPI_HP_SHL
# include <dl.h>
typedef shl_t HDLL;
# endif
# ifdef DLDAPI_AIX_LOAD
typedef void* HDLL;
# endif
extern HPROC _iodbcdm_getproc();
extern HDLL _iodbcdm_dllopen(char FAR* dll);
extern HPROC _iodbcdm_dllproc(HDLL hdll, char FAR* sym);
extern char FAR* _iodbcdm_dllerror();
extern int _iodbcdm_dllclose(HDLL hdll);
#define SQL_NULL_HDLL ((HDLL)NULL)
#define SQL_NULL_HPROC ((HPROC)NULL)
#endif

789
src/iodbc/execute.c Normal file
View File

@ -0,0 +1,789 @@
/** Invoke a query
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
static void do_cursoropen(STMT_t FAR* pstmt)
{
RETCODE retcode;
SWORD ncol;
pstmt->state = en_stmt_executed;
retcode = SQLNumResultCols( pstmt, &ncol );
if( retcode == SQL_SUCCESS
|| retcode == SQL_SUCCESS_WITH_INFO )
{
if( ncol )
{
pstmt->state = en_stmt_cursoropen;
pstmt->cursor_state = en_stmt_cursor_opened;
}
else
{
pstmt->state = en_stmt_executed;
pstmt->cursor_state = en_stmt_cursor_no;
}
}
}
RETCODE SQL_API SQLexecute ( HSTMT hstmt )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
sqlstat = en_S1010;
break;
case en_stmt_executed:
if( ! pstmt->prep_state )
{
sqlstat = en_S1010;
}
break;
case en_stmt_cursoropen:
if( ! pstmt->prep_state )
{
sqlstat = en_S1010;
}
break;
case en_stmt_fetched:
case en_stmt_xfetched:
if( ! pstmt->prep_state )
{
sqlstat = en_S1010;
}
else
{
sqlstat = en_24000;
}
break;
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
sqlstat = en_S1010;
break;
default:
break;
}
}
else if( pstmt->asyn_on != en_Execute )
{
sqlstat = en_S1010;
}
if( sqlstat == en_00000 )
{
hproc = _iodbcdm_getproc( pstmt->hdbc, en_Execute );
if( hproc == SQL_NULL_HPROC )
{
sqlstat = en_IM001;
}
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc,
en_Execute, ( pstmt->dhstmt ) )
#if 0
retcode = hproc ( pstmt->dhstmt );
#endif
/* stmt state transition */
if( pstmt->asyn_on == en_Execute )
{
switch ( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NEED_DATA:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_prepared:
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
do_cursoropen(hstmt);
break;
case SQL_NEED_DATA:
pstmt->state = en_stmt_needdata;
pstmt->need_on = en_Execute;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_Execute;
break;
default:
break;
}
break;
case en_stmt_executed:
switch( retcode )
{
case SQL_ERROR:
pstmt->state = en_stmt_allocated;
pstmt->cursor_state = en_stmt_cursor_no;
pstmt->prep_state = 0;
break;
case SQL_NEED_DATA:
pstmt->state = en_stmt_needdata;
pstmt->need_on = en_Execute;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_Execute;
break;
default:
break;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLExecDirect (
HSTMT hstmt,
UCHAR FAR* szSqlStr,
SDWORD cbSqlStr )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
int sqlstat = en_00000;
RETCODE retcode = SQL_SUCCESS;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check arguments */
if( szSqlStr == NULL )
{
sqlstat = en_S1009;
}
else if( cbSqlStr < 0 && cbSqlStr != SQL_NTS )
{
sqlstat = en_S1090;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch ( pstmt->state )
{
case en_stmt_fetched:
case en_stmt_xfetched:
sqlstat = en_24000;
break;
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
sqlstat = en_S1010;
break;
default:
break;
}
}
else if( pstmt->asyn_on != en_ExecDirect )
{
sqlstat = en_S1010;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_ExecDirect);
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_ExecDirect, (
pstmt->dhstmt, szSqlStr, cbSqlStr) )
#if 0
retcode = hproc ( pstmt->dhstmt, szSqlStr, cbSqlStr );
#endif
/* stmt state transition */
if( pstmt->asyn_on == en_ExecDirect )
{
switch ( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NEED_DATA:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
if( pstmt->state <= en_stmt_executed )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
do_cursoropen(hstmt);
break;
case SQL_NEED_DATA:
pstmt->state = en_stmt_needdata;
pstmt->need_on = en_ExecDirect;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_ExecDirect;
break;
case SQL_ERROR:
pstmt->state = en_stmt_allocated;
pstmt->cursor_state = en_stmt_cursor_no;
pstmt->prep_state = 0;
break;
default:
break;
}
}
return retcode;
}
RETCODE SQL_API SQLPutData(
HSTMT hstmt,
PTR rgbValue,
SDWORD cbValue )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument value */
if( rgbValue == NULL
&& ( cbValue != SQL_DEFAULT_PARAM
&& cbValue != SQL_NULL_DATA ) )
{
PUSHSQLERR ( pstmt->herr, en_S1009 );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
if( pstmt->state <= en_stmt_xfetched )
{
PUSHSQLERR( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
}
else if( pstmt->asyn_on != en_PutData )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_PutData );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_PutData, (
pstmt->dhstmt, rgbValue, cbValue ) )
#if 0
retcode = hproc(pstmt->dhstmt, rgbValue, cbValue );
#endif
/* state transition */
if( pstmt->asyn_on == en_PutData )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
/* must in mustput or canput states */
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
pstmt->state = en_stmt_canput;
break;
case SQL_ERROR:
switch( pstmt->need_on )
{
case en_ExecDirect:
pstmt->state = en_stmt_allocated;
pstmt->need_on = en_NullProc;
break;
case en_Execute:
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
pstmt->need_on = en_NullProc;
}
break;
case en_SetPos:
/* Is this possible ???? */
pstmt->state = en_stmt_xfetched;
break;
default:
break;
}
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_PutData;
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLParamData (
HSTMT hstmt,
PTR FAR* prgbValue )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
if( pstmt->state <= en_stmt_xfetched )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
}
else if( pstmt->asyn_on != en_ParamData )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_ParamData );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_ParamData, (
pstmt->dhstmt, prgbValue ) )
#if 0
retcode = hproc ( pstmt->dhstmt, prgbValue );
#endif
/* state transition */
if( pstmt->asyn_on == en_ParamData )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
if( pstmt->state < en_stmt_needdata )
{
return retcode;
}
switch( retcode )
{
case SQL_ERROR:
switch( pstmt->need_on )
{
case en_ExecDirect:
pstmt->state = en_stmt_allocated;
break;
case en_Execute:
pstmt->state = en_stmt_prepared;
break;
case en_SetPos:
pstmt->state = en_stmt_xfetched;
pstmt->cursor_state
= en_stmt_cursor_xfetched;
break;
default:
break;
}
pstmt->need_on = en_NullProc;
break;
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
switch( pstmt->state )
{
case en_stmt_needdata:
pstmt->state = en_stmt_mustput;
break;
case en_stmt_canput:
switch( pstmt->need_on )
{
case en_SetPos:
pstmt->state
= en_stmt_xfetched;
pstmt->cursor_state
= en_stmt_cursor_xfetched;
break;
case en_ExecDirect:
case en_Execute:
do_cursoropen(hstmt);
break;
default:
break;
}
break;
default:
break;
}
pstmt->need_on = en_NullProc;
break;
case SQL_NEED_DATA:
pstmt->state = en_stmt_mustput;
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLNumParams (
HSTMT hstmt,
SWORD FAR* pcpar )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
default:
break;
}
}
else if( pstmt->asyn_on != en_NumParams )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc ( pstmt->hdbc, en_NumParams );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_NumParams, (
pstmt->dhstmt, pcpar) )
#if 0
retcode = hproc ( pstmt->dhstmt, pcpar );
#endif
/* state transition */
if( pstmt->asyn_on == en_NumParams )
{
switch ( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_ERROR:
break;
default:
return retcode;
}
}
if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_NumParams;
}
return retcode;
}
RETCODE SQL_API SQLDescribeParam (
HSTMT hstmt,
UWORD ipar,
SWORD FAR* pfSqlType,
UDWORD FAR* pcbColDef,
SWORD FAR* pibScale,
SWORD FAR* pfNullable )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
if( ipar == 0 )
{
PUSHSQLERR ( pstmt->herr, en_S1093 );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
default:
break;
}
}
else if( pstmt->asyn_on != en_DescribeParam )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc ( pstmt->hdbc, en_DescribeParam );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_DescribeParam, (
pstmt->dhstmt,
ipar,
pfSqlType,
pcbColDef,
pibScale,
pfNullable ) )
#if 0
retcode = hproc(pstmt->dhstmt,
ipar,
pfSqlType,
pcbColDef,
pibScale,
pfNullable );
#endif
/* state transition */
if( pstmt->asyn_on == en_DescribeParam )
{
switch ( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_ERROR:
break;
default:
return retcode;
}
}
if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_DescribeParam;
}
return retcode;
}

675
src/iodbc/fetch.c Normal file
View File

@ -0,0 +1,675 @@
/** Fetch query result
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
RETCODE SQL_API SQLFetch ( HSTMT hstmt )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_xfetched:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
default:
break;
}
}
else if( pstmt->asyn_on != en_Fetch )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_Fetch );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_Fetch, (pstmt->dhstmt) )
#if 0
retcode = hproc( pstmt->dhstmt );
#endif
/* state transition */
if( pstmt->asyn_on == en_Fetch )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_cursoropen:
case en_stmt_fetched:
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
pstmt->state = en_stmt_fetched;
pstmt->cursor_state = en_stmt_cursor_fetched;
break;
case SQL_NO_DATA_FOUND:
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
}
else
{
pstmt->state = en_stmt_allocated;
}
pstmt->cursor_state = en_stmt_cursor_no;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_Fetch;
break;
default:
break;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLExtendedFetch (
HSTMT hstmt,
UWORD fFetchType,
SDWORD irow,
UDWORD FAR* pcrow,
UWORD FAR* rgfRowStatus )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check fetch type */
if( fFetchType < SQL_FETCH_NEXT
|| fFetchType > SQL_FETCH_BOOKMARK )
{
/* Unlike MS driver manager(i.e. DM),
* we don't check driver's ODBC version
* against SQL_FETCH_RESUME (only 1.0)
* and SQL_FETCH_BOOKMARK (only 2.0).
*/
PUSHSQLERR ( pstmt->herr, en_S1106 );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_fetched:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
default:
break;
}
}
else if( pstmt->asyn_on != en_ExtendedFetch )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_ExtendedFetch );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_ExtendedFetch, (
pstmt->dhstmt,
fFetchType,
irow,
pcrow,
rgfRowStatus ) )
#if 0
retcode = hproc(pstmt->dhstmt,
fFetchType,
irow,
pcrow,
rgfRowStatus );
#endif
/* state transition */
if( pstmt->asyn_on == en_ExtendedFetch )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_cursoropen:
case en_stmt_xfetched:
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
pstmt->state = en_stmt_xfetched;
pstmt->cursor_state = en_stmt_cursor_xfetched;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_ExtendedFetch;
break;
default:
break;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLGetData(
HSTMT hstmt,
UWORD icol,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR* pcbValue )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
if( rgbValue == NULL )
{
sqlstat = en_S1009;
}
else if( cbValueMax < 0 )
{
sqlstat = en_S1090;
}
else
{
switch(fCType)
{
case SQL_C_DEFAULT:
case SQL_C_CHAR:
case SQL_C_BINARY:
case SQL_C_BIT:
case SQL_C_TINYINT:
case SQL_C_STINYINT:
case SQL_C_UTINYINT:
case SQL_C_SHORT:
case SQL_C_SSHORT:
case SQL_C_USHORT:
case SQL_C_LONG:
case SQL_C_SLONG:
case SQL_C_ULONG:
case SQL_C_FLOAT:
case SQL_C_DOUBLE:
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
break;
default:
sqlstat = en_S1003;
break;
}
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
sqlstat = en_S1010;
break;
case en_stmt_executed:
case en_stmt_cursoropen:
sqlstat = en_24000;
break;
default:
break;
}
}
else if( pstmt->asyn_on != en_GetData )
{
sqlstat = en_S1010;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_GetData );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_GetData, (
pstmt->dhstmt,
icol,
fCType,
rgbValue,
cbValueMax,
pcbValue ) )
#if 0
retcode = hproc(pstmt->dhstmt,
icol,
fCType,
rgbValue,
cbValueMax,
pcbValue );
#endif
/* state transition */
if( pstmt->asyn_on == en_GetData )
{
switch ( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_fetched:
case en_stmt_xfetched:
if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_GetData;
break;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLMoreResults( HSTMT hstmt )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
return SQL_NO_DATA_FOUND;
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
default:
break;
}
}
else if( pstmt->asyn_on != en_MoreResults )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_MoreResults );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_MoreResults, (pstmt->dhstmt) )
#if 0
retcode = hproc( pstmt->dhstmt );
#endif
/* state transition */
if( pstmt->asyn_on == en_MoreResults )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
/* driver should return SQL_NO_DATA_FOUND */
break;
case en_stmt_executed:
if( retcode == SQL_NO_DATA_FOUND )
{
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
}
else
{
pstmt->state = en_stmt_allocated;
}
}
else if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_MoreResults;
}
break;
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
if( retcode == SQL_SUCCESS )
{
break;
}
else if( retcode == SQL_NO_DATA_FOUND )
{
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
}
else
{
pstmt->state = en_stmt_allocated;
}
}
else if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_MoreResults;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLSetPos (
HSTMT hstmt,
UWORD irow,
UWORD fOption,
UWORD fLock )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument value */
if( fOption > SQL_ADD
|| fLock > SQL_LOCK_UNLOCK )
{
PUSHSQLERR ( pstmt->herr, en_S1009 );
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_fetched:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
sqlstat = en_S1010;
break;
case en_stmt_executed:
case en_stmt_cursoropen:
sqlstat = en_24000;
break;
default:
break;
}
}
else if( pstmt->asyn_on != en_SetPos )
{
sqlstat = en_S1010;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetPos );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetPos, (
pstmt->dhstmt,
irow,
fOption,
fLock ) )
#if 0
retcode = hproc(pstmt->dhstmt,
irow,
fOption,
fLock );
#endif
/* state transition */
if( pstmt->asyn_on == en_SetPos )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NEED_DATA:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
/* now, the only possible init state is 'xfetched' */
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
break;
case SQL_NEED_DATA:
pstmt->state = en_stmt_needdata;
pstmt->need_on = en_SetPos;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_SetPos;
break;
default:
break;
}
return retcode;
}

804
src/iodbc/hdbc.c Normal file
View File

@ -0,0 +1,804 @@
/** data source connect object management functions
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
#include <stdio.h>
RETCODE SQL_API SQLAllocConnect(
HENV henv,
HDBC FAR* phdbc )
{
GENV_t FAR* genv = (GENV_t FAR*)henv;
DBC_t FAR* pdbc;
#if (ODBCVER >= 0x0300)
if( henv == SQL_NULL_HENV
|| genv->type != SQL_HANDLE_ENV )
#else
if( henv == SQL_NULL_HENV )
#endif
{
return SQL_INVALID_HANDLE;
}
if( phdbc == NULL )
{
PUSHSQLERR ( genv->herr, en_S1009 );
return SQL_ERROR;
}
pdbc = (DBC_t FAR*)MEM_ALLOC (sizeof(DBC_t));
if( pdbc == NULL )
{
*phdbc = SQL_NULL_HDBC;
PUSHSQLERR ( genv->herr, en_S1001 );
return SQL_ERROR;
}
#if (ODBCVER >= 0x0300)
pdbc->type = SQL_HANDLE_DBC;
#endif
/* insert this dbc entry into the link list */
pdbc->next = genv->hdbc;
genv->hdbc = pdbc;
pdbc->genv = henv;
pdbc->henv = SQL_NULL_HENV;
pdbc->hstmt= SQL_NULL_HSTMT;
pdbc->herr = SQL_NULL_HERR;
pdbc->dhdbc= SQL_NULL_HDBC;
pdbc->state= en_dbc_allocated;
pdbc->trace = 0;
pdbc->tstm = NULL;
pdbc->tfile = NULL;
/* set connect options to default values */
pdbc->access_mode = SQL_MODE_DEFAULT;
pdbc->autocommit = SQL_AUTOCOMMIT_DEFAULT;
pdbc->current_qualifier = NULL;
pdbc->login_timeout = 0UL;
pdbc->odbc_cursors = SQL_CUR_DEFAULT;
pdbc->packet_size = 0UL;
pdbc->quiet_mode = (UDWORD)NULL;
pdbc->txn_isolation = SQL_TXN_READ_UNCOMMITTED;
pdbc->cb_commit = (SWORD)SQL_CB_DELETE;
pdbc->cb_rollback = (SWORD)SQL_CB_DELETE;
*phdbc = (HDBC)pdbc;
return SQL_SUCCESS;
}
RETCODE SQL_API SQLFreeConnect( HDBC hdbc )
{
GENV_t FAR* genv;
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
DBC_t FAR* tpdbc;
if( hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pdbc->state != en_dbc_allocated )
{
PUSHSQLERR ( pdbc->herr, en_S1010 );
return SQL_ERROR;
}
genv = (GENV_t FAR*)pdbc->genv;
for( tpdbc = (DBC_t FAR*)genv->hdbc;
tpdbc != NULL;
tpdbc = tpdbc->next )
{
if( pdbc == tpdbc )
{
genv->hdbc = pdbc->next;
break;
}
if( pdbc == tpdbc->next )
{
tpdbc->next = pdbc->next;
break;
}
}
/* free this dbc */
_iodbcdm_driverunload(pdbc);
_iodbcdm_freesqlerrlist( pdbc->herr );
if( pdbc->tfile )
{
MEM_FREE( pdbc->tfile );
}
SQLSetConnectOption( pdbc, SQL_OPT_TRACE, SQL_OPT_TRACE_OFF);
MEM_FREE ( pdbc );
return SQL_SUCCESS;
}
RETCODE SQL_API SQLSetConnectOption(
HDBC hdbc,
UWORD fOption,
UDWORD vParam )
{
GENV_t FAR* genv;
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
STMT_t FAR* pstmt;
HPROC hproc = SQL_NULL_HPROC;
int sqlstat = en_00000;
RETCODE retcode = SQL_SUCCESS;
if( hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check option */
if( fOption < SQL_CONN_OPT_MIN
|| ( fOption > SQL_CONN_OPT_MAX
&& fOption < SQL_CONNECT_OPT_DRVR_START ) )
{
PUSHSQLERR ( pdbc->herr, en_S1092 );
return SQL_ERROR;
}
/* check state of connection handle */
switch( pdbc->state )
{
case en_dbc_allocated:
if( fOption == SQL_TRANSLATE_DLL
|| fOption == SQL_TRANSLATE_OPTION )
{
/* This two options are only meaningful
* for specified driver. So, has to be
* set after a dirver has been loaded.
*/
sqlstat = en_08003;
break;
}
if( fOption >= SQL_CONNECT_OPT_DRVR_START
&& pdbc->henv == SQL_NULL_HENV )
/* An option only meaningful for drivers
* is passed before loading a driver.
* We classify this as an invalid option error.
* This is not documented by MS SDK guide.
*/
{
sqlstat = en_S1092;
break;
}
break;
case en_dbc_needdata:
sqlstat = en_S1010;
break;
case en_dbc_connected:
case en_dbc_hstmt:
if( fOption == SQL_ODBC_CURSORS )
{
sqlstat = en_08002;
}
break;
default:
break;
}
/* check state of statement handle(s) */
for( pstmt = (STMT_t FAR*)pdbc->hstmt;
pstmt != NULL && sqlstat == en_00000;
pstmt = (STMT_t FAR*)pstmt->next )
{
if( pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc )
{
sqlstat = en_S1010;
}
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pdbc->herr, sqlstat );
return SQL_ERROR;
}
if( fOption == SQL_OPT_TRACE )
/* tracing flag can be set before and after connect
* and only meaningful for driver manager(actually
* there is only one tracing file under one global
* environment).
*/
{
switch( vParam )
{
case SQL_OPT_TRACE_ON:
if( pdbc->tfile == NULL )
{
pdbc->tfile = (char FAR*)MEM_ALLOC( 1 +
STRLEN(SQL_OPT_TRACE_FILE_DEFAULT) );
if( pdbc->tfile == NULL )
{
PUSHSQLERR( pdbc->herr, en_S1001 );
return SQL_ERROR;
}
STRCPY( pdbc->tfile, SQL_OPT_TRACE_FILE_DEFAULT );
}
if( pdbc->tstm == NULL )
{
#if defined(stderr) && defined(stdout)
if(STREQ( pdbc->tfile, "stderr"))
{
pdbc->tstm = stderr;
}
else
if(STREQ(pdbc->tfile, "stdout"))
{
pdbc->tstm = stdout;
}
else
#endif
{
pdbc->tstm
= fopen(pdbc->tfile, "a+");
}
if(pdbc->tstm )
{
pdbc->trace = 1;
}
else
{
pdbc->trace = 0;
sqlstat = en_IM013;
retcode = SQL_ERROR;
}
}
break;
case SQL_OPT_TRACE_OFF:
if( pdbc->trace && pdbc->tstm )
{
#if defined(stderr) && defined(stdout)
if( stderr != (FILE FAR*)(pdbc->tstm)
&& stdout != (FILE FAR*)(pdbc->tstm) )
#endif
{
fclose(pdbc->tstm);
}
}
pdbc->tstm = NULL;
pdbc->trace = 0;
break;
default:
PUSHSQLERR (pdbc->herr, en_S1009);
retcode = SQL_ERROR;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pdbc->herr, sqlstat );
}
return retcode;
}
if( fOption == SQL_OPT_TRACEFILE )
/* Tracing file can be set before and after connect
* and only meaningful for driver manager.
*/
{
if( vParam == 0UL
|| ((char FAR*)vParam)[0] == 0 )
{
PUSHSQLERR ( pdbc->herr, en_S1009 );
return SQL_ERROR;
}
if( pdbc->tfile && STREQ (pdbc->tfile, vParam) )
{
return SQL_SUCCESS;
}
if( pdbc->trace )
{
PUSHSQLERR ( pdbc->herr, en_IM014 );
return SQL_ERROR;
}
if( pdbc->tfile )
{
MEM_FREE( pdbc->tfile );
}
pdbc->tfile = (char FAR*)MEM_ALLOC( 1 + STRLEN( vParam ) );
if( pdbc->tfile == NULL )
{
PUSHSQLERR( pdbc->herr, en_S1001 );
return SQL_ERROR;
}
STRCPY ( pdbc->tfile, vParam );
return SQL_SUCCESS;
}
if( pdbc->state != en_dbc_allocated )
{
/* If already connected, then, driver's odbc call
* will be invoked. Otherwise, we only save the options
* and delay the setting process until the connection
* been established.
*/
hproc = _iodbcdm_getproc( hdbc, en_SetConnectOption );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pdbc->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( hdbc, retcode, hproc, en_SetConnectOption, (
pdbc->dhdbc, fOption, vParam ) )
#if 0
retcode = hproc( pdbc->dhdbc, fOption, vParam);
#endif
if( retcode != SQL_SUCCESS
&& retcode != SQL_SUCCESS_WITH_INFO )
{
return retcode;
}
}
/*
* Now, either driver's odbc call was successed or
* driver has not been loaded yet. In the first case, we
* need flip flag for(such as access_mode, autocommit, ...)
* for our finit state machine. While in the second case,
* we need save option values(such as current_qualifier, ...)
* for delaied setting. So, ...
*/
/* No matter what state we are(i.e. allocated or connected, ..)
* we need to flip the flag.
*/
switch( fOption )
{
case SQL_ACCESS_MODE:
pdbc->access_mode = vParam;
break;
case SQL_AUTOCOMMIT:
pdbc->autocommit = vParam;
break;
}
/* state transition */
if( pdbc->state != en_dbc_allocated )
{
return retcode;
}
/* Only 'allocated' state is possible here, and we need to
* save the options for delaied setting.
*/
switch( fOption )
{
case SQL_CURRENT_QUALIFIER:
if( pdbc->current_qualifier != NULL )
{
MEM_FREE ( pdbc->current_qualifier );
}
if( vParam == 0UL )
{
pdbc->current_qualifier = NULL;
break;
}
pdbc->current_qualifier
= (char FAR*)MEM_ALLOC (
STRLEN (vParam) + 1 );
if( pdbc->current_qualifier == NULL )
{
PUSHSQLERR ( pdbc->herr, en_S1001 );
return SQL_ERROR;
}
STRCPY ( pdbc->current_qualifier, vParam );
break;
case SQL_LOGIN_TIMEOUT:
pdbc->login_timeout = vParam;
break;
case SQL_ODBC_CURSORS:
pdbc->odbc_cursors = vParam;
break;
case SQL_PACKET_SIZE:
pdbc->packet_size = vParam;
break;
case SQL_QUIET_MODE:
pdbc->quiet_mode = vParam;
break;
case SQL_TXN_ISOLATION:
pdbc->txn_isolation = vParam;
break;
default:
/* Since we didn't save the option value for delaied
* setting, we should raise an error here.
*/
break;
}
return retcode;
}
RETCODE SQL_API SQLGetConnectOption(
HDBC hdbc,
UWORD fOption,
PTR pvParam )
{
GENV_t FAR* genv;
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
int sqlstat = en_00000;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
if( hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check option */
if( fOption < SQL_CONN_OPT_MIN
|| ( fOption > SQL_CONN_OPT_MAX
&& fOption < SQL_CONNECT_OPT_DRVR_START ) )
{
PUSHSQLERR ( pdbc->herr, en_S1092 );
return SQL_ERROR;
}
/* check state */
switch( pdbc->state )
{
case en_dbc_allocated:
if( fOption != SQL_ACCESS_MODE
&& fOption != SQL_AUTOCOMMIT
&& fOption != SQL_LOGIN_TIMEOUT
&& fOption != SQL_OPT_TRACE
&& fOption != SQL_OPT_TRACEFILE )
{
sqlstat = en_08003;
}
/* MS ODBC SDK document only
* allows SQL_ACCESS_MODE
* and SQL_AUTOCOMMIT in this
* dbc state. We allow another
* two options, because they
* are only meaningful for driver
* manager.
*/
break;
case en_dbc_needdata:
sqlstat = en_S1010;
break;
default:
break;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pdbc->herr, sqlstat );
return SQL_ERROR;
}
/* Tracing and tracing file options are only
* meaningful for driver manager
*/
if( fOption == SQL_OPT_TRACE )
{
if( pdbc->trace )
*((UDWORD*)pvParam) = (UDWORD)SQL_OPT_TRACE_ON;
else
*((UDWORD*)pvParam) = (UDWORD)SQL_OPT_TRACE_OFF;
return SQL_SUCCESS;
}
if( fOption == SQL_OPT_TRACEFILE )
{
STRCPY (pvParam, pdbc->tfile );
return SQL_ERROR;
}
if( pdbc->state != en_dbc_allocated )
/* if already connected, we will invoke driver's function */
{
hproc = _iodbcdm_getproc( hdbc, en_GetConnectOption );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR( pdbc->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( hdbc, retcode, hproc, en_GetConnectOption, (
pdbc->dhdbc, fOption, pvParam ) )
#if 0
retcode = hproc(pdbc->dhdbc, fOption, pvParam);
#endif
return retcode;
}
/* We needn't to handle options which are not allowed
* to be *get* at a allocated dbc state(and two tracing
* options which has been handled and returned). Thus,
* there are only two possible cases.
*/
switch( fOption )
{
case SQL_ACCESS_MODE:
*((UDWORD*)pvParam) = pdbc->access_mode;
break;
case SQL_AUTOCOMMIT:
*((UDWORD*)pvParam) = pdbc->autocommit;
break;
case SQL_LOGIN_TIMEOUT:
*((UDWORD*)pvParam) = pdbc->login_timeout;
break;
default:
break;
}
return SQL_SUCCESS;
}
static RETCODE _iodbcdm_transact(
HDBC hdbc,
UWORD fType )
{
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
STMT_t FAR* pstmt;
HPROC hproc;
RETCODE retcode;
/* check state */
switch( pdbc->state )
{
case en_dbc_allocated:
case en_dbc_needdata:
PUSHSQLERR ( pdbc->herr, en_08003 );
return SQL_ERROR;
case en_dbc_connected:
return SQL_SUCCESS;
case en_dbc_hstmt:
default:
break;
}
for( pstmt = (STMT_t FAR*)(pdbc->hstmt);
pstmt != NULL;
pstmt = pstmt->next )
{
if( pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc )
{
PUSHSQLERR ( pdbc->herr, en_S1010 );
return SQL_ERROR;
}
}
hproc = _iodbcdm_getproc( hdbc, en_Transact );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pdbc->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( hdbc, retcode, hproc, en_Transact, (
SQL_NULL_HENV, pdbc->dhdbc, fType ) )
#if 0
retcode = hproc( SQL_NULL_HENV, pdbc->dhdbc, fType );
#endif
/* state transition */
if( retcode != SQL_SUCCESS
&& retcode != SQL_SUCCESS_WITH_INFO )
{
return retcode;
}
pdbc->state = en_dbc_hstmt;
for( pstmt = (STMT_t FAR*)(pdbc->hstmt);
pstmt != NULL;
pstmt = pstmt->next )
{
switch( pstmt->state )
{
case en_stmt_prepared:
if( pdbc->cb_commit == SQL_CB_DELETE
|| pdbc->cb_rollback == SQL_CB_DELETE )
{
pstmt->state = en_stmt_allocated;
pstmt->prep_state = 0;
break;
}
break;
case en_stmt_executed:
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
if( ! pstmt->prep_state
&& pdbc->cb_commit != SQL_CB_PRESERVE
&& pdbc->cb_rollback != SQL_CB_PRESERVE )
{
pstmt->state = en_stmt_allocated;
pstmt->prep_state = 0;
pstmt->cursor_state = en_stmt_cursor_no;
break;
}
if( pstmt->prep_state )
{
if( pdbc->cb_commit == SQL_CB_DELETE
|| pdbc->cb_rollback== SQL_CB_DELETE )
{
pstmt->state = en_stmt_allocated;
pstmt->prep_state = 0;
pstmt->cursor_state = en_stmt_cursor_no;
break;
}
if( pdbc->cb_commit == SQL_CB_CLOSE
|| pdbc->cb_rollback== SQL_CB_CLOSE )
{
pstmt->state
= en_stmt_prepared;
pstmt->cursor_state
= en_stmt_cursor_no;
break;
}
break;
}
break;
default:
break;
}
}
return retcode;
}
RETCODE SQL_API SQLTransact(
HENV henv,
HDBC hdbc,
UWORD fType )
{
GENV_t FAR* genv = (GENV_t FAR*)henv;
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
HERR herr;
RETCODE retcode;
if( hdbc != SQL_NULL_HDBC )
{
herr = pdbc->herr;
}
else if( henv != SQL_NULL_HENV )
{
herr = genv->herr;
}
else
{
return SQL_INVALID_HANDLE;
}
/* check argument */
if( fType != SQL_COMMIT
&& fType != SQL_ROLLBACK )
{
PUSHSQLERR ( herr, en_S1012 );
return SQL_ERROR;
}
if( hdbc != SQL_NULL_HDBC )
{
retcode = _iodbcdm_transact( hdbc, fType );
}
else
{
for( pdbc = (DBC_t FAR*)(genv->hdbc);
pdbc != NULL;
pdbc = pdbc->next )
{
retcode |= _iodbcdm_transact( hdbc, fType );
}
}
if( retcode != SQL_SUCCESS
&& retcode != SQL_SUCCESS_WITH_INFO )
{
/* fail on one of the connection */
return SQL_ERROR;
}
return retcode;
}

67
src/iodbc/hdbc.h Normal file
View File

@ -0,0 +1,67 @@
#ifndef _HDBC_H
#define _HDBC_H
typedef struct DBC
{
int type; /* must be 1st field */
struct DBC FAR*
next;
HENV genv; /* back point to global env object */
HDBC dhdbc; /* driver's private dbc */
HENV henv; /* back point to instant env object */
HSTMT hstmt; /* list of statement object handle(s) */
HERR herr;
int state;
/* options */
UDWORD access_mode;
UDWORD autocommit;
UDWORD login_timeout;
UDWORD odbc_cursors;
UDWORD packet_size;
UDWORD quiet_mode;
UDWORD txn_isolation;
SWORD cb_commit;
SWORD cb_rollback;
char FAR*
current_qualifier;
int trace; /* trace flag */
char FAR*
tfile;
void FAR*
tstm; /* trace stream */
} DBC_t;
/*
* Note:
* - ODBC applications can see address of driver manager's
* connection object, i.e connection handle -- a void pointer,
* but not detail of it. ODBC applications can neither see
* detail driver's connection object nor its address.
*
* - ODBC driver manager knows its own connection objects and
* exposes their address to an ODBC application. Driver manager
* also knows address of driver's connection objects and keeps
* it via dhdbc field in driver manager's connection object.
*
* - ODBC driver exposes address of its own connection object to
* driver manager without detail.
*
* - Applications can get driver's connection object handle by
* SQLGetInfo() with fInfoType equals to SQL_DRIVER_HDBC.
*/
enum {
en_dbc_allocated,
en_dbc_needdata,
en_dbc_connected,
en_dbc_hstmt
};
#endif

75
src/iodbc/henv.c Normal file
View File

@ -0,0 +1,75 @@
/** Environment object managment functions
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/itrace.h>
RETCODE SQL_API SQLAllocEnv( HENV FAR* phenv )
{
GENV_t FAR* genv;
genv = (GENV_t*)MEM_ALLOC( sizeof(GENV_t) );
if( genv == NULL )
{
*phenv = SQL_NULL_HENV;
return SQL_ERROR;
}
#if (ODBCVER >= 0x0300 )
genv->type = SQL_HANDLE_ENV;
#endif
genv->henv = SQL_NULL_HENV; /* driver's env list */
genv->hdbc = SQL_NULL_HDBC; /* driver's dbc list */
genv->herr = SQL_NULL_HERR; /* err list */
*phenv = (HENV)genv;
return SQL_SUCCESS;
}
RETCODE SQL_API SQLFreeEnv ( HENV henv )
{
GENV_t FAR* genv = (GENV_t*)henv;
if( henv == SQL_NULL_HENV )
{
return SQL_INVALID_HANDLE;
}
if( genv->hdbc != SQL_NULL_HDBC )
{
PUSHSQLERR ( genv->herr, en_S1010 );
return SQL_ERROR;
}
_iodbcdm_freesqlerrlist( genv->herr );
MEM_FREE( henv );
return SQL_SUCCESS;
}

95
src/iodbc/henv.ci Normal file
View File

@ -0,0 +1,95 @@
#ifdef __HPUX__
#define CLI_NAME_PREFIX "_SQL"
#endif
#ifdef __AIX__
#define CLI_NAME_PREFIX ".SQL"
#endif
#ifndef CLI_NAME_PREFIX
/* There are some exceptions :
* on FreeBSD 2.x CLI_NAME_PREFIX is defined in Config.mk as "_SQL"
* on HP/UX s300/s400, CLI_NAME_PREFIX is defined in Config.mk as "_SQL"
* on AIX 3.x 4.x, CLI_NAME_PREFIX is defined in Config.mk as ".SQL"
*/
# define CLI_NAME_PREFIX "SQL" /* using call by value prefix */
#endif
static struct {
int en_idx;
char* symbol;
} odbcapi_symtab[] = {
#if (ODBCVER >= 0x0300)
en_AllocHandle CLI_NAME_PREFIX "AllocHandle",
en_FreeHandle CLI_NAME_PREFIX "FreeHandle",
#endif
en_AllocEnv, CLI_NAME_PREFIX "AllocEnv",
en_AllocConnect, CLI_NAME_PREFIX "AllocConnect",
en_Connect, CLI_NAME_PREFIX "Connect",
en_DriverConnect, CLI_NAME_PREFIX "DriverConnect",
en_BrowseConnect, CLI_NAME_PREFIX "BrowseConnect",
en_DataSources, CLI_NAME_PREFIX "DataSources",
en_Drivers, CLI_NAME_PREFIX "Driver",
en_GetInfo, CLI_NAME_PREFIX "GetInfo",
en_GetFunctions, CLI_NAME_PREFIX "GetFunctions",
en_GetTypeInfo, CLI_NAME_PREFIX "GetTypeInfo",
en_SetConnectOption, CLI_NAME_PREFIX "SetConnectOption",
en_GetConnectOption, CLI_NAME_PREFIX "GetConnectOption",
en_SetStmtOption, CLI_NAME_PREFIX "SetStmtOption",
en_GetStmtOption, CLI_NAME_PREFIX "GetStmtOption",
en_AllocStmt, CLI_NAME_PREFIX "AllocStmt",
en_Prepare, CLI_NAME_PREFIX "Prepare",
en_BindParameter, CLI_NAME_PREFIX "BindParameter",
en_ParamOptions, CLI_NAME_PREFIX "ParamOptions",
en_GetCursorName, CLI_NAME_PREFIX "GetCursorName",
en_SetCursorName, CLI_NAME_PREFIX "SetCursorName",
en_SetScrollOptions, CLI_NAME_PREFIX "SetScrollOptions",
en_SetParam, CLI_NAME_PREFIX "SetParam",
en_Execute, CLI_NAME_PREFIX "Execute",
en_ExecDirect, CLI_NAME_PREFIX "ExecDirect",
en_NativeSql, CLI_NAME_PREFIX "NativeSql",
en_DescribeParam, CLI_NAME_PREFIX "DescribeParam",
en_NumParams, CLI_NAME_PREFIX "NumParams",
en_ParamData, CLI_NAME_PREFIX "ParamData",
en_PutData, CLI_NAME_PREFIX "PutData",
en_RowCount, CLI_NAME_PREFIX "RowCount",
en_NumResultCols, CLI_NAME_PREFIX "NumResultCols",
en_DescribeCol, CLI_NAME_PREFIX "DescribeCol",
en_ColAttributes, CLI_NAME_PREFIX "ColAttributes",
en_BindCol, CLI_NAME_PREFIX "BindCol",
en_Fetch, CLI_NAME_PREFIX "Fetch",
en_ExtendedFetch, CLI_NAME_PREFIX "ExtendedFetch",
en_GetData, CLI_NAME_PREFIX "GetData",
en_SetPos, CLI_NAME_PREFIX "SetPos",
en_MoreResults, CLI_NAME_PREFIX "MoreResults",
en_Error, CLI_NAME_PREFIX "Error",
en_ColumnPrivileges, CLI_NAME_PREFIX "ColumnPrivileges",
en_Columns, CLI_NAME_PREFIX "Columns",
en_ForeignKeys, CLI_NAME_PREFIX "ForeignKeys",
en_PrimaryKeys, CLI_NAME_PREFIX "PrimaryKeys",
en_ProcedureColumns, CLI_NAME_PREFIX "ProcedureColumns",
en_Procedures, CLI_NAME_PREFIX "Procedures",
en_SpecialColumns, CLI_NAME_PREFIX "SpecialColumns",
en_Statistics, CLI_NAME_PREFIX "Statistics",
en_TablePrivileges, CLI_NAME_PREFIX "TablePrivileges",
en_Tables, CLI_NAME_PREFIX "Tables",
en_FreeStmt, CLI_NAME_PREFIX "FreeStmt",
en_Cancel, CLI_NAME_PREFIX "Cancel",
en_Transact, CLI_NAME_PREFIX "Transact",
en_Disconnect, CLI_NAME_PREFIX "Disconnect",
en_FreeConnect, CLI_NAME_PREFIX "FreeConnect",
en_FreeEnv, CLI_NAME_PREFIX "FreeEnv",
en_NullProc, NULL
};

125
src/iodbc/henv.h Normal file
View File

@ -0,0 +1,125 @@
#ifndef _HENV_H
#define _HENV_H
# include <../iodbc/config.h>
# include <../iodbc/dlproc.h>
# include <../iodbc/isql.h>
# include <../iodbc/isqlext.h>
enum {
#if (ODBCVER >= 0x0300)
en_AllocHandle = SQL_API_SQLALLOCHANDLE,
en_FreeHandle = SQL_API_SQLFREEHANDLE,
#endif
en_AllocEnv = SQL_API_SQLALLOCENV,
en_AllocConnect = SQL_API_SQLALLOCCONNECT,
en_Connect = SQL_API_SQLCONNECT,
en_DriverConnect = SQL_API_SQLDRIVERCONNECT,
en_BrowseConnect = SQL_API_SQLBROWSECONNECT,
en_DataSources = SQL_API_SQLDATASOURCES,
en_Drivers = SQL_API_SQLDRIVERS,
en_GetInfo = SQL_API_SQLGETINFO,
en_GetFunctions = SQL_API_SQLGETFUNCTIONS,
en_GetTypeInfo = SQL_API_SQLGETTYPEINFO,
en_SetConnectOption = SQL_API_SQLSETCONNECTOPTION,
en_GetConnectOption = SQL_API_SQLGETCONNECTOPTION,
en_SetStmtOption = SQL_API_SQLSETSTMTOPTION,
en_GetStmtOption = SQL_API_SQLGETSTMTOPTION,
en_AllocStmt = SQL_API_SQLALLOCSTMT,
en_Prepare = SQL_API_SQLPREPARE,
en_BindParameter = SQL_API_SQLBINDPARAMETER,
en_ParamOptions = SQL_API_SQLPARAMOPTIONS,
en_GetCursorName = SQL_API_SQLGETCURSORNAME,
en_SetCursorName = SQL_API_SQLSETCURSORNAME,
en_SetScrollOptions = SQL_API_SQLSETSCROLLOPTIONS,
en_SetParam = SQL_API_SQLSETPARAM,
en_Execute = SQL_API_SQLEXECUTE,
en_ExecDirect = SQL_API_SQLEXECDIRECT,
en_NativeSql = SQL_API_SQLNATIVESQL,
en_DescribeParam = SQL_API_SQLDESCRIBEPARAM,
en_NumParams = SQL_API_SQLNUMPARAMS,
en_ParamData = SQL_API_SQLPARAMDATA,
en_PutData = SQL_API_SQLPUTDATA,
en_RowCount = SQL_API_SQLROWCOUNT,
en_NumResultCols = SQL_API_SQLNUMRESULTCOLS,
en_DescribeCol = SQL_API_SQLDESCRIBECOL,
en_ColAttributes = SQL_API_SQLCOLATTRIBUTES,
en_BindCol = SQL_API_SQLBINDCOL,
en_Fetch = SQL_API_SQLFETCH,
en_ExtendedFetch = SQL_API_SQLEXTENDEDFETCH,
en_GetData = SQL_API_SQLGETDATA,
en_SetPos = SQL_API_SQLSETPOS,
en_MoreResults = SQL_API_SQLMORERESULTS,
en_Error = SQL_API_SQLERROR,
en_ColumnPrivileges = SQL_API_SQLCOLUMNPRIVILEGES,
en_Columns = SQL_API_SQLCOLUMNS,
en_ForeignKeys = SQL_API_SQLFOREIGNKEYS,
en_PrimaryKeys = SQL_API_SQLPRIMARYKEYS,
en_ProcedureColumns = SQL_API_SQLPROCEDURECOLUMNS,
en_Procedures = SQL_API_SQLPROCEDURES,
en_SpecialColumns = SQL_API_SQLSPECIALCOLUMNS,
en_Statistics = SQL_API_SQLSTATISTICS,
en_TablePrivileges = SQL_API_SQLTABLEPRIVILEGES,
en_Tables = SQL_API_SQLTABLES,
en_FreeStmt = SQL_API_SQLFREESTMT,
en_Cancel = SQL_API_SQLCANCEL,
en_Transact = SQL_API_SQLTRANSACT,
en_Disconnect = SQL_API_SQLDISCONNECT,
en_FreeConnect = SQL_API_SQLFREECONNECT,
en_FreeEnv = SQL_API_SQLFREEENV,
en_NullProc = SYSERR
};
typedef struct {
int type; /* must be 1st field */
HENV henv; /* driver's env list */
HDBC hdbc; /* driver's dbc list */
HERR herr; /* err list */
int state;
} GENV_t;
typedef struct {
HENV next; /* next attached env handle */
int refcount; /* Driver's bookkeeping reference count */
HPROC dllproc_tab[SQL_EXT_API_LAST + 1]; /* driver api calls */
HENV dhenv; /* driver env handle */
HDLL hdll; /* drvier share library handle */
} ENV_t;
/* Note:
*
* - ODBC applications only know about global environment handle,
* a void pointer points to a GENV_t object. There is only one
* this object per process(however, to make the library reentrant,
* we still keep this object on heap). Applications only know
* address of this object and needn't care about its detail.
*
* - ODBC driver manager knows about instance environment handles,
* void pointers point to ENV_t objects. There are maybe more
* than one this kind of objects per process. However, multiple
* connections to a same data source(i.e. call same share library)
* will share one instance environment object.
*
* - ODBC drvier manager knows about their own environemnt handle,
* a void pointer point to a driver defined object. Every driver
* keeps one of its own environment object and driver manager
* keeps address of it by the 'dhenv' field in the instance
* environment object without care about its detail.
*
* - Applications can get driver's environment object handle by
* SQLGetInfo() with fInfoType equals to SQL_DRIVER_HENV
*/
#endif

364
src/iodbc/herr.c Normal file
View File

@ -0,0 +1,364 @@
/** Error stack management functions
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
#include "../iodbc/herr.ci"
static HERR _iodbcdm_popsqlerr( HERR herr )
{
sqlerr_t* list = (sqlerr_t*)herr;
sqlerr_t* next;
if( herr == SQL_NULL_HERR )
{
return herr;
}
next = list->next;
MEM_FREE (list);
return next;
}
void _iodbcdm_freesqlerrlist( HERR herrlist )
{
HERR list;
for(list = herrlist; list!= 0; )
{
list = _iodbcdm_popsqlerr(list);
}
}
HERR _iodbcdm_pushsqlerr (
HERR herr,
sqlstcode_t code,
char* msg )
{
sqlerr_t* ebuf;
sqlerr_t* perr = (sqlerr_t*)herr;
int idx = 0;
if(herr != SQL_NULL_HERR )
{
idx = perr->idx + 1;
}
if( idx == 64 )
/* over wirte the top entry to prevent error stack blow out */
{
perr->code = code;
perr->msg = msg;
return herr;
}
ebuf = (sqlerr_t*)MEM_ALLOC (sizeof(sqlerr_t));
if( ebuf == NULL )
{
return NULL;
}
ebuf->msg = msg;
ebuf->code = code;
ebuf->idx = idx;
ebuf->next = (sqlerr_t*)herr;
return (HERR)ebuf;
}
static char FAR* _iodbcdm_getsqlstate (
HERR herr,
void FAR* tab )
{
sqlerr_t* perr = (sqlerr_t*)herr;
sqlerrmsg_t* ptr;
if( herr == SQL_NULL_HERR || tab == NULL )
{
return (char FAR*)NULL;
}
for( ptr = tab;
ptr->code != en_sqlstat_total;
ptr++ )
{
if(ptr->code == perr->code)
{
return (char FAR*)(ptr->stat);
}
}
return (char FAR*)NULL;
}
static char FAR* _iodbcdm_getsqlerrmsg(
HERR herr,
void FAR* errtab )
{
sqlerr_t* perr = (sqlerr_t*)herr;
sqlerrmsg_t* ptr;
if( herr == SQL_NULL_HERR )
{
return NULL;
}
if( perr->msg == NULL && errtab == NULL )
{
return NULL;
}
if( perr->msg != NULL )
{
return perr->msg;
}
for( ptr = (sqlerrmsg_t*)errtab;
ptr->code != en_sqlstat_total;
ptr++ )
{
if( ptr->code == perr->code )
{
return (char FAR*)ptr->msg;
}
}
return (char FAR*)NULL;
}
RETCODE SQL_API SQLError (
HENV henv,
HDBC hdbc,
HSTMT hstmt,
UCHAR FAR* szSqlstate,
SDWORD FAR* pfNativeError,
UCHAR FAR* szErrorMsg,
SWORD cbErrorMsgMax,
SWORD FAR* pcbErrorMsg )
{
GENV_t FAR* genv = (GENV_t FAR*) henv;
DBC_t FAR* pdbc = (DBC_t FAR*) hdbc;
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HDBC thdbc;
HENV dhenv = SQL_NULL_HENV;
HDBC dhdbc = SQL_NULL_HDBC;
HSTMT dhstmt = SQL_NULL_HSTMT;
HERR herr = SQL_NULL_HERR;
HPROC hproc = SQL_NULL_HPROC;
char FAR* errmsg = NULL;
char FAR* ststr = NULL;
int handle = 0;
RETCODE retcode = SQL_SUCCESS;
if( hstmt != SQL_NULL_HSTMT ) /* retrive stmt err */
{
herr = pstmt->herr;
thdbc = pstmt->hdbc;
if( thdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
hproc = _iodbcdm_getproc( thdbc, en_Error );
dhstmt = pstmt->dhstmt;
handle = 3;
}
else if( hdbc != SQL_NULL_HDBC ) /* retrive dbc err */
{
herr = pdbc->herr;
thdbc = hdbc;
if( thdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
hproc = _iodbcdm_getproc( thdbc, en_Error );
dhdbc = pdbc->dhdbc;
handle = 2;
if( herr == SQL_NULL_HERR
&& pdbc->henv == SQL_NULL_HENV )
{
return SQL_NO_DATA_FOUND;
}
}
else if( henv != SQL_NULL_HENV ) /* retrive env err */
{
herr = genv->herr;
/* Drivers shouldn't push error message
* on envoriment handle */
if( herr == SQL_NULL_HERR )
{
return SQL_NO_DATA_FOUND;
}
handle = 1;
}
else
{
return SQL_INVALID_HANDLE;
}
if( szErrorMsg != NULL )
{
if( cbErrorMsgMax < 0
|| cbErrorMsgMax > SQL_MAX_MESSAGE_LENGTH - 1 )
{
return SQL_ERROR;
/* SQLError() doesn't post error for itself */
}
}
if( herr == SQL_NULL_HERR ) /* no err on drv mng */
{
/* call driver */
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( thdbc, retcode, hproc, en_Error, (
dhenv, dhdbc, dhstmt,
szSqlstate, pfNativeError,
szErrorMsg, cbErrorMsgMax, pcbErrorMsg) )
#if 0
retcode = hproc(dhenv, dhdbc, dhstmt,
szSqlstate, pfNativeError,
szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
#endif
return retcode;
}
if( szSqlstate != NULL )
{
int len;
/* get sql state string */
ststr = (char FAR*)_iodbcdm_getsqlstate( herr,
(void FAR*)sqlerrmsg_tab );
if( ststr == NULL)
{
len = 0;
}
else
{
len = (int)STRLEN(ststr);
}
STRNCPY ( szSqlstate, ststr, len );
szSqlstate[len] = 0;
/* buffer size of szSqlstate is not checked. Applications
* suppose provide enough ( not less than 6 bytes ) buffer
* or NULL for it.
*/
}
if( pfNativeError != NULL )
{
/* native error code is specific to data source */
*pfNativeError = (SDWORD)0L;
}
if( szErrorMsg == NULL || cbErrorMsgMax == 0 )
{
if( pcbErrorMsg != NULL )
{
*pcbErrorMsg = (SWORD)0;
}
}
else
{
int len;
char msgbuf[256] = { '\0' };
/* get sql state message */
errmsg = _iodbcdm_getsqlerrmsg(herr,
(void FAR*)sqlerrmsg_tab);
if(errmsg == NULL)
{
errmsg = (char FAR*)"";
}
sprintf(msgbuf, "%s%s", sqlerrhd, errmsg);
len = STRLEN( msgbuf );
if( len < cbErrorMsgMax - 1 )
{
retcode = SQL_SUCCESS;
}
else
{
len = cbErrorMsgMax - 1;
retcode = SQL_SUCCESS_WITH_INFO;
/* and not posts error for itself */
}
STRNCPY((char*)szErrorMsg, msgbuf, len);
szErrorMsg[len] = 0;
if( pcbErrorMsg != NULL)
{
*pcbErrorMsg = (SWORD)len;
}
}
switch(handle) /* free this err */
{
case 1:
genv->herr = _iodbcdm_popsqlerr(genv->herr);
break;
case 2:
pdbc->herr = _iodbcdm_popsqlerr(pdbc->herr);
break;
case 3:
pstmt->herr= _iodbcdm_popsqlerr(pstmt->herr);
break;
default:
break;
}
return retcode;
}

98
src/iodbc/herr.ci Normal file
View File

@ -0,0 +1,98 @@
static const sqlerrmsg_t sqlerrmsg_tab[] =
{
en_00000, "00000", "",
en_01000, "01000", "General warning",
en_01002, "01002", "Disconnect error",
en_01004, "01004", "Data truncated",
en_01006, "01006", "Privilege not revoked",
en_01S00, "01S00", "Invalid connection string attribute",
en_01S01, "01S01", "Error in row",
en_01S02, "01S02", "Optional value changed",
en_01S03, "01S03", "No rows updated or deleted",
en_01S04, "01S04", "More than one row updated or deleted",
en_07001, "07001", "Wrong number of parameters",
en_07006, "07006", "Restricted data type attribute violation",
en_08001, "08001", "Unable to connect to data source",
en_08002, "08002", "Connection in use",
en_08003, "08003", "Connect not open",
en_08004, "08004", "Data source rejected establishment of connection",
en_08007, "08007", "Connection failure during transaction",
en_08S01, "08S01", "Communication link failure",
en_21S01, "21S01", "Insert value list does not match",
en_21S02, "21S02", "Degree of derived table does not match column list",
en_22001, "22001", "String data right truncation",
en_22003, "22003", "Numeric value out of range",
en_22005, "22005", "Error in assignment",
en_22008, "22008", "Datetime field overflow",
en_22012, "22012", "Division by zero",
en_22026, "22026", "String data, length mismatch",
en_23000, "23000", "Integrity constraint violation",
en_24000, "24000", "Invalid cursor state",
en_25000, "25000", "Invalid transaction state",
en_28000, "28000", "Invalid authorization specification",
en_34000, "34000", "Invalid cursor name",
en_37000, "37000", "Syntex error or access violation",
en_3C000, "3C000", "Duplicate cursor name",
en_40001, "40001", "Serialization failure",
en_42000, "42000", "Syntax error or access violation",
en_70100, "70100", "Operation aborted",
en_IM001, "IM001", "Driver does not support this function",
en_IM002, "IM002", "Data source name not found and no default "
"driver specified. Driver could not be loaded",
en_IM003, "IM003", "Specified driver could not be loaded",
en_IM004, "IM004", "Driver's SQLAllocEnv() failed",
en_IM005, "IM005", "Driver's SQLAllocConnect() failed",
en_IM006, "IM006", "Driver's SQLSetConnectOption failed",
en_IM007, "IM007", "No data source or driver specified, dialog prohibited",
en_IM008, "IM008", "Dialog failed",
en_IM009, "IM009", "Unable to load translation DLL",
en_IM010, "IM010", "Data source name too long",
en_IM011, "IM011", "Driver name too long",
en_IM012, "IM012", "DRIVER keyword syntax error",
en_IM013, "IM013", "Trace file error",
en_IM014, "IM014", "Try to change tracing file while tracing is on",
en_S0001, "S0001", "Base table or view already exists",
en_S0002, "S0002", "Base table not found",
en_S0011, "S0011", "Index already exists",
en_S0012, "S0012", "Index not found",
en_S0021, "S0021", "Column already exists",
en_S0022, "S0022", "Column not found",
en_S0023, "S0023", "No default for column",
en_S1000, "S1000", "General error",
en_S1001, "S1001", "Memory allocation failure",
en_S1002, "S1002", "Invalid column number",
en_S1003, "S1003", "Program type out of range",
en_S1004, "S1004", "SQL data type out of range",
en_S1008, "S1008", "Operation canceled",
en_S1009, "S1009", "Invalid argument value",
en_S1010, "S1010", "Function sequence error",
en_S1011, "S1011", "Operation invalid at this time",
en_S1012, "S1012", "Invalid transaction operation code specified",
en_S1015, "S1015", "No cursor name available",
en_S1090, "S1090", "Invalid string or buffer length",
en_S1091, "S1091", "Descriptor type out of range",
en_S1092, "S1092", "Option type out of range",
en_S1093, "S1093", "Invalid parameter",
en_S1094, "S1094", "Invalid scale value",
en_S1095, "S1095", "Function type out of range",
en_S1096, "S1096", "Information type out of range",
en_S1097, "S1097", "Column type out of range",
en_S1098, "S1098", "Scope type out of range",
en_S1099, "S1099", "Nullable type out of range",
en_S1100, "S1100", "Uniquenss option type out of range",
en_S1101, "S1101", "Accuracy option type out of range",
en_S1103, "S1103", "Direction option out of range",
en_S1104, "S1104", "Invalid precision value",
en_S1105, "S1105", "Invalid parameter type",
en_S1106, "S1106", "Fetch type out of range",
en_S1107, "S1107", "Row value out of range",
en_S1108, "S1108", "Concurrency option out of range",
en_S1109, "S1109", "Invalid cursor position",
en_S1110, "S1110", "Invalid driver completion",
en_S1111, "S1111", "Invalid bookmark value",
en_S1C00, "S1C00", "Driver not capable",
en_S1T00, "S1T00", "Timeout expired",
en_sqlstat_total, NULL, NULL
};
static char FAR* sqlerrhd = "[iODBC][Driver Manager]";

125
src/iodbc/herr.h Normal file
View File

@ -0,0 +1,125 @@
#ifndef _HERR_H
#define _HERR_H
typedef enum {
en_00000 = 0,
en_01000,
en_01002,
en_01004,
en_01006,
en_01S00,
en_01S01,
en_01S02,
en_01S03,
en_01S04,
en_07001,
en_07006,
en_08001,
en_08002,
en_08003,
en_08004,
en_08007,
en_08S01,
en_21S01,
en_21S02,
en_22001,
en_22003,
en_22005,
en_22008,
en_22012,
en_22026,
en_23000,
en_24000,
en_25000,
en_28000,
en_34000,
en_37000,
en_3C000,
en_40001,
en_42000,
en_70100,
en_IM001,
en_IM002,
en_IM003,
en_IM004,
en_IM005,
en_IM006,
en_IM007,
en_IM008,
en_IM009,
en_IM010,
en_IM011,
en_IM012,
en_IM013,
en_IM014,
en_S0001,
en_S0002,
en_S0011,
en_S0012,
en_S0021,
en_S0022,
en_S0023,
en_S1000,
en_S1001,
en_S1002,
en_S1003,
en_S1004,
en_S1008,
en_S1009,
en_S1010,
en_S1011,
en_S1012,
en_S1015,
en_S1090,
en_S1091,
en_S1092,
en_S1093,
en_S1094,
en_S1095,
en_S1096,
en_S1097,
en_S1098,
en_S1099,
en_S1100,
en_S1101,
en_S1103,
en_S1104,
en_S1105,
en_S1106,
en_S1107,
en_S1108,
en_S1109,
en_S1110,
en_S1111,
en_S1C00,
en_S1T00,
en_sqlstat_total
} sqlstcode_t;
typedef void FAR* HERR;
# define SQL_NULL_HERR ((HERR)NULL)
typedef struct
{
sqlstcode_t code;
char FAR* stat;
char FAR* msg;
} sqlerrmsg_t;
typedef struct sqlerr {
sqlstcode_t code;
int idx;
char FAR* msg;
struct sqlerr* next;
} sqlerr_t;
extern void _iodbcdm_freesqlerrlist( HERR herr );
extern HERR _iodbcdm_pushsqlerr ( HERR list, sqlstcode_t code, char* sysmsg );
# define PUSHSYSERR(list, msg) \
list = (HERR)_iodbcdm_pushsqlerr( (HERR)(list), 0, (char*)msg )
# define PUSHSQLERR(list, code) \
list = (HERR)_iodbcdm_pushsqlerr( (HERR)(list), (int)(code), NULL )
#endif /* _SQLERR_H */

598
src/iodbc/hstmt.c Normal file
View File

@ -0,0 +1,598 @@
/** Query statement object management functions
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
RETCODE SQL_API SQLAllocStmt (
HDBC hdbc,
HSTMT FAR* phstmt )
{
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
STMT_t FAR* pstmt = NULL;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode = SQL_SUCCESS;
#if (ODBCVER >= 0x0300)
if( hdbc == SQL_NULL_HDBC
|| pdbc->type != SQL_HANDLE_DBC )
#else
if( hdbc == SQL_NULL_HDBC )
#endif
{
return SQL_INVALID_HANDLE;
}
if( phstmt == NULL )
{
PUSHSQLERR ( pdbc->herr, en_S1009 );
return SQL_ERROR;
}
/* check state */
switch( pdbc->state )
{
case en_dbc_connected:
case en_dbc_hstmt:
break;
case en_dbc_allocated:
case en_dbc_needdata:
PUSHSQLERR ( pdbc->herr, en_08003 );
*phstmt = SQL_NULL_HSTMT;
return SQL_ERROR;
default:
return SQL_INVALID_HANDLE;
}
pstmt = (STMT_t FAR*)MEM_ALLOC(sizeof(STMT_t));
if( pstmt == NULL )
{
PUSHSQLERR ( pdbc->herr, en_S1001 );
*phstmt = SQL_NULL_HSTMT;
return SQL_ERROR;
}
#if (ODBCVER >= 0x0300)
pstmt->type = SQL_HANDLE_STMT;
#endif
/* initiate the object */
pstmt->herr = SQL_NULL_HERR;
pstmt->hdbc = hdbc;
pstmt->state = en_stmt_allocated;
pstmt->cursor_state = en_stmt_cursor_no;
pstmt->prep_state = 0;
pstmt->asyn_on = en_NullProc;
pstmt->need_on = en_NullProc;
/* call driver's function */
#if (ODBCVER >= 0x0300)
hproc = _iodbcdm_getproc( hdbc, en_AllocHandle );
if( hproc )
{
CALL_DRIVER ( pstmt->hdbc, hdbc, retcode, hproc,
en_AllocHandle, (
SQL_HANDLE_STMT,
pdbc->dhdbc,
&(pstmt->dhstmt) ) )
}
else
#endif
{
hproc = _iodbcdm_getproc( hdbc, en_AllocStmt );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
*phstmt = SQL_NULL_HSTMT;
MEM_FREE ( pstmt );
return SQL_ERROR;
}
CALL_DRIVER ( hdbc, retcode, hproc, en_AllocStmt, (
pdbc->dhdbc, &(pstmt->dhstmt) ) )
}
if( retcode != SQL_SUCCESS
&& retcode != SQL_SUCCESS_WITH_INFO )
{
*phstmt = SQL_NULL_HSTMT;
MEM_FREE ( pstmt );
return retcode;
}
/* insert into list */
pstmt->next = pdbc->hstmt;
pdbc->hstmt = pstmt;
*phstmt = (HSTMT)pstmt;
/* state transition */
pdbc->state = en_dbc_hstmt;
return SQL_SUCCESS;
}
RETCODE _iodbcdm_dropstmt( HSTMT hstmt )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
STMT_t FAR* tpstmt;
DBC_t FAR* pdbc;
if( hstmt == SQL_NULL_HSTMT )
{
return SQL_INVALID_HANDLE;
}
pdbc = (DBC_t FAR*)(pstmt->hdbc);
for(tpstmt = (STMT_t FAR*)pdbc->hstmt;
tpstmt != NULL;
tpstmt = tpstmt->next )
{
if(tpstmt == pstmt)
{
pdbc->hstmt = (HSTMT)pstmt->next;
break;
}
if(tpstmt->next == pstmt)
{
tpstmt->next = pstmt->next;
break;
}
}
if( tpstmt == NULL )
{
return SQL_INVALID_HANDLE;
}
_iodbcdm_freesqlerrlist(pstmt->herr);
MEM_FREE(hstmt);
return SQL_SUCCESS;
}
RETCODE SQL_API SQLfreestmt (
HSTMT hstmt,
UWORD fOption )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
STMT_t FAR* tpstmt;
DBC_t FAR* pdbc;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
pdbc = (DBC_t FAR*)(pstmt->hdbc);
/* check option */
switch( fOption )
{
case SQL_DROP:
case SQL_CLOSE:
case SQL_UNBIND:
case SQL_RESET_PARAMS:
break;
default:
PUSHSQLERR ( pstmt->herr, en_S1092 );
return SQL_ERROR;
}
/* check state */
if( pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
hproc = SQL_NULL_HPROC;
#if (ODBCVER >= 0x0300)
if( fOption == SQL_DROP )
{
hproc = _iodbcdm_getproc( pstmt->hdbc, en_FreeHandle );
if( hproc )
{
CALL_DRIVER( pstmt->hdbc, retcode, hproc, en_FreeHandle, (
SQL_HANDLE_STMT, pstmt->dhstmt )
}
}
#endif
if( hproc == SQL_NULL_HPROC )
{
hproc = _iodbcdm_getproc( pstmt->hdbc, en_FreeStmt);
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_FreeStmt, (
pstmt->dhstmt, fOption) )
}
if( retcode != SQL_SUCCESS
&& retcode != SQL_SUCCESS_WITH_INFO )
{
return retcode;
}
/* state transition */
switch( fOption )
{
case SQL_DROP:
/* delet this object (ignore return) */
_iodbcdm_dropstmt( hstmt );
break;
case SQL_CLOSE:
pstmt->cursor_state = en_stmt_cursor_no;
/* This means cursor name set by
* SQLSetCursorName() call will also
* be erased.
*/
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
break;
case en_stmt_executed:
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
if( pstmt->prep_state )
{
pstmt->state =
en_stmt_prepared;
}
else
{
pstmt->state =
en_stmt_allocated;
}
break;
default:
break;
}
break;
case SQL_UNBIND:
case SQL_RESET_PARAMS:
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLSetStmtOption (
HSTMT hstmt,
UWORD fOption,
UDWORD vParam )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
int sqlstat = en_00000;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check option */
if(/* fOption < SQL_STMT_OPT_MIN || */
fOption > SQL_STMT_OPT_MAX )
{
PUSHSQLERR ( pstmt->herr, en_S1092 );
return SQL_ERROR;
}
if( fOption == SQL_CONCURRENCY
|| fOption == SQL_CURSOR_TYPE
|| fOption == SQL_SIMULATE_CURSOR
|| fOption == SQL_USE_BOOKMARKS )
{
if( pstmt->asyn_on != en_NullProc )
{
if( pstmt->prep_state )
{
sqlstat = en_S1011;
}
}
else
{
switch( pstmt->state )
{
case en_stmt_prepared:
sqlstat = en_S1011;
break;
case en_stmt_executed:
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
sqlstat = en_24000;
break;
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
if( pstmt->prep_state )
{
sqlstat = en_S1011;
}
break;
default:
break;
}
}
}
else
{
if( pstmt->asyn_on != en_NullProc )
{
if( ! pstmt->prep_state )
{
sqlstat = en_S1010;
}
}
else
{
if( pstmt->state >= en_stmt_needdata )
{
sqlstat = en_S1010;
}
}
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetStmtOption );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetStmtOption, (
pstmt->dhstmt, fOption, vParam ) )
#if 0
retcode = hproc ( pstmt->dhstmt, fOption, vParam );
#endif
return retcode;
}
RETCODE SQL_API SQLGetStmtOption (
HSTMT hstmt,
UWORD fOption,
PTR pvParam )
{
STMT_t FAR* pstmt = (STMT_t*)hstmt;
HPROC hproc;
int sqlstat = en_00000;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check option */
if( /* fOption < SQL_STMT_OPT_MIN || */
fOption > SQL_STMT_OPT_MAX )
{
PUSHSQLERR ( pstmt->herr, en_S1092 );
return SQL_ERROR;
}
/* check state */
if( pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc )
{
sqlstat = en_S1010;
}
else
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_executed:
case en_stmt_cursoropen:
if( fOption == SQL_ROW_NUMBER
|| fOption == SQL_GET_BOOKMARK )
{
sqlstat = en_24000;
}
break;
default:
break;
}
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_GetStmtOption);
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_GetStmtOption, (
pstmt->dhstmt, fOption, pvParam ) )
#if 0
retcode = hproc ( pstmt->dhstmt, fOption, pvParam );
#endif
return retcode;
}
RETCODE SQL_API SQLCancel ( HSTMT hstmt )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
/* check state */
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_Cancel );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_Cancel, (pstmt->dhstmt) )
#if 0
retcode = hproc ( pstmt->dhstmt );
#endif
/* state transition */
if( retcode != SQL_SUCCESS
&& retcode != SQL_SUCCESS_WITH_INFO )
{
return retcode;
}
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
break;
case en_stmt_executed:
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
}
else
{
pstmt->state = en_stmt_allocated;
}
break;
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
}
else
{
pstmt->state = en_stmt_allocated;
}
break;
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
switch( pstmt->need_on )
{
case en_ExecDirect:
pstmt->state = en_stmt_allocated;
break;
case en_Execute:
pstmt->state = en_stmt_prepared;
break;
case en_SetPos:
pstmt->state = en_stmt_xfetched;
break;
default:
break;
}
pstmt->need_on = en_NullProc;
break;
default:
break;
}
return retcode;
}

48
src/iodbc/hstmt.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef _HSTMT_H
#define _HSTMT_H
#include <../iodbc/config.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
typedef struct STMT
{
int type; /* must be 1st field */
struct STMT* next;
HERR herr;
HDBC hdbc; /* back point to connection object */
HSTMT dhstmt; /* driver's stmt handle */
int state;
int cursor_state;
int prep_state;
int asyn_on; /* async executing which odbc call */
int need_on; /* which call return SQL_NEED_DATA */
} STMT_t;
enum {
en_stmt_allocated = 0,
en_stmt_prepared,
en_stmt_executed,
en_stmt_cursoropen,
en_stmt_fetched,
en_stmt_xfetched,
en_stmt_needdata, /* not call SQLParamData() yet */
en_stmt_mustput, /* not call SQLPutData() yet */
en_stmt_canput /* SQLPutData() called */
}; /* for statement handle state */
enum {
en_stmt_cursor_no = 0,
en_stmt_cursor_named,
en_stmt_cursor_opened,
en_stmt_cursor_fetched,
en_stmt_cursor_xfetched
}; /* for statement cursor state */
extern RETCODE _iodbcdm_dropstmt();
#endif

389
src/iodbc/info.c Normal file
View File

@ -0,0 +1,389 @@
/** Information functions
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
RETCODE SQL_API SQLDataSources(
HENV henv,
UWORD fDir,
UCHAR FAR* szDSN,
SWORD cbDSNMax,
SWORD FAR* pcbDSN,
UCHAR FAR* szDesc,
SWORD cbDescMax,
SWORD FAR* pcbDesc )
{
GENV_t FAR* genv = (GENV_t FAR*)henv;
if( henv == SQL_NULL_HENV )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
if( cbDSNMax < 0 || cbDescMax < 0 )
{
PUSHSQLERR ( genv->herr, en_S1090 );
return SQL_ERROR;
}
if( fDir != SQL_FETCH_FIRST
&& fDir != SQL_FETCH_NEXT )
{
PUSHSQLERR ( genv->herr, en_S1103 );
return SQL_ERROR;
}
/*************************/
return SQL_NO_DATA_FOUND;
}
RETCODE SQL_API SQLDrivers(
HENV henv,
UWORD fDir,
UCHAR FAR* szDrvDesc,
SWORD cbDrvDescMax,
SWORD FAR* pcbDrvDesc,
UCHAR FAR* szDrvAttr,
SWORD cbDrvAttrMax,
SWORD FAR* pcbDrvAttr )
{
GENV_t FAR* genv = (GENV_t FAR*)henv;
if( henv == SQL_NULL_HENV )
{
return SQL_INVALID_HANDLE;
}
if( cbDrvDescMax < 0
|| cbDrvAttrMax < 0
|| cbDrvAttrMax == 1 )
{
PUSHSQLERR ( genv->herr, en_S1090 );
return SQL_ERROR;
}
if( fDir != SQL_FETCH_FIRST
|| fDir != SQL_FETCH_NEXT )
{
PUSHSQLERR ( genv->herr, en_S1103 );
return SQL_ERROR;
}
/*********************/
return SQL_SUCCESS;
}
RETCODE SQL_API SQLGetInfo(
HDBC hdbc,
UWORD fInfoType,
PTR rgbInfoValue,
SWORD cbInfoValueMax,
SWORD FAR* pcbInfoValue )
{
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
ENV_t FAR* penv;
STMT_t FAR* pstmt = NULL;
STMT_t FAR* tpstmt;
HPROC hproc;
RETCODE retcode = SQL_SUCCESS;
DWORD dword;
int size = 0, len = 0;
char buf[16] = { '\0' };
if( hdbc == SQL_NULL_HDBC
|| pdbc->henv == SQL_NULL_HENV )
{
return SQL_INVALID_HANDLE;
}
if( cbInfoValueMax < 0 )
{
PUSHSQLERR ( pdbc->herr, en_S1090 );
return SQL_ERROR;
}
if( /* fInfoType < SQL_INFO_FIRST || */
( fInfoType > SQL_INFO_LAST
&& fInfoType < SQL_INFO_DRIVER_START ) )
{
PUSHSQLERR ( pdbc->herr, en_S1096 );
return SQL_ERROR;
}
if( fInfoType == SQL_ODBC_VER )
{
sprintf( buf, "%02d.%02d",
(ODBCVER)>>8, 0x00FF&(ODBCVER) );
if( rgbInfoValue != NULL
&& cbInfoValueMax > 0 )
{
len = STRLEN( buf );
if( len < cbInfoValueMax - 1 )
{
len = cbInfoValueMax - 1;
PUSHSQLERR ( pdbc->herr, en_01004 );
retcode = SQL_SUCCESS_WITH_INFO;
}
STRNCPY( rgbInfoValue, buf, len );
((char FAR*)rgbInfoValue)[len] = '\0';
}
if( pcbInfoValue != NULL )
{
*pcbInfoValue = (SWORD)len;
}
return retcode;
}
if( pdbc->state == en_dbc_allocated
|| pdbc->state == en_dbc_needdata )
{
PUSHSQLERR ( pdbc->herr, en_08003 );
return SQL_ERROR;
}
switch( fInfoType )
{
case SQL_DRIVER_HDBC:
dword = (DWORD)(pdbc->dhdbc);
size = sizeof(dword);
break;
case SQL_DRIVER_HENV:
penv = (ENV_t FAR*)(pdbc->henv);
dword = (DWORD)(penv->dhenv);
size = sizeof(dword);
break;
case SQL_DRIVER_HLIB:
penv = (ENV_t FAR*)(pdbc->henv);
dword = (DWORD)(penv->hdll);
size = sizeof(dword);
break;
case SQL_DRIVER_HSTMT:
if( rgbInfoValue != NULL )
{
pstmt = *((STMT_t FAR**)rgbInfoValue);
}
for( tpstmt = (STMT_t FAR*)(pdbc->hstmt);
tpstmt != NULL;
tpstmt = tpstmt->next )
{
if( tpstmt == pstmt )
{
break;
}
}
if( tpstmt == NULL )
{
PUSHSQLERR ( pdbc->herr, en_S1009 );
return SQL_ERROR;
}
dword = (DWORD)(pstmt->dhstmt);
size = sizeof(dword);
break;
default:
break;
}
if( size )
{
if( rgbInfoValue != NULL )
{
*((DWORD*)rgbInfoValue) = dword;
}
if( pcbInfoValue != NULL )
{
*(pcbInfoValue) = (SWORD)size;
}
return SQL_SUCCESS;
}
hproc = _iodbcdm_getproc( hdbc, en_GetInfo );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pdbc->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( hdbc, retcode, hproc, en_GetInfo, (
pdbc->dhdbc,
fInfoType,
rgbInfoValue,
cbInfoValueMax,
pcbInfoValue ) )
#if 0
retcode = hproc(pdbc->dhdbc,
fInfoType,
rgbInfoValue,
cbInfoValueMax,
pcbInfoValue );
#endif
if( retcode == SQL_ERROR
&& fInfoType == SQL_DRIVER_ODBC_VER )
{
STRCPY( buf, "01.00" );
if( rgbInfoValue != NULL
&& cbInfoValueMax > 0 )
{
len = STRLEN( buf );
if( len < cbInfoValueMax - 1 )
{
len = cbInfoValueMax - 1;
PUSHSQLERR ( pdbc->herr, en_01004 );
}
STRNCPY( rgbInfoValue, buf, len );
((char FAR*)rgbInfoValue)[len] = '\0';
}
if( pcbInfoValue != NULL )
{
*pcbInfoValue = (SWORD)len;
}
/* what should we return in this case ???? */
}
return retcode;
}
RETCODE SQL_API SQLGetFunctions(
HDBC hdbc,
UWORD fFunc,
UWORD FAR* pfExists )
{
DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
HPROC hproc;
RETCODE retcode;
if( hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
if( fFunc > SQL_EXT_API_LAST )
{
PUSHSQLERR ( pdbc->herr, en_S1095 );
return SQL_ERROR;
}
if( pdbc->state == en_dbc_allocated
|| pdbc->state == en_dbc_needdata )
{
PUSHSQLERR ( pdbc->herr, en_S1010 );
return SQL_ERROR;
}
if( pfExists == NULL )
{
return SQL_SUCCESS;
}
hproc = _iodbcdm_getproc( hdbc, en_GetFunctions );
if( hproc != SQL_NULL_HPROC )
{
CALL_DRIVER ( hdbc, retcode, hproc, en_GetFunctions, (
pdbc->dhdbc, fFunc, pfExists ) )
#if 0
retcode = hproc( pdbc->dhdbc, fFunc, pfExists );
#endif
return retcode;
}
if( fFunc == SQL_API_SQLSETPARAM )
{
fFunc = SQL_API_SQLBINDPARAMETER;
}
if( fFunc != SQL_API_ALL_FUNCTIONS )
{
hproc = _iodbcdm_getproc( hdbc, fFunc );
if( hproc == SQL_NULL_HPROC )
{
*pfExists = (UWORD)0;
}
else
{
*pfExists = (UWORD)1;
}
return SQL_SUCCESS;
}
for( fFunc=0 ; fFunc < 100; fFunc ++ )
{
hproc = _iodbcdm_getproc( hdbc, fFunc );
if( hproc == SQL_NULL_HPROC )
{
pfExists[fFunc] = (UWORD)0;
}
else
{
pfExists[fFunc] = (UWORD)1;
}
}
return SQL_SUCCESS;
}

66
src/iodbc/iodbc.h Normal file
View File

@ -0,0 +1,66 @@
#ifndef _CONFIG_H
#define _CONFIG_H
# if !defined(WINDOWS) && !defined(WIN32_SYSTEM)
# define _UNIX_
# include <stdlib.h>
# include <sys/types.h>
# define MEM_ALLOC(size) (malloc((size_t)(size)))
# define MEM_FREE(ptr) {if(ptr) free(ptr);}
# define STRCPY(t, s) (strcpy((char*)(t), (char*)(s)))
# define STRNCPY(t,s,n) (strncpy((char*)(t), (char*)(s), (size_t)(n)))
# define STRCAT(t, s) (strcat((char*)(t), (char*)(s)))
# define STRNCAT(t,s,n) (strncat((char*)(t), (char*)(s), (size_t)(n)))
# define STREQ(a, b) (strcmp((char*)(a), (char*)(b)) == 0)
# define STRLEN(str) ((str)? strlen((char*)(str)):0)
# define EXPORT
# define CALLBACK
# define FAR
typedef signed short SSHOR;
typedef short WORD;
typedef long DWORD;
typedef WORD WPARAM;
typedef DWORD LPARAM;
typedef void* HWND;
typedef int BOOL;
# endif /* _UNIX_ */
# if defined(WINDOWS) || defined(WIN32_SYSTEM)
# include <windows.h>
# include <windowsx.h>
# ifdef _MSVC_
# define MEM_ALLOC(size) (fmalloc((size_t)(size)))
# define MEM_FREE(ptr) ((ptr)? ffree((PTR)(ptr)):0))
# define STRCPY(t, s) (fstrcpy((char FAR*)(t), (char FAR*)(s)))
# define STRNCPY(t,s,n) (fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
# define STRLEN(str) ((str)? fstrlen((char FAR*)(str)):0)
# define STREQ(a, b) (fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
# endif
# ifdef _BORLAND_
# define MEM_ALLOC(size) (farmalloc((unsigned long)(size))
# define MEM_FREE(ptr) ((ptr)? farfree((void far*)(ptr)):0)
# define STRCPY(t, s) (_fstrcpy((char FAR*)(t), (char FAR*)(s)))
# define STRNCPY(t,s,n) (_fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
# define STRLEN(str) ((str)? _fstrlen((char FAR*)(str)):0)
# define STREQ(a, b) (_fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
# endif
# endif /* WINDOWS */
# define SYSERR (-1)
# ifndef NULL
# define NULL ((void FAR*)0UL)
# endif
#endif

91
src/iodbc/isql.h Normal file
View File

@ -0,0 +1,91 @@
#ifndef _INTRINSIC_SQL_H
# define _INTRINSIC_SQL_H
typedef unsigned char UCHAR;
typedef long int SDWORD;
typedef short int SWORD;
typedef unsigned long int UDWORD;
typedef unsigned short int UWORD;
typedef void FAR* PTR;
typedef void FAR* HENV;
typedef void FAR* HDBC;
typedef void FAR* HSTMT;
typedef signed short RETCODE;
# ifdef WIN32
# define SQL_API __stdcall
# else
# define SQL_API EXPORT CALLBACK
# endif
# define ODBCVER 0x0200
# define SQL_MAX_MESSAGE_LENGTH 512
# define SQL_MAX_DSN_LENGTH 32
/* return code */
# define SQL_INVALID_HANDLE (-2)
# define SQL_ERROR (-1)
# define SQL_SUCCESS 0
# define SQL_SUCCESS_WITH_INFO 1
# define SQL_NO_DATA_FOUND 100
/* standard SQL datatypes (agree with ANSI type numbering) */
# define SQL_CHAR 1
# define SQL_NUMERIC 2
# define SQL_DECIMAL 3
# define SQL_INTEGER 4
# define SQL_SMALLINT 5
# define SQL_FLOAT 6
# define SQL_REAL 7
# define SQL_DOUBLE 8
# define SQL_VARCHAR 12
# define SQL_TYPE_MIN SQL_CHAR
# define SQL_TYPE_NULL 0
# define SQL_TYPE_MAX SQL_VARCHAR
/* C to SQL datatype mapping */
# define SQL_C_CHAR SQL_CHAR
# define SQL_C_LONG SQL_INTEGER
# define SQL_C_SHORT SQL_SMALLINT
# define SQL_C_FLOAT SQL_REAL
# define SQL_C_DOUBLE SQL_DOUBLE
# define SQL_C_DEFAULT 99
# define SQL_NO_NULLS 0
# define SQL_NULLABLE 1
# define SQL_NULLABLE_UNKNOWN 2
/* some special length values */
# define SQL_NULL_DATA (-1)
# define SQL_DATA_AT_EXEC (-2)
# define SQL_NTS (-3)
/* SQLFreeStmt flag values */
# define SQL_CLOSE 0
# define SQL_DROP 1
# define SQL_UNBIND 2
# define SQL_RESET_PARAMS 3
/* SQLTransact flag values */
# define SQL_COMMIT 0
# define SQL_ROLLBACK 1
/* SQLColAttributes flag values */
# define SQL_COLUMN_COUNT 0
# define SQL_COLUMN_LABEL 18
# define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
# define SQL_COLUMN_DRIVER_START 1000
# define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
/* Null handles */
# define SQL_NULL_HENV 0
# define SQL_NULL_HDBC 0
# define SQL_NULL_HSTMT 0
#endif

307
src/iodbc/isqlext.h Normal file
View File

@ -0,0 +1,307 @@
#ifndef _INTRINSIC_SQLEXT_H
# define _INTRINSIC_SQLEXT_H
# include <../iodbc/isql.h>
# define SQL_STILL_EXECUTING 2
# define SQL_NEED_DATA 99
/* extend SQL datatypes */
# define SQL_DATE 9
# define SQL_TIME 10
# define SQL_TIMESTAMP 11
# define SQL_LONGVARCHAR (-1)
# define SQL_BINARY (-2)
# define SQL_VARBINARY (-3)
# define SQL_LONGVARBINARY (-4)
# define SQL_BIGINT (-5)
# define SQL_TINYINT (-6)
# define SQL_BIT (-7) /* conflict with SQL3 ??? */
# define SQL_TYPE_DRIVER_START (-80)
/* C to SQL datatype mapping */
# define SQL_C_DATE SQL_DATE
# define SQL_C_TIME SQL_TIME
# define SQL_C_TIMESTAMP SQL_TIMESTAMP
# define SQL_C_BINARY SQL_BINARY
# define SQL_C_BIT SQL_BIT
# define SQL_C_TINYINT SQL_TINYINT
# define SQL_SIGNED_OFFSET (-20)
# define SQL_UNSIGNED_OFFSET (-22)
# define SQL_C_SLONG (SQL_C_LONG + SQL_SIGNED_OFFSET)
# define SQL_C_SSHORT (SQL_C_SHORT + SQL_SIGNED_OFFSET)
# define SQL_C_STINYINT (SQL_TINYINT + SQL_SIGNED_OFFSET)
# define SQL_C_ULONG (SQL_C_LONG + SQL_UNSIGNED_OFFSET)
# define SQL_C_USHORT (SQL_C_SHORT + SQL_UNSIGNED_OFFSET)
# define SQL_C_UTINYINT (SQL_TINYINT + SQL_UNSIGNED_OFFSET)
# define SQL_C_BOOKMARK SQL_C_ULONG
# if defined(SQL_TYPE_MIN)
# undef SQL_TYPE_MIN
# define SQL_TYPE_MIN SQL_BIT
/* Note:If SQL_BIT uses SQL3 value (i.e. 14) then,
* SQL_TYPE_MIN need to be defined as SQL_TINYINT
* (i.e. -6).
*/
# endif
# define SQL_ALL_TYPES 0
/* SQLDriverConnect flag values */
# define SQL_DRIVER_NOPROMPT 0
# define SQL_DRIVER_COMPLETE 1
# define SQL_DRIVER_PROMPT 2
# define SQL_DRIVER_COMPLETE_REQUIRED 3
/* SQLSetParam extensions */
# define SQL_DEFAULT_PARAM (-5)
# define SQL_IGNORE (-6)
/* function number for SQLGetFunctions and _iodbcdm_getproc */
# define SQL_API_SQLALLOCCONNECT 1
# define SQL_API_SQLALLOCENV 2
# define SQL_API_SQLALLOCSTMT 3
# define SQL_API_SQLBINDCOL 4
# define SQL_API_SQLCANCEL 5
# define SQL_API_SQLCOLATTRIBUTES 6
# define SQL_API_SQLCONNECT 7
# define SQL_API_SQLDESCRIBECOL 8
# define SQL_API_SQLDISCONNECT 9
# define SQL_API_SQLERROR 10
# define SQL_API_SQLEXECDIRECT 11
# define SQL_API_SQLEXECUTE 12
# define SQL_API_SQLFETCH 13
# define SQL_API_SQLFREECONNECT 14
# define SQL_API_SQLFREEENV 15
# define SQL_API_SQLFREESTMT 16
# define SQL_API_SQLGETCURSORNAME 17
# define SQL_API_SQLNUMRESULTCOLS 18
# define SQL_API_SQLPREPARE 19
# define SQL_API_SQLROWCOUNT 20
# define SQL_API_SQLSETCURSORNAME 21
# define SQL_API_SQLSETPARAM 22
# define SQL_API_SQLTRANSACT 23
# define SQL_NUM_FUNCTIONS 23
# define SQL_EXT_API_START 40
# define SQL_API_SQLCOLUMNS 40
# define SQL_API_SQLDRIVERCONNECT 41
# define SQL_API_SQLGETCONNECTOPTION 42
# define SQL_API_SQLGETDATA 43
# define SQL_API_SQLGETFUNCTIONS 44
# define SQL_API_SQLGETINFO 45
# define SQL_API_SQLGETSTMTOPTION 46
# define SQL_API_SQLGETTYPEINFO 47
# define SQL_API_SQLPARAMDATA 48
# define SQL_API_SQLPUTDATA 49
# define SQL_API_SQLSETCONNECTOPTION 50
# define SQL_API_SQLSETSTMTOPTION 51
# define SQL_API_SQLSPECIALCOLUMNS 52
# define SQL_API_SQLSTATISTICS 53
# define SQL_API_SQLTABLES 54
# define SQL_API_SQLBROWSECONNECT 55
# define SQL_API_SQLCOLUMNPRIVILEGES 56
# define SQL_API_SQLDATASOURCES 57
# define SQL_API_SQLDESCRIBEPARAM 58
# define SQL_API_SQLEXTENDEDFETCH 59
# define SQL_API_SQLFOREIGNKEYS 60
# define SQL_API_SQLMORERESULTS 61
# define SQL_API_SQLNATIVESQL 62
# define SQL_API_SQLNUMPARAMS 63
# define SQL_API_SQLPARAMOPTIONS 64
# define SQL_API_SQLPRIMARYKEYS 65
# define SQL_API_SQLPROCEDURECOLUMNS 66
# define SQL_API_SQLPROCEDURES 67
# define SQL_API_SQLSETPOS 68
# define SQL_API_SQLSETSCROLLOPTIONS 69
# define SQL_API_SQLTABLEPRIVILEGES 70
# define SQL_API_SQLDRIVERS 71
# define SQL_API_SQLBINDPARAMETER 72
# define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER
# define SQL_API_ALL_FUNCTIONS 0
/* SQLGetInfo infor number */
# define SQL_INFO_FIRST 0
# define SQL_DRIVER_HDBC 3
# define SQL_DRIVER_HENV 4
# define SQL_DRIVER_HSTMT 5
# define SQL_DRIVER_NAME 6
# define SQL_ODBC_VER 10
# define SQL_CURSOR_COMMIT_BEHAVIOR 23
# define SQL_CURSOR_ROLLBACK_BEHAVIOR 24
# define SQL_DEFAULT_TXN_ISOLATION 26
# define SQL_TXN_ISOLATION_OPTION 72
# define SQL_NON_NULLABLE_COLUMNS 75
# define SQL_DRIVER_HLIB 76
# define SQL_DRIVER_ODBC_VER 77
# define SQL_QUALIFIER_LOCATION 114
# define SQL_INFO_LAST SQL_QUALIFIER_LOCATION
# define SQL_INFO_DRIVER_START 1000
/* SQL_TXN_ISOLATION_OPTION masks */
# define SQL_TXN_READ_UNCOMMITTED 0x00000001L
# define SQL_TXN_READ_COMMITTED 0x00000002L
# define SQL_TXN_REPEATABLE_READ 0x00000004L
# define SQL_TXN_SERIALIZABLE 0x00000008L
# define SQL_TXN_VERSIONING 0x00000010L
/* SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR values */
# define SQL_CB_DELETE 0x0000
# define SQL_CB_CLOSE 0x0001
# define SQL_CB_PRESERVE 0x0002
/* options for SQLGetStmtOption/SQLSetStmtOption */
# define SQL_QUERY_TIMEOUT 0
# define SQL_MAX_ROWS 1
# define SQL_NOSCAN 2
# define SQL_MAX_LENGTH 3
# define SQL_ASYNC_ENABLE 4
# define SQL_BIND_TYPE 5
# define SQL_CURSOR_TYPE 6
# define SQL_CONCURRENCY 7
# define SQL_KEYSET_SIZE 8
# define SQL_ROWSET_SIZE 9
# define SQL_SIMULATE_CURSOR 10
# define SQL_RETRIEVE_DATA 11
# define SQL_USE_BOOKMARKS 12
# define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */
# define SQL_ROW_NUMBER 14 /* GetStmtOption Only */
# define SQL_STMT_OPT_MAX SQL_ROW_NUMBER
# define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT
/* SQL_QUERY_TIMEOUT options */
# define SQL_QUERY_TIMEOUT_DEFAULT 0UL
/* SQL_MAX_ROWS options */
# define SQL_MAX_ROWS_DEFAULT 0UL
/* SQL_MAX_LENGTH options */
# define SQL_MAX_LENGTH_DEFAULT 0UL
/* SQL_CONCURRENCY options */
# define SQL_CONCUR_READ_ONLY 1
# define SQL_CONCUR_LOCK 2
# define SQL_CONCUR_ROWVER 3
# define SQL_CONCUR_VALUES 4
/* options for SQLSetConnectOption/SQLGetConnectOption */
# define SQL_ACCESS_MODE 101
# define SQL_AUTOCOMMIT 102
# define SQL_LOGIN_TIMEOUT 103
# define SQL_OPT_TRACE 104
# define SQL_OPT_TRACEFILE 105
# define SQL_TRANSLATE_DLL 106
# define SQL_TRANSLATE_OPTION 107
# define SQL_TXN_ISOLATION 108
# define SQL_CURRENT_QUALIFIER 109
# define SQL_ODBC_CURSORS 110
# define SQL_QUIET_MODE 111
# define SQL_PACKET_SIZE 112
# define SQL_CONN_OPT_MAX SQL_PACKET_SIZE
# define SQL_CONNECT_OPT_DRVR_START 1000
# define SQL_CONN_OPT_MIN SQL_ACCESS_MODE
/* SQL_ACCESS_MODE options */
# define SQL_MODE_READ_WRITE 0UL
# define SQL_MODE_READ_ONLY 1UL
# define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE
/* SQL_AUTOCOMMIT options */
# define SQL_AUTOCOMMIT_OFF 0UL
# define SQL_AUTOCOMMIT_ON 1UL
# define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON
/* SQL_LOGIN_TIMEOUT options */
# define SQL_LOGIN_TIMEOUT_DEFAULT 15UL
/* SQL_OPT_TRACE options */
# define SQL_OPT_TRACE_OFF 0UL
# define SQL_OPT_TRACE_ON 1UL
# define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF
# define SQL_OPT_TRACE_FILE_DEFAULT "odbc.log"
/* SQL_ODBC_CURSORS options */
# define SQL_CUR_USE_IF_NEEDED 0UL
# define SQL_CUR_USE_ODBC 1UL
# define SQL_CUR_USE_DRIVER 2UL
# define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER
/* Column types and scopes in SQLSpecialColumns. */
# define SQL_BEST_ROWID 1
# define SQL_ROWVER 2
# define SQL_SCOPE_CURROW 0
# define SQL_SCOPE_TRANSACTION 1
# define SQL_SCOPE_SESSION 2
/* Operations in SQLSetPos */
# define SQL_ADD 4
/* Lock options in SQLSetPos */
# define SQL_LOCK_NO_CHANGE 0
# define SQL_LOCK_EXCLUSIVE 1
# define SQL_LOCK_UNLOCK 2
/* SQLExtendedFetch flag values */
# define SQL_FETCH_NEXT 1
# define SQL_FETCH_FIRST 2
# define SQL_FETCH_LAST 3
# define SQL_FETCH_PRIOR 4
# define SQL_FETCH_ABSOLUTE 5
# define SQL_FETCH_RELATIVE 6
# define SQL_FETCH_BOOKMARK 8
/* Defines for SQLBindParameter/SQLProcedureColumns */
# define SQL_PARAM_TYPE_UNKNOWN 0
# define SQL_PARAM_INPUT 1
# define SQL_PARAM_INPUT_OUTPUT 2
# define SQL_RESULT_COL 3
# define SQL_PARAM_OUTPUT 4
/* Defines used by Driver Manager for mapping SQLSetParam to SQLBindParameter */
# define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT
# define SQL_SETPARAM_VALUE_MAX (-1L)
/* SQLStatistics flag values */
# define SQL_INDEX_UNIQUE 0
# define SQL_INDEX_ALL 1
# define SQL_QUICK 0
# define SQL_ENSURE 1
/* SQLSetScrollOption flag values */
# define SQL_SCROLL_FORWARD_ONLY 0L
# define SQL_SCROLL_KEYSET_DRIVEN (-1L)
# define SQL_SCROLL_DYNAMIC (-2L)
# define SQL_SCROLL_STATIC (-3L)
# ifdef __cplusplus
extern "C" {
# endif
RETCODE SQL_API SQLSetConnectOption (HDBC, UWORD, UDWORD);
RETCODE SQL_API SQLNumResultCols ( HSTMT, SWORD FAR* );
# ifdef __cplusplus
}
# endif
#endif

104
src/iodbc/itrace.c Normal file
View File

@ -0,0 +1,104 @@
/** trace functions
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/itrace.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include "../iodbc/henv.ci"
#include <stdio.h>
static int printreturn(void FAR* istm, int ret )
{
FILE FAR* stm = (FILE FAR*)istm;
char FAR* ptr = "Invalid return value";
switch( ret )
{
case SQL_SUCCESS:
ptr = "SQL_SUCCESS";
break;
case SQL_SUCCESS_WITH_INFO:
ptr = "SQL_SUCCESS_WITH_INFO";
break;
case SQL_NO_DATA_FOUND:
ptr = "SQL_NO_DATA_FOUND";
break;
case SQL_NEED_DATA:
ptr = "SQL_NEED_DATA";
break;
case SQL_INVALID_HANDLE:
ptr = "SQL_INVALID_HANDLE";
break;
case SQL_ERROR:
ptr = "SQL_ERROR";
break;
case SQL_STILL_EXECUTING:
ptr = "SQL_STILL_EXECUTING";
break;
default:
break;
}
fprintf( stm, "%s\n", ptr);
fflush( stm );
return 0;
}
HPROC _iodbcdm_gettrproc(void FAR* istm, int procid, int type)
{
FILE FAR* stm = (FILE FAR*)istm;
if( type == TRACE_TYPE_DM2DRV )
{
int i,j = 0;
for(i=0;j != en_NullProc ;i++)
{
j = odbcapi_symtab[i].en_idx;
if( j == procid )
{
fprintf( stm, "\n%s ( ... )\n",
odbcapi_symtab[i].symbol);
fflush( stm );
}
}
}
if( type == TRACE_TYPE_RETURN )
{
return (HPROC)printreturn;
}
return SQL_NULL_HPROC;
}

97
src/iodbc/itrace.h Normal file
View File

@ -0,0 +1,97 @@
#ifndef _ITRACE_H
# define _ITRACE_H
# ifdef DEBUG
# ifndef NO_TRACE
# define NO_TRACE
# endif
# endif
# define TRACE_TYPE_APP2DM 1
# define TRACE_TYPE_DM2DRV 2
# define TRACE_TYPE_DRV2DM 3
# define TRACE_TYPE_RETURN 4
extern HPROC _iodbcdm_gettrproc(void FAR* stm, int procid, int type);
# ifdef NO_TRACE
# define TRACE_CALL( stm, trace_on, procid, plist )
# else
# define TRACE_CALL( stm, trace_on, plist )\
{\
if( trace_on)\
{\
HPROC hproc;\
\
hproc = _iodbcdm_gettrproc(stm, procid, TRACE_TYPE_APP2DM);\
\
if( hproc )\
hproc plist;\
}\
}
# endif
# ifdef NO_TRACE
# define TRACE_DM2DRV( stm, procid, plist )
# else
# define TRACE_DM2DRV( stm, procid, plist )\
{\
HPROC hproc;\
\
hproc = _iodbcdm_gettrproc(stm, procid, TRACE_TYPE_DM2DRV);\
\
if( hproc )\
hproc plist;\
}
# endif
# ifdef NO_TRACE
# define TRACE_DRV2DM( stm, procid, plist )
# else
# define TRACE_DRV2DM( stm, procid, plist ) \
{\
HPROC hproc;\
\
hproc = _iodbcdm_gettrproc( stm, procid, TRACE_TYPE_DRV2DM);\
\
if( hproc )\
hproc plist;\
}
# endif
# ifdef NO_TRACE
# define TRACE_RETURN( stm, trace_on, ret )
# else
# define TRACE_RETURN( stm, trace_on, ret )\
{\
if( trace_on ) {\
HPROC hproc;\
\
hproc = _iodbcdm_gettrproc( stm, 0, TRACE_TYPE_RETURN);\
\
if( hproc )\
hproc( stm, ret );\
}\
}
# endif
# ifdef NO_TRACE
# define CALL_DRIVER( hdbc, ret, proc, procid, plist ) { ret = proc plist; }
# else
# define CALL_DRIVER( hdbc, ret, proc, procid, plist )\
{\
DBC_t FAR* pdbc = (DBC_t FAR*)(hdbc);\
\
if( pdbc->trace ) {\
TRACE_DM2DRV( pdbc->tstm, procid, plist )\
ret = proc plist;\
TRACE_DRV2DM( pdbc->tstm, procid, plist )\
TRACE_RETURN( pdbc->tstm, 1, ret )\
}\
else\
ret = proc plist;\
}
# endif
#endif

7
src/iodbc/main.c Normal file
View File

@ -0,0 +1,7 @@
#include <iodbc.h>
/* entry function used to build a share library on AIX */
int __start()
{
return 0;
}

379
src/iodbc/misc.c Normal file
View File

@ -0,0 +1,379 @@
/** miscellaneous functions
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <stdio.h>
static int
upper_strneq(
char* s1,
char* s2,
int n )
{
int i;
char c1, c2;
for(i=1;i<n;i++)
{
c1 = s1[i];
c2 = s2[i];
if( c1 >= 'a' && c1 <= 'z' )
{
c1 += ('A' - 'a');
}
else if( c1 == '\n' )
{
c1 = '\0';
}
if( c2 >= 'a' && c2 <= 'z' )
{
c2 += ('A' - 'a');
}
else if( c2 == '\n' )
{
c2 = '\0';
}
if( (c1 - c2) || !c1 || !c2 )
{
break;
}
}
return (int)!(c1 - c2);
}
static char* /* return new position in input str */
readtoken(
char* istr, /* old position in input buf */
char* obuf ) /* token string ( if "\0", then finished ) */
{
for(; *istr && *istr != '\n' ; istr ++ )
{
char c, nx;
c = *(istr);
if( c == ' ' || c == '\t' )
{
continue;
}
nx = *(istr + 1);
*obuf = c;
obuf ++;
if( c == ';' || c == '=' )
{
istr ++;
break;
}
if( nx == ' ' || nx == '\t' || nx == ';' || nx == '=' )
{
istr ++;
break;
}
}
*obuf = '\0';
return istr;
}
#if !defined(WINDOWS) && !defined(WIN32) && !defined(OS2)
# include <pwd.h>
# define UNIX_PWD
#endif
static char*
getinitfile(char* buf, int size)
{
int i, j;
char* ptr;
j = STRLEN("/odbc.ini") + 1;
if( size < j )
{
return NULL;
}
#if !defined(UNIX_PWD)
i = GetWindowsDirectory((LPSTR)buf, size );
if( i == 0 || i > size - j )
{
return NULL;
}
sprintf( buf + i, "/odbc.ini");
return buf;
#else
ptr = (char*)getpwuid(getuid());
if( ptr == NULL )
{
return NULL;
}
ptr = ((struct passwd*)ptr)->pw_dir;
if( ptr == NULL || *ptr == '\0' )
{
ptr = "/home";
}
if( size < STRLEN(ptr) + j )
{
return NULL;
}
sprintf( buf, "%s%s", ptr, "/.odbc.ini");
/* i.e. searching ~/.odbc.ini */
#endif
return buf;
}
char* _iodbcdm_getkeyvalbydsn(
char* dsn,
int dsnlen,
char* keywd,
char* value,
int size )
/* read odbc init file to resolve the value of specified
* key from named or defaulted dsn section
*/
{
char buf[1024];
char dsntk[SQL_MAX_DSN_LENGTH + 3] = { '[', '\0' };
char token[1024]; /* large enough */
FILE* file;
char pathbuf[1024];
char* path;
#define DSN_NOMATCH 0
#define DSN_NAMED 1
#define DSN_DEFAULT 2
int dsnid = DSN_NOMATCH;
int defaultdsn = DSN_NOMATCH;
if( dsn == NULL || *dsn == 0 )
{
dsn = "default";
dsnlen = STRLEN(dsn);
}
if( dsnlen == SQL_NTS )
{
dsnlen = STRLEN(dsn);
}
if( dsnlen <= 0 || keywd == NULL || buf == 0 || size <= 0 )
{
return NULL;
}
if( dsnlen > sizeof(dsntk) - 2 )
{
return NULL;
}
value[0] = '\0';
STRNCAT( dsntk, dsn, dsnlen );
STRCAT( dsntk, "]" );
dsnlen = dsnlen + 2;
path = getinitfile(pathbuf, sizeof(pathbuf));
if( path == NULL )
{
return NULL;
}
file = (FILE*)fopen(path, "r");
if( file == NULL )
{
return NULL;
}
for(;;)
{
char* str;
str = fgets(buf, sizeof(buf), file);
if( str == NULL )
{
break;
}
if( *str == '[' )
{
if( upper_strneq(str, "[default]", STRLEN("[default]")) )
{
/* we only read first dsn default dsn
* section (as well as named dsn).
*/
if( defaultdsn == DSN_NOMATCH )
{
dsnid = DSN_DEFAULT;
defaultdsn = DSN_DEFAULT;
}
else
{
dsnid = DSN_NOMATCH;
}
continue;
}
else if( upper_strneq( str, dsntk, dsnlen ) )
{
dsnid = DSN_NAMED;
}
else
{
dsnid = DSN_NOMATCH;
}
continue;
}
else if( dsnid == DSN_NOMATCH )
{
continue;
}
str = readtoken(str, token);
if( upper_strneq( keywd, token, STRLEN(keywd)) )
{
str = readtoken(str, token);
if( ! STREQ( token, "=") )
/* something other than = */
{
continue;
}
str = readtoken(str, token);
if( STRLEN(token) > size - 1)
{
break;
}
STRNCPY(value, token, size);
/* copy the value(i.e. next token) to buf */
if( dsnid != DSN_DEFAULT )
{
break;
}
}
}
fclose(file);
return (*value)? value:NULL;
}
char* _iodbcdm_getkeyvalinstr(
char* cnstr,
int cnlen,
char* keywd,
char* value,
int size )
{
char token[1024] = { '\0' };
int flag = 0;
if( cnstr == NULL || value == NULL
|| keywd == NULL || size < 1 )
{
return NULL;
}
if( cnlen == SQL_NTS )
{
cnlen = STRLEN (cnstr);
}
if( cnlen <= 0 )
{
return NULL;
}
for(;;)
{
cnstr = readtoken(cnstr, token);
if( *token == '\0' )
{
break;
}
if( STREQ( token, ";" ) )
{
flag = 0;
continue;
}
switch(flag)
{
case 0:
if( upper_strneq(token, keywd, strlen(keywd)) )
{
flag = 1;
}
break;
case 1:
if( STREQ( token, "=" ) )
{
flag = 2;
}
break;
case 2:
if( size < strlen(token) + 1 )
{
return NULL;
}
STRNCPY( value, token, size );
return value;
default:
break;
}
}
return NULL;
}

188
src/iodbc/postgres/isql.h Normal file
View File

@ -0,0 +1,188 @@
#ifndef _INTRINSIC_SQL_H
# define _INTRINSIC_SQL_H
#ifndef OS2
typedef unsigned char UCHAR;
#endif
typedef long int SDWORD;
typedef short int SWORD;
typedef unsigned long int UDWORD;
typedef unsigned short int UWORD;
#ifndef FAR
# define FAR
#endif
#ifndef NEAR
# define NEAR
#endif
#ifndef HANDLE
typedef int HANDLE;
#endif
#ifndef HGLOBAL
typedef HANDLE HGLOBAL;
#endif
#ifndef SQL_INDEX_OTHER
#define SQL_INDEX_OTHER 3
#endif
# ifndef BOOL
# define BOOL int
# endif
# ifndef CHAR
# define CHAR char
# endif
# ifndef FALSE
# define FALSE (0 != 0)
# endif
# ifndef HWND
# define HWND int
# endif
# ifndef SQLHWND
# define SQLHWND int
# endif
# ifndef LONG
# define LONG long
# endif
# ifndef PASCAL
# define PASCAL
# endif
# ifndef SHORT
# define SHORT short
# endif
# ifndef SQL_API
# define SQL_API
# endif
# ifndef SQL_LOCAL_API
# define SQL_LOCAL_API
# endif
# ifndef TRUE
# define TRUE (0 == 0)
# endif
typedef struct tagDATE_STRUCT
{
SWORD year;
UWORD month;
UWORD day;
} DATE_STRUCT;
typedef struct tagTIME_STRUCT
{
UWORD hour;
UWORD minute;
UWORD second;
} TIME_STRUCT;
typedef struct tagTIMESTAMP_STRUCT
{
SWORD year;
UWORD month;
UWORD day;
UWORD hour;
UWORD minute;
UWORD second;
UDWORD fraction;
} TIMESTAMP_STRUCT;
typedef UCHAR FAR* PTR,
FAR* SQLPTR;
typedef void FAR* HENV,
FAR* SQLHENV;
typedef void FAR* HDBC,
FAR* SQLHDBC;
typedef void FAR* HSTMT,
FAR* SQLHSTMT;
typedef SDWORD SQLINTEGER;
typedef signed short RETCODE;
typedef UCHAR SQLCHAR;
typedef UWORD SQLUSMALLINT;
typedef PTR SQLPOINTER;
typedef SWORD SQLSMALLINT;
typedef UDWORD SQLUINTEGER;
# ifdef WIN32
# define SQL_API __stdcall
# else
# define SQL_API /* giovanni EXPORT CALLBACK */
# endif
# ifdef OS2
# ifdef BCPP
# define _Optlink
# define _System _syscall
# endif
# undef SQL_API
# define SQL_API _System
# endif
# define ODBCVER 0x0200
# define SQL_MAX_MESSAGE_LENGTH 512
# define SQL_MAX_DSN_LENGTH 32
/* return code */
# define SQL_INVALID_HANDLE (-2)
# define SQL_ERROR (-1)
# define SQL_SUCCESS 0
# define SQL_SUCCESS_WITH_INFO 1
# define SQL_NO_DATA_FOUND 100
/* standard SQL datatypes (agree with ANSI type numbering) */
# define SQL_CHAR 1
# define SQL_NUMERIC 2
# define SQL_DECIMAL 3
# define SQL_INTEGER 4
# define SQL_SMALLINT 5
# define SQL_FLOAT 6
# define SQL_REAL 7
# define SQL_DOUBLE 8
# define SQL_VARCHAR 12
# define SQL_TYPE_MIN SQL_CHAR
# define SQL_TYPE_NULL 0
# define SQL_TYPE_MAX SQL_VARCHAR
/* C to SQL datatype mapping */
# define SQL_C_CHAR SQL_CHAR
# define SQL_C_LONG SQL_INTEGER
# define SQL_C_SHORT SQL_SMALLINT
# define SQL_C_FLOAT SQL_REAL
# define SQL_C_DOUBLE SQL_DOUBLE
# define SQL_C_DEFAULT 99
# define SQL_NO_NULLS 0
# define SQL_NULLABLE 1
# define SQL_NULLABLE_UNKNOWN 2
/* some special length values */
# define SQL_NULL_DATA (-1)
# define SQL_DATA_AT_EXEC (-2)
# define SQL_NTS (-3)
/* SQLFreeStmt flag values */
# define SQL_CLOSE 0
# define SQL_DROP 1
# define SQL_UNBIND 2
# define SQL_RESET_PARAMS 3
/* SQLTransact flag values */
# define SQL_COMMIT 0
# define SQL_ROLLBACK 1
/* SQLColAttributes flag values */
# define SQL_COLUMN_COUNT 0
# define SQL_COLUMN_LABEL 18
# define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
# define SQL_COLUMN_DRIVER_START 1000
# define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
/* Null handles */
# define SQL_NULL_HENV 0
# define SQL_NULL_HDBC 0
# define SQL_NULL_HSTMT 0
#endif

View File

@ -0,0 +1,321 @@
#ifndef _INTRINSIC_SQLEXT_H
# define _INTRINSIC_SQLEXT_H
# include <../iodbc/postgres/isql.h>
# define SQL_STILL_EXECUTING 2
# define SQL_NEED_DATA 99
/* extend SQL datatypes */
# define SQL_DATE 9
# define SQL_TIME 10
# define SQL_TIMESTAMP 11
# define SQL_LONGVARCHAR (-1)
# define SQL_BINARY (-2)
# define SQL_VARBINARY (-3)
# define SQL_LONGVARBINARY (-4)
# define SQL_BIGINT (-5)
# define SQL_TINYINT (-6)
# define SQL_BIT (-7) /* conflict with SQL3 ??? */
# define SQL_TYPE_DRIVER_START (-80)
/* C to SQL datatype mapping */
# define SQL_C_DATE SQL_DATE
# define SQL_C_TIME SQL_TIME
# define SQL_C_TIMESTAMP SQL_TIMESTAMP
# define SQL_C_BINARY SQL_BINARY
# define SQL_C_BIT SQL_BIT
# define SQL_C_TINYINT SQL_TINYINT
# define SQL_SIGNED_OFFSET (-20)
# define SQL_UNSIGNED_OFFSET (-22)
# define SQL_C_SLONG (SQL_C_LONG + SQL_SIGNED_OFFSET)
# define SQL_C_SSHORT (SQL_C_SHORT + SQL_SIGNED_OFFSET)
# define SQL_C_STINYINT (SQL_TINYINT + SQL_SIGNED_OFFSET)
# define SQL_C_ULONG (SQL_C_LONG + SQL_UNSIGNED_OFFSET)
# define SQL_C_USHORT (SQL_C_SHORT + SQL_UNSIGNED_OFFSET)
# define SQL_C_UTINYINT (SQL_TINYINT + SQL_UNSIGNED_OFFSET)
# define SQL_C_BOOKMARK SQL_C_ULONG
# if defined(SQL_TYPE_MIN)
# undef SQL_TYPE_MIN
# define SQL_TYPE_MIN SQL_BIT
/* Note:If SQL_BIT uses SQL3 value (i.e. 14) then,
* SQL_TYPE_MIN need to be defined as SQL_TINYINT
* (i.e. -6).
*/
# endif
# define SQL_ALL_TYPES 0
/* SQLDriverConnect flag values */
# define SQL_DRIVER_NOPROMPT 0
# define SQL_DRIVER_COMPLETE 1
# define SQL_DRIVER_PROMPT 2
# define SQL_DRIVER_COMPLETE_REQUIRED 3
/* SQLSetParam extensions */
# define SQL_DEFAULT_PARAM (-5)
# define SQL_IGNORE (-6)
/* function number for SQLGetFunctions and _iodbcdm_getproc */
# define SQL_API_SQLALLOCCONNECT 1
# define SQL_API_SQLALLOCENV 2
# define SQL_API_SQLALLOCSTMT 3
# define SQL_API_SQLBINDCOL 4
# define SQL_API_SQLCANCEL 5
# define SQL_API_SQLCOLATTRIBUTES 6
# define SQL_API_SQLCONNECT 7
# define SQL_API_SQLDESCRIBECOL 8
# define SQL_API_SQLDISCONNECT 9
# define SQL_API_SQLERROR 10
# define SQL_API_SQLEXECDIRECT 11
# define SQL_API_SQLEXECUTE 12
# define SQL_API_SQLFETCH 13
# define SQL_API_SQLFREECONNECT 14
# define SQL_API_SQLFREEENV 15
# define SQL_API_SQLFREESTMT 16
# define SQL_API_SQLGETCURSORNAME 17
# define SQL_API_SQLNUMRESULTCOLS 18
# define SQL_API_SQLPREPARE 19
# define SQL_API_SQLROWCOUNT 20
# define SQL_API_SQLSETCURSORNAME 21
# define SQL_API_SQLSETPARAM 22
# define SQL_API_SQLTRANSACT 23
# define SQL_NUM_FUNCTIONS 23
# define SQL_EXT_API_START 40
# define SQL_API_SQLCOLUMNS 40
# define SQL_API_SQLDRIVERCONNECT 41
# define SQL_API_SQLGETCONNECTOPTION 42
# define SQL_API_SQLGETDATA 43
# define SQL_API_SQLGETFUNCTIONS 44
# define SQL_API_SQLGETINFO 45
# define SQL_API_SQLGETSTMTOPTION 46
# define SQL_API_SQLGETTYPEINFO 47
# define SQL_API_SQLPARAMDATA 48
# define SQL_API_SQLPUTDATA 49
# define SQL_API_SQLSETCONNECTOPTION 50
# define SQL_API_SQLSETSTMTOPTION 51
# define SQL_API_SQLSPECIALCOLUMNS 52
# define SQL_API_SQLSTATISTICS 53
# define SQL_API_SQLTABLES 54
# define SQL_API_SQLBROWSECONNECT 55
# define SQL_API_SQLCOLUMNPRIVILEGES 56
# define SQL_API_SQLDATASOURCES 57
# define SQL_API_SQLDESCRIBEPARAM 58
# define SQL_API_SQLEXTENDEDFETCH 59
# define SQL_API_SQLFOREIGNKEYS 60
# define SQL_API_SQLMORERESULTS 61
# define SQL_API_SQLNATIVESQL 62
# define SQL_API_SQLNUMPARAMS 63
# define SQL_API_SQLPARAMOPTIONS 64
# define SQL_API_SQLPRIMARYKEYS 65
# define SQL_API_SQLPROCEDURECOLUMNS 66
# define SQL_API_SQLPROCEDURES 67
# define SQL_API_SQLSETPOS 68
# define SQL_API_SQLSETSCROLLOPTIONS 69
# define SQL_API_SQLTABLEPRIVILEGES 70
# define SQL_API_SQLDRIVERS 71
# define SQL_API_SQLBINDPARAMETER 72
# define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER
# define SQL_API_ALL_FUNCTIONS 0
/* SQLGetInfo infor number */
# define SQL_INFO_FIRST 0
# define SQL_DRIVER_HDBC 3
# define SQL_DRIVER_HENV 4
# define SQL_DRIVER_HSTMT 5
# define SQL_DRIVER_NAME 6
# define SQL_ODBC_VER 10
# define SQL_CURSOR_COMMIT_BEHAVIOR 23
# define SQL_CURSOR_ROLLBACK_BEHAVIOR 24
# define SQL_DEFAULT_TXN_ISOLATION 26
# define SQL_TXN_ISOLATION_OPTION 72
# define SQL_NON_NULLABLE_COLUMNS 75
# define SQL_DRIVER_HLIB 76
# define SQL_DRIVER_ODBC_VER 77
# define SQL_QUALIFIER_LOCATION 114
# define SQL_INFO_LAST SQL_QUALIFIER_LOCATION
# define SQL_INFO_DRIVER_START 1000
/* SQL_TXN_ISOLATION_OPTION masks */
# define SQL_TXN_READ_UNCOMMITTED 0x00000001L
# define SQL_TXN_READ_COMMITTED 0x00000002L
# define SQL_TXN_REPEATABLE_READ 0x00000004L
# define SQL_TXN_SERIALIZABLE 0x00000008L
# define SQL_TXN_VERSIONING 0x00000010L
/* SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR values */
# define SQL_CB_DELETE 0x0000
# define SQL_CB_CLOSE 0x0001
# define SQL_CB_PRESERVE 0x0002
/* options for SQLGetStmtOption/SQLSetStmtOption */
# define SQL_QUERY_TIMEOUT 0
# define SQL_MAX_ROWS 1
# define SQL_NOSCAN 2
# define SQL_MAX_LENGTH 3
# define SQL_ASYNC_ENABLE 4
# define SQL_BIND_TYPE 5
# define SQL_CURSOR_TYPE 6
# define SQL_CONCURRENCY 7
# define SQL_KEYSET_SIZE 8
# define SQL_ROWSET_SIZE 9
# define SQL_SIMULATE_CURSOR 10
# define SQL_RETRIEVE_DATA 11
# define SQL_USE_BOOKMARKS 12
# define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */
# define SQL_ROW_NUMBER 14 /* GetStmtOption Only */
# define SQL_STMT_OPT_MAX SQL_ROW_NUMBER
# define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT
/* SQL_QUERY_TIMEOUT options */
# define SQL_QUERY_TIMEOUT_DEFAULT 0UL
/* SQL_MAX_ROWS options */
# define SQL_MAX_ROWS_DEFAULT 0UL
/* SQL_MAX_LENGTH options */
# define SQL_MAX_LENGTH_DEFAULT 0UL
/* SQL_CONCURRENCY options */
# define SQL_CONCUR_READ_ONLY 1
# define SQL_CONCUR_LOCK 2
# define SQL_CONCUR_ROWVER 3
# define SQL_CONCUR_VALUES 4
/* options for SQLSetConnectOption/SQLGetConnectOption */
# define SQL_ACCESS_MODE 101
# define SQL_AUTOCOMMIT 102
# define SQL_LOGIN_TIMEOUT 103
# define SQL_OPT_TRACE 104
# define SQL_OPT_TRACEFILE 105
# define SQL_TRANSLATE_DLL 106
# define SQL_TRANSLATE_OPTION 107
# define SQL_TXN_ISOLATION 108
# define SQL_CURRENT_QUALIFIER 109
# define SQL_ODBC_CURSORS 110
# define SQL_QUIET_MODE 111
# define SQL_PACKET_SIZE 112
# define SQL_CONN_OPT_MAX SQL_PACKET_SIZE
# define SQL_CONNECT_OPT_DRVR_START 1000
# define SQL_CONN_OPT_MIN SQL_ACCESS_MODE
/* SQL_ACCESS_MODE options */
# define SQL_MODE_READ_WRITE 0UL
# define SQL_MODE_READ_ONLY 1UL
# define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE
/* SQL_AUTOCOMMIT options */
# define SQL_AUTOCOMMIT_OFF 0UL
# define SQL_AUTOCOMMIT_ON 1UL
# define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON
/* SQL_LOGIN_TIMEOUT options */
# define SQL_LOGIN_TIMEOUT_DEFAULT 15UL
/* SQL_OPT_TRACE options */
# define SQL_OPT_TRACE_OFF 0UL
# define SQL_OPT_TRACE_ON 1UL
# define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF
# define SQL_OPT_TRACE_FILE_DEFAULT "odbc.log"
/* SQL_ODBC_CURSORS options */
# define SQL_CUR_USE_IF_NEEDED 0UL
# define SQL_CUR_USE_ODBC 1UL
# define SQL_CUR_USE_DRIVER 2UL
# define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER
/* Column types and scopes in SQLSpecialColumns. */
# define SQL_BEST_ROWID 1
# define SQL_ROWVER 2
# define SQL_SCOPE_CURROW 0
# define SQL_SCOPE_TRANSACTION 1
# define SQL_SCOPE_SESSION 2
/* Operations in SQLSetPos */
# define SQL_ADD 4
/* Lock options in SQLSetPos */
# define SQL_LOCK_NO_CHANGE 0
# define SQL_LOCK_EXCLUSIVE 1
# define SQL_LOCK_UNLOCK 2
/* SQLExtendedFetch flag values */
# define SQL_FETCH_NEXT 1
# define SQL_FETCH_FIRST 2
# define SQL_FETCH_LAST 3
# define SQL_FETCH_PRIOR 4
# define SQL_FETCH_ABSOLUTE 5
# define SQL_FETCH_RELATIVE 6
# define SQL_FETCH_BOOKMARK 8
/* Defines for SQLBindParameter/SQLProcedureColumns */
# define SQL_PARAM_TYPE_UNKNOWN 0
# define SQL_PARAM_INPUT 1
# define SQL_PARAM_INPUT_OUTPUT 2
# define SQL_RESULT_COL 3
# define SQL_PARAM_OUTPUT 4
/* Defines used by Driver Manager for mapping SQLSetParam to SQLBindParameter */
# define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT
# define SQL_SETPARAM_VALUE_MAX (-1L)
/* SQLStatistics flag values */
# define SQL_INDEX_UNIQUE 0
# define SQL_INDEX_ALL 1
# define SQL_QUICK 0
# define SQL_ENSURE 1
/* SQLSetScrollOption flag values */
# define SQL_SCROLL_FORWARD_ONLY 0L
# define SQL_SCROLL_KEYSET_DRIVEN (-1L)
# define SQL_SCROLL_DYNAMIC (-2L)
# define SQL_SCROLL_STATIC (-3L)
# if defined(__cplusplus) || defined(__IBMCPP__)
extern "C" {
# endif
/* SQL CONVERT_FUNCTIONS function */
#define SQL_FN_CVT_CONVERT 0x00000001L
/* SQL_SUBQUERIES masks */
#define SQL_SQ_COMPARISON 0x00000001L
#define SQL_SQ_EXISTS 0x00000002L
#define SQL_SQ_IN 0x00000004L
#define SQL_SQ_QUANTIFIED 0x00000008L
#define SQL_SQ_CORRELATED_SUBQUERIES 0x00000010L
RETCODE SQL_API SQLSetConnectOption (HDBC, UWORD, UDWORD);
RETCODE SQL_API SQLNumResultCols ( HSTMT, SWORD FAR* );
# if defined(__cplusplus) || defined(__IBMCPP__)
}
# endif
#endif

View File

@ -0,0 +1,380 @@
#define SQLRETURN RETCODE
SQLRETURN SQL_API SQLDriverConnect(
SQLHDBC hdbc,
SQLHWND hwnd,
SQLCHAR FAR *szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR FAR *szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT FAR *pcbConnStrOut,
SQLUSMALLINT fDriverCompletion);
SQLRETURN SQL_API SQLBrowseConnect(
SQLHDBC hdbc,
SQLCHAR FAR *szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR FAR *szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT FAR *pcbConnStrOut);
SQLRETURN SQL_API SQLColumnPrivileges(
SQLHSTMT hstmt,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szTableName,
SQLSMALLINT cbTableName,
SQLCHAR FAR *szColumnName,
SQLSMALLINT cbColumnName);
SQLRETURN SQL_API SQLDescribeParam(
SQLHSTMT hstmt,
SQLUSMALLINT ipar,
SQLSMALLINT FAR *pfSqlType,
SQLUINTEGER FAR *pcbParamDef,
SQLSMALLINT FAR *pibScale,
SQLSMALLINT FAR *pfNullable);
SQLRETURN SQL_API SQLExtendedFetch(
SQLHSTMT hstmt,
SQLUSMALLINT fFetchType,
SQLINTEGER irow,
SQLUINTEGER FAR *pcrow,
SQLUSMALLINT FAR *rgfRowStatus);
SQLRETURN SQL_API SQLForeignKeys(
SQLHSTMT hstmt,
SQLCHAR FAR *szPkCatalogName,
SQLSMALLINT cbPkCatalogName,
SQLCHAR FAR *szPkSchemaName,
SQLSMALLINT cbPkSchemaName,
SQLCHAR FAR *szPkTableName,
SQLSMALLINT cbPkTableName,
SQLCHAR FAR *szFkCatalogName,
SQLSMALLINT cbFkCatalogName,
SQLCHAR FAR *szFkSchemaName,
SQLSMALLINT cbFkSchemaName,
SQLCHAR FAR *szFkTableName,
SQLSMALLINT cbFkTableName);
SQLRETURN SQL_API SQLMoreResults(
SQLHSTMT hstmt);
SQLRETURN SQL_API SQLNativeSql(
SQLHDBC hdbc,
SQLCHAR FAR *szSqlStrIn,
SQLINTEGER cbSqlStrIn,
SQLCHAR FAR *szSqlStr,
SQLINTEGER cbSqlStrMax,
SQLINTEGER FAR *pcbSqlStr);
SQLRETURN SQL_API SQLNumParams(
SQLHSTMT hstmt,
SQLSMALLINT FAR *pcpar);
SQLRETURN SQL_API SQLParamOptions(
SQLHSTMT hstmt,
SQLUINTEGER crow,
SQLUINTEGER FAR *pirow);
SQLRETURN SQL_API SQLPrimaryKeys(
SQLHSTMT hstmt,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szTableName,
SQLSMALLINT cbTableName);
SQLRETURN SQL_API SQLProcedureColumns(
SQLHSTMT hstmt,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szProcName,
SQLSMALLINT cbProcName,
SQLCHAR FAR *szColumnName,
SQLSMALLINT cbColumnName);
SQLRETURN SQL_API SQLProcedures(
SQLHSTMT hstmt,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szProcName,
SQLSMALLINT cbProcName);
SQLRETURN SQL_API SQLSetPos(
SQLHSTMT hstmt,
SQLUSMALLINT irow,
SQLUSMALLINT fOption,
SQLUSMALLINT fLock);
SQLRETURN SQL_API SQLTablePrivileges(
SQLHSTMT hstmt,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szTableName,
SQLSMALLINT cbTableName);
SQLRETURN SQL_API SQLDrivers(
SQLHENV henv,
SQLUSMALLINT fDirection,
SQLCHAR FAR *szDriverDesc,
SQLSMALLINT cbDriverDescMax,
SQLSMALLINT FAR *pcbDriverDesc,
SQLCHAR FAR *szDriverAttributes,
SQLSMALLINT cbDrvrAttrMax,
SQLSMALLINT FAR *pcbDrvrAttr);
SQLRETURN SQL_API SQLBindParameter(
SQLHSTMT hstmt,
SQLUSMALLINT ipar,
SQLSMALLINT fParamType,
SQLSMALLINT fCType,
SQLSMALLINT fSqlType,
SQLUINTEGER cbColDef,
SQLSMALLINT ibScale,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER FAR *pcbValue);
SQLRETURN SQL_API SQLAllocConnect(
SQLHENV henv,
SQLHDBC FAR *phdbc);
SQLRETURN SQL_API SQLAllocEnv(
SQLHENV FAR *phenv);
SQLRETURN SQL_API SQLAllocStmt(
SQLHDBC hdbc,
SQLHSTMT FAR *phstmt);
SQLRETURN SQL_API SQLBindCol(
SQLHSTMT hstmt,
SQLUSMALLINT icol,
SQLSMALLINT fCType,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER FAR *pcbValue);
SQLRETURN SQL_API SQLCancel(
SQLHSTMT hstmt);
SQLRETURN SQL_API SQLColAttributes(
SQLHSTMT hstmt,
SQLUSMALLINT icol,
SQLUSMALLINT fDescType,
SQLPOINTER rgbDesc,
SQLSMALLINT cbDescMax,
SQLSMALLINT FAR *pcbDesc,
SQLINTEGER FAR *pfDesc);
SQLRETURN SQL_API SQLConnect(
SQLHDBC hdbc,
SQLCHAR FAR *szDSN,
SQLSMALLINT cbDSN,
SQLCHAR FAR *szUID,
SQLSMALLINT cbUID,
SQLCHAR FAR *szAuthStr,
SQLSMALLINT cbAuthStr);
SQLRETURN SQL_API SQLDescribeCol(
SQLHSTMT hstmt,
SQLUSMALLINT icol,
SQLCHAR FAR *szColName,
SQLSMALLINT cbColNameMax,
SQLSMALLINT FAR *pcbColName,
SQLSMALLINT FAR *pfSqlType,
SQLUINTEGER FAR *pcbColDef,
SQLSMALLINT FAR *pibScale,
SQLSMALLINT FAR *pfNullable);
SQLRETURN SQL_API SQLDisconnect(
SQLHDBC hdbc);
SQLRETURN SQL_API SQLError(
SQLHENV henv,
SQLHDBC hdbc,
SQLHSTMT hstmt,
SQLCHAR FAR *szSqlState,
SQLINTEGER FAR *pfNativeError,
SQLCHAR FAR *szErrorMsg,
SQLSMALLINT cbErrorMsgMax,
SQLSMALLINT FAR *pcbErrorMsg);
SQLRETURN SQL_API SQLExecDirect(
SQLHSTMT hstmt,
SQLCHAR FAR *szSqlStr,
SQLINTEGER cbSqlStr);
SQLRETURN SQL_API SQLExecute(
SQLHSTMT hstmt);
SQLRETURN SQL_API SQLFetch(
SQLHSTMT hstmt);
SQLRETURN SQL_API SQLFreeConnect(
SQLHDBC hdbc);
SQLRETURN SQL_API SQLFreeEnv(
SQLHENV henv);
SQLRETURN SQL_API SQLFreeStmt(
SQLHSTMT hstmt,
SQLUSMALLINT fOption);
SQLRETURN SQL_API SQLGetCursorName(
SQLHSTMT hstmt,
SQLCHAR FAR *szCursor,
SQLSMALLINT cbCursorMax,
SQLSMALLINT FAR *pcbCursor);
SQLRETURN SQL_API SQLNumResultCols(
SQLHSTMT hstmt,
SQLSMALLINT FAR *pccol);
SQLRETURN SQL_API SQLPrepare(
SQLHSTMT hstmt,
SQLCHAR FAR *szSqlStr,
SQLINTEGER cbSqlStr);
SQLRETURN SQL_API SQLRowCount(
SQLHSTMT hstmt,
SQLINTEGER FAR *pcrow);
SQLRETURN SQL_API SQLSetCursorName(
SQLHSTMT hstmt,
SQLCHAR FAR *szCursor,
SQLSMALLINT cbCursor);
SQLRETURN SQL_API SQLTransact(
SQLHENV henv,
SQLHDBC hdbc,
SQLUSMALLINT fType);
SQLRETURN SQL_API SQLSetParam( /* Use SQLBindParameter */
SQLHSTMT hstmt,
SQLUSMALLINT ipar,
SQLSMALLINT fCType,
SQLSMALLINT fSqlType,
SQLUINTEGER cbParamDef,
SQLSMALLINT ibScale,
SQLPOINTER rgbValue,
SQLINTEGER FAR *pcbValue);
SQLRETURN SQL_API SQLColumns(
SQLHSTMT hstmt,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szTableName,
SQLSMALLINT cbTableName,
SQLCHAR FAR *szColumnName,
SQLSMALLINT cbColumnName);
SQLRETURN SQL_API SQLGetConnectOption(
SQLHDBC hdbc,
SQLUSMALLINT fOption,
SQLPOINTER pvParam);
SQLRETURN SQL_API SQLGetData(
SQLHSTMT hstmt,
SQLUSMALLINT icol,
SQLSMALLINT fCType,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER FAR *pcbValue);
SQLRETURN SQL_API SQLGetFunctions(
SQLHDBC hdbc,
SQLUSMALLINT fFunction,
SQLUSMALLINT FAR *pfExists);
SQLRETURN SQL_API SQLGetInfo(
SQLHDBC hdbc,
SQLUSMALLINT fInfoType,
SQLPOINTER rgbInfoValue,
SQLSMALLINT cbInfoValueMax,
SQLSMALLINT FAR *pcbInfoValue);
SQLRETURN SQL_API SQLGetStmtOption(
SQLHSTMT hstmt,
SQLUSMALLINT fOption,
SQLPOINTER pvParam);
SQLRETURN SQL_API SQLGetTypeInfo(
SQLHSTMT hstmt,
SQLSMALLINT fSqlType);
SQLRETURN SQL_API SQLParamData(
SQLHSTMT hstmt,
SQLPOINTER FAR *prgbValue);
SQLRETURN SQL_API SQLPutData(
SQLHSTMT hstmt,
SQLPOINTER rgbValue,
SQLINTEGER cbValue);
SQLRETURN SQL_API SQLSetConnectOption(
SQLHDBC hdbc,
SQLUSMALLINT fOption,
SQLUINTEGER vParam);
SQLRETURN SQL_API SQLSetStmtOption(
SQLHSTMT hstmt,
SQLUSMALLINT fOption,
SQLUINTEGER vParam);
SQLRETURN SQL_API SQLSpecialColumns(
SQLHSTMT hstmt,
SQLUSMALLINT fColType,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szTableName,
SQLSMALLINT cbTableName,
SQLUSMALLINT fScope,
SQLUSMALLINT fNullable);
SQLRETURN SQL_API SQLStatistics(
SQLHSTMT hstmt,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szTableName,
SQLSMALLINT cbTableName,
SQLUSMALLINT fUnique,
SQLUSMALLINT fAccuracy);
SQLRETURN SQL_API SQLTables(
SQLHSTMT hstmt,
SQLCHAR FAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR FAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR FAR *szTableName,
SQLSMALLINT cbTableName,
SQLCHAR FAR *szTableType,
SQLSMALLINT cbTableType);
SQLRETURN SQL_API SQLDataSources(
SQLHENV henv,
SQLUSMALLINT fDirection,
SQLCHAR FAR *szDSN,
SQLSMALLINT cbDSNMax,
SQLSMALLINT FAR *pcbDSN,
SQLCHAR FAR *szDescription,
SQLSMALLINT cbDescriptionMax,
SQLSMALLINT FAR *pcbDescription);

View File

@ -0,0 +1,298 @@
#define SQL_SPEC_STRING "02.00" /* String constant for version */
#define SQL_ACTIVE_CONNECTIONS 0
#define SQL_ACTIVE_STATEMENTS 1
#define SQL_DATA_SOURCE_NAME 2
#define SQL_DATABASE_NAME 16 /* Use SQLGetConnectOption/SQL_CURRENT_QUALIFIER */
#define SQL_DBMS_VER 18
#define SQL_FETCH_DIRECTION 8
#define SQL_ROW_UPDATES 11
#define SQL_ODBC_SAG_CLI_CONFORMANCE 12
#define SQL_DRIVER_VER 7
#define SQL_SERVER_NAME 13
#define SQL_SEARCH_PATTERN_ESCAPE 14
#define SQL_ODBC_API_CONFORMANCE 9
#define SQL_ODBC_SQL_CONFORMANCE 15
#define SQL_OAC_LEVEL1 0x0001
#define SQL_DBMS_NAME 17
#define SQL_ACCESSIBLE_PROCEDURES 20
#define SQL_OUTER_JOINS 38
#define SQL_NEED_LONG_DATA_LEN 111
#define SQL_EXPRESSIONS_IN_ORDERBY 27
#define SQL_PROCEDURES 21
#define SQL_COLUMN_ALIAS 87
#define SQL_CONCAT_NULL_BEHAVIOR 22
#define SQL_DATA_SOURCE_READ_ONLY 25
#define SQL_ACCESSIBLE_TABLES 19
#define SQL_IDENTIFIER_QUOTE_CHAR 29
#define SQL_MAX_COLUMN_NAME_LEN 30
#define SQL_MAX_CURSOR_NAME_LEN 31
#define SQL_MAX_OWNER_NAME_LEN 32
#define SQL_MAX_PROCEDURE_NAME_LEN 33
#define SQL_MAX_QUALIFIER_NAME_LEN 34
#define SQL_MAX_TABLE_NAME_LEN 35
#define SQL_MULT_RESULT_SETS 36
#define SQL_MULTIPLE_ACTIVE_TXN 37
#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103
#define SQL_OWNER_TERM 39
#define SQL_PROCEDURE_TERM 40
#define SQL_QUALIFIER_NAME_SEPARATOR 41
#define SQL_QUALIFIER_TERM 42
#define SQL_SCROLL_CONCURRENCY 43
#define SQL_SCROLL_OPTIONS 44
#define SQL_TABLE_TERM 45
#define SQL_TXN_CAPABLE 46
#define SQL_USER_NAME 47
#define SQL_CONVERT_FUNCTIONS 48
#define SQL_SYSTEM_FUNCTIONS 51
#define SQL_NUMERIC_FUNCTIONS 49
#define SQL_FN_NUM_ABS 0x00000001L
#define SQL_FN_NUM_FLOOR 0x00000200L
#define SQL_FN_NUM_MOD 0x00000800L
#define SQL_FN_NUM_SIGN 0x00001000L
#define SQL_STRING_FUNCTIONS 50
#define SQL_FN_STR_CONCAT 0x00000001L
#define SQL_FN_STR_LEFT 0x00000004L
#define SQL_FN_STR_LENGTH 0x00000010L
#define SQL_FN_STR_LOCATE 0x00000020L
#define SQL_FN_STR_LOCATE_2 0x00010000L
#define SQL_FN_STR_RIGHT 0x00000200L
#define SQL_FN_STR_SUBSTRING 0x00000800L
#define SQL_FN_STR_REPLACE 0x00000100L
#define SQL_FN_STR_LCASE 0x00000040L
#define SQL_FN_STR_UCASE 0x00001000L
#define SQL_TIMEDATE_FUNCTIONS 52
#define SQL_FN_TD_CURDATE 0x00000002L
#define SQL_CONVERT_BIGINT 53
#define SQL_CONVERT_BIT 55
#define SQL_CONVERT_CHAR 56
#define SQL_CONVERT_DATE 57
#define SQL_CONVERT_DECIMAL 58
#define SQL_CONVERT_DOUBLE 59
#define SQL_CONVERT_FLOAT 60
#define SQL_CONVERT_INTEGER 61
#define SQL_CONVERT_LONGVARCHAR 62
#define SQL_CONVERT_NUMERIC 63
#define SQL_CONVERT_REAL 64
#define SQL_CONVERT_SMALLINT 65
#define SQL_CONVERT_TIME 66
#define SQL_CONVERT_TIMESTAMP 67
#define SQL_CONVERT_TIMESTAMP 67
#define SQL_CONVERT_TINYINT 68
#define SQL_CONVERT_VARCHAR 70
#define SQL_CVT_CHAR 0x00000001L
#define SQL_CVT_NUMERIC 0x00000002L
#define SQL_CVT_DECIMAL 0x00000004L
#define SQL_CVT_INTEGER 0x00000008L
#define SQL_CVT_SMALLINT 0x00000010L
#define SQL_CVT_FLOAT 0x00000020L
#define SQL_CVT_REAL 0x00000040L
#define SQL_CVT_DOUBLE 0x00000080L
#define SQL_CVT_VARCHAR 0x00000100L
#define SQL_CVT_LONGVARCHAR 0x00000200L
#define SQL_CVT_BIT 0x00001000L
#define SQL_CVT_TINYINT 0x00002000L
#define SQL_CVT_BIGINT 0x00004000L
#define SQL_CVT_DATE 0x00008000L
#define SQL_CVT_TIME 0x00010000L
#define SQL_CVT_TIMESTAMP 0x00020000L
#define SQL_CVT_TIMESTAMP 0x00020000L
#define SQL_CONVERT_BINARY 54
#define SQL_CONVERT_VARBINARY 69
#define SQL_CONVERT_LONGVARBINARY 71
#define SQL_CORRELATION_NAME 74
#define SQL_CN_DIFFERENT 0x0001
#define SQL_NNC_NON_NULL 0x0001
#define SQL_NULL_COLLATION 85
#define SQL_NC_START 0x0002
#define SQL_MAX_COLUMNS_IN_GROUP_BY 97
#define SQL_MAX_COLUMNS_IN_ORDER_BY 99
#define SQL_MAX_COLUMNS_IN_SELECT 100
#define SQL_MAX_COLUMNS_IN_TABLE 101
#define SQL_MAX_TABLES_IN_SELECT 106
#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103
#define SQL_MAX_ROW_SIZE 104
#define SQL_MAX_BINARY_LITERAL_LEN 112
#define SQL_MAX_CHAR_LITERAL_LEN 108
#define SQL_MAX_COLUMNS_IN_INDEX 98
#define SQL_MAX_INDEX_SIZE 102
#define SQL_MAX_STATEMENT_LEN 105
#define SQL_QL_START 0x0001L
#define SQL_SEARCHABLE 3
#define SQL_IDENTIFIER_CASE 28
#define SQL_COLUMN_NAME 1
#define SQL_COLUMN_TYPE 2
#define SQL_COLUMN_TYPE_NAME 14
#define SQL_COLUMN_PRECISION 4
#define SQL_COLUMN_DISPLAY_SIZE 6
#define SQL_COLUMN_LENGTH 3
#define SQL_COLUMN_SCALE 5
#define SQL_COLUMN_NULLABLE 7
#define SQL_COLUMN_SEARCHABLE 13
#define SQL_COLUMN_UNSIGNED 8
#define SQL_COLUMN_MONEY 9
#define SQL_COLUMN_AUTO_INCREMENT 11
#define SQL_COLUMN_CASE_SENSITIVE 12
#define SQL_COLUMN_UPDATABLE 10
#define SQL_COLUMN_OWNER_NAME 16
#define SQL_COLUMN_QUALIFIER_NAME 17
#define SQL_OSCC_COMPLIANT 0x0001
#define SQL_ODBC_SQL_OPT_IEF 73
#define SQL_LIKE_ESCAPE_CLAUSE 113
#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90
#define SQL_POS_OPERATIONS 79
#define SQL_POSITIONED_STATEMENTS 80
#define SQL_LOCK_TYPES 78
#define SQL_BOOKMARK_PERSISTENCE 82
#define SQL_ALTER_TABLE 86
#define SQL_OWNER_USAGE 91
#define SQL_QUALIFIER_USAGE 92
#define SQL_QUOTED_IDENTIFIER_CASE 93
#define SQL_SUBQUERIES 95
#define SQL_UNION 96
#define SQL_TIMEDATE_DIFF_INTERVALS 110
#define SQL_GETDATA_EXTENSIONS 81
#define SQL_GD_ANY_COLUMN 0x00000001L
#define SQL_GD_ANY_ORDER 0x00000002L
#define SQL_GD_BOUND 0x00000008L
#define SQL_STATIC_SENSITIVITY 83
#define SQL_SS_DELETIONS 0x00000002L
#define SQL_SS_UPDATES 0x00000004L
#define SQL_FILE_USAGE 84
#define SQL_FILE_NOT_SUPPORTED 0x0000
#define SQL_GROUP_BY 88
#define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001
#define SQL_KEYWORDS 89
#define SQL_SPECIAL_CHARACTERS 94
#define SQL_TIMEDATE_ADD_INTERVALS 109
#define SQL_FN_SYS_DBNAME 0x00000002L
#define SQL_FN_SYS_IFNULL 0x00000004L
#define SQL_FN_SYS_USERNAME 0x00000001L
#define SQL_FN_NUM_CEILING 0x00000020L
#define SQL_FN_NUM_EXP 0x00000100L
#define SQL_FN_NUM_LOG 0x00000400L
#define SQL_FN_NUM_LOG10 0x00080000L
#define SQL_FN_NUM_LOG10 0x00080000L
#define SQL_FN_NUM_POWER 0x00100000L
#define SQL_FN_NUM_SQRT 0x00004000L
#define SQL_FN_NUM_ROUND 0x00400000L
#define SQL_FN_STR_INSERT 0x00000002L
#define SQL_FN_STR_LTRIM 0x00000008L
#define SQL_FN_STR_RTRIM 0x00000400L
#define SQL_BLOB 21
#define SQL_BLOB_LOCATOR 22
#define SQL_CLOB 23
#define SQL_CLOB_LOCATOR 24
#define SQL_DBCLOB 25
#define SQL_DBCLOB_LOCATOR 26
#define SQL_GRAPHIC 27
#define SQL_LONGVARGRAPHIC 30
#define SQL_VARGRAPHIC 32
#define SQL_SQLSTATE_SIZE 8
#define SQL_COLUMN_DISTINCT_TYPE 1250
#define SQL_COLUMN_TABLE_NAME 15
#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100)
#define SQL_CB_NULL 0x0000
#define SQL_FN_NUM_RAND 0x00020000L
#define SQL_NOSCAN_OFF 0UL
#define SQL_ASYNC_ENABLE_OFF 0UL
#define SQL_CURSOR_STATIC 3UL
#define SQL_SC_NON_UNIQUE 0UL
#define SQL_UB_OFF 0UL
#define SQL_PC_NOT_PSEUDO 1
#define SQL_PC_NON_PSEUDO SQL_PC_NOT_PSEUDO
#define SQL_UNSEARCHABLE 0
/*
* Following constants are missed in original odbc_types.h
* Added by serg@informika.ru
*/
#define SQL_UNKNOWN_TYPE 0
/* SQLColAttributes subdefines for SQL_COLUMN_SEARCHABLE */
/* These are also used by SQLGetInfo */
#define SQL_UNSEARCHABLE 0
#define SQL_LIKE_ONLY 1
#define SQL_ALL_EXCEPT_LIKE 2
#define SQL_SEARCHABLE 3
#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE
/* Special return values for SQLGetData */
#define SQL_NO_TOTAL (-4)
/* SQL_CORRELATION_NAME values */
#define SQL_CN_NONE 0x0000
#define SQL_CN_DIFFERENT 0x0001
#define SQL_CN_ANY 0x0002
/* SQL_NULL_COLLATION values */
#define SQL_NC_HIGH 0
#define SQL_NC_LOW 1
#define SQL_NC_START 0x0002
#define SQL_NC_END 0x0004
/* SQL_GROUP_BY values */
#define SQL_GB_NOT_SUPPORTED 0x0000
#define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001
#define SQL_GB_GROUP_BY_CONTAINS_SELECT 0x0002
#define SQL_GB_NO_RELATION 0x0003
/* SQL_IDENTIFIER_CASE values */
#define SQL_IC_UPPER 1
#define SQL_IC_LOWER 2
#define SQL_IC_SENSITIVE 3
#define SQL_IC_MIXED 4
/* SQL_ODBC_SQL_CONFORMANCE values */
#define SQL_OSC_MINIMUM 0x0000
#define SQL_OSC_CORE 0x0001
#define SQL_OSC_EXTENDED 0x0002
/* SQL_SCROLL_OPTIONS masks */
#define SQL_SO_FORWARD_ONLY 0x00000001L
#define SQL_SO_KEYSET_DRIVEN 0x00000002L
#define SQL_SO_DYNAMIC 0x00000004L
#define SQL_SO_MIXED 0x00000008L
#define SQL_SO_STATIC 0x00000010L
/* SQL_TXN_CAPABLE values */
#define SQL_TC_NONE 0
#define SQL_TC_DML 1
#define SQL_TC_ALL 2
#define SQL_TC_DDL_COMMIT 3
#define SQL_TC_DDL_IGNORE 4
/* SQL_ALTER_TABLE bitmasks */
#if (ODBCVER >= 0x0200)
#define SQL_AT_ADD_COLUMN 0x00000001L
#define SQL_AT_DROP_COLUMN 0x00000002L
#endif /* ODBCVER >= 0x0200 */
#define SQL_MAX_USER_NAME_LEN 107
/* SQLColAttributes subdefines for SQL_COLUMN_UPDATABLE */
#define SQL_ATTR_READONLY 0
#define SQL_ATTR_WRITE 1
#define SQL_ATTR_READWRITE_UNKNOWN 2
/* SQLExtendedFetch "rgfRowStatus" element values */
#define SQL_ROW_SUCCESS 0
#define SQL_ROW_DELETED 1
#define SQL_ROW_UPDATED 2
#define SQL_ROW_NOROW 3
#define SQL_ROW_ADDED 4
#define SQL_ROW_ERROR 5
/* SQL_TIMEDATE_FUNCTIONS */
#define SQL_FN_TD_NOW 0x00000001L
#define SQL_FN_TD_CURTIME 0x00000200L

537
src/iodbc/prepare.c Normal file
View File

@ -0,0 +1,537 @@
/** Prepare a query
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
RETCODE SQL_API SQLprepare (
HSTMT hstmt,
UCHAR FAR* szSqlStr,
SDWORD cbSqlStr )
{
STMT_t FAR* pstmt = (STMT_t*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode = SQL_SUCCESS;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
/* not on asyn state */
switch( pstmt->state )
{
case en_stmt_fetched:
case en_stmt_xfetched:
sqlstat = en_24000;
break;
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
sqlstat = en_S1010;
break;
default:
break;
}
}
else if( pstmt->asyn_on != en_Prepare )
{
/* asyn on other */
sqlstat = en_S1010;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
if( szSqlStr == NULL )
{
PUSHSQLERR ( pstmt->herr, en_S1009 );
return SQL_ERROR;
}
if( cbSqlStr < 0 && cbSqlStr != SQL_NTS )
{
PUSHSQLERR ( pstmt->herr, en_S1090 );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_Prepare );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_Prepare, (
pstmt->dhstmt, szSqlStr, cbSqlStr) )
#if 0
retcode = hproc ( pstmt->dhstmt, szSqlStr, cbSqlStr );
#endif
/* stmt state transition */
if( pstmt->asyn_on == en_Prepare )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
return retcode;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( retcode )
{
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_Prepare;
break;
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
pstmt->state = en_stmt_prepared;
pstmt->prep_state = 1;
break;
case SQL_ERROR:
switch( pstmt->state )
{
case en_stmt_prepared:
case en_stmt_executed:
pstmt->state = en_stmt_allocated;
pstmt->prep_state = 0;
break;
default:
break;
}
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLSetCursorName (
HSTMT hstmt,
UCHAR FAR* szCursor,
SWORD cbCursor )
{
STMT_t FAR* pstmt = (STMT_t*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode = SQL_SUCCESS;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
if( szCursor == NULL )
{
PUSHSQLERR ( pstmt->herr, en_S1009 );
return SQL_ERROR;
}
if( cbCursor < 0 && cbCursor != SQL_NTS )
{
PUSHSQLERR ( pstmt->herr, en_S1090 );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on != en_NullProc )
{
sqlstat = en_S1010;
}
else
{
switch( pstmt->state )
{
case en_stmt_executed:
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
sqlstat = en_24000;
break;
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
sqlstat = en_S1010;
break;
default:
break;
}
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetCursorName);
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetCursorName, (
pstmt->dhstmt, szCursor, cbCursor ) )
#if 0
retcode = hproc ( pstmt->dhstmt, szCursor, cbCursor );
#endif
if( retcode == SQL_SUCCESS
|| retcode == SQL_SUCCESS_WITH_INFO )
{
pstmt->cursor_state = en_stmt_cursor_named;
}
return retcode;
}
RETCODE SQL_API SQLBindParameter (
HSTMT hstmt,
UWORD ipar,
SWORD fParamType,
SWORD fCType,
SWORD fSqlType,
UDWORD cbColDef,
SWORD ibScale,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR* pcbValue )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
int sqlstat = en_00000;
RETCODE retcode = SQL_SUCCESS;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check param */
if( fSqlType > SQL_TYPE_MAX
|| ( fSqlType < SQL_TYPE_MIN
&& fSqlType > SQL_TYPE_DRIVER_START ) )
/* Note: SQL_TYPE_DRIVER_START is a nagtive number
* So, we use ">" */
{
sqlstat = en_S1004;
}
else if ( ipar < 1 )
{
sqlstat = en_S1093;
}
else if( (rgbValue == NULL && pcbValue == NULL)
&& fParamType != SQL_PARAM_OUTPUT )
{
sqlstat = en_S1009;
/* This means, I allow output to nowhere
* (i.e. * junk output result). But I can't
* allow input from nowhere.
*/
}
/**********
else if( cbValueMax < 0L && cbValueMax != SQL_SETPARAM_VALUE_MAX )
{
sqlstat = en_S1090;
}
**********/
else if( fParamType != SQL_PARAM_INPUT
&& fParamType != SQL_PARAM_OUTPUT
&& fParamType != SQL_PARAM_INPUT_OUTPUT )
{
sqlstat = en_S1105;
}
else
{
switch( fCType )
{
case SQL_C_DEFAULT:
case SQL_C_CHAR:
case SQL_C_BINARY:
case SQL_C_BIT:
case SQL_C_TINYINT:
case SQL_C_STINYINT:
case SQL_C_UTINYINT:
case SQL_C_SHORT:
case SQL_C_SSHORT:
case SQL_C_USHORT:
case SQL_C_LONG:
case SQL_C_SLONG:
case SQL_C_ULONG:
case SQL_C_FLOAT:
case SQL_C_DOUBLE:
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
break;
default:
sqlstat = en_S1003;
break;
}
}
if(sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* check state */
if( pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
retcode = SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_BindParameter );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_BindParameter, (
pstmt->dhstmt, ipar, fParamType, fCType, fSqlType,
cbColDef, ibScale, rgbValue, cbValueMax, pcbValue ) )
#if 0
retcode = hproc(pstmt->dhstmt, ipar, fParamType, fCType, fSqlType,
cbColDef, ibScale, rgbValue, cbValueMax, pcbValue );
#endif
return retcode;
}
RETCODE SQL_API SQLParamOptions(
HSTMT hstmt,
UDWORD crow,
UDWORD FAR* pirow )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
if( crow == (UDWORD)0UL )
{
PUSHSQLERR ( pstmt->herr, en_S1107 );
return SQL_ERROR;
}
if( pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc ( pstmt->hdbc, en_ParamOptions );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_ParamOptions, (
pstmt->dhstmt, crow, pirow) )
#if 0
retcode = hproc ( pstmt->dhstmt, crow, pirow );
#endif
return retcode;
}
RETCODE SQL_API SQLSetScrollOptions(
HSTMT hstmt,
UWORD fConcurrency,
SDWORD crowKeyset,
UWORD crowRowset )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
int sqlstat = en_00000;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
for(;;)
{
if( crowRowset == (UWORD)0 )
{
sqlstat = en_S1107;
break;
}
if( crowKeyset > (SDWORD)0L && crowKeyset < (SDWORD)crowRowset )
{
sqlstat = en_S1107;
break;
}
if( crowKeyset < 1 )
{
if( crowKeyset != SQL_SCROLL_FORWARD_ONLY
&& crowKeyset != SQL_SCROLL_STATIC
&& crowKeyset != SQL_SCROLL_KEYSET_DRIVEN
&& crowKeyset != SQL_SCROLL_DYNAMIC )
{
sqlstat = en_S1107;
break;
}
}
if( fConcurrency != SQL_CONCUR_READ_ONLY
&& fConcurrency != SQL_CONCUR_LOCK
&& fConcurrency != SQL_CONCUR_ROWVER
&& fConcurrency != SQL_CONCUR_VALUES )
{
sqlstat = en_S1108;
break;
}
if( pstmt->state != en_stmt_allocated )
{
sqlstat = en_S1010;
break;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetScrollOptions );
if( hproc == SQL_NULL_HPROC )
{
sqlstat = en_IM001;
break;
}
sqlstat = en_00000;
if( 1 ) /* turn off solaris warning message */
break;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetScrollOptions, (
pstmt->dhstmt,
fConcurrency,
crowKeyset,
crowRowset ) )
#if 0
retcode = hproc(pstmt->dhstmt,
fConcurrency,
crowKeyset,
crowRowset );
#endif
return retcode;
}
RETCODE SQL_API SQLSetParam (
HSTMT hstmt,
UWORD ipar,
SWORD fCType,
SWORD fSqlType,
UDWORD cbColDef,
SWORD ibScale,
PTR rgbValue,
SDWORD FAR *pcbValue)
{
return SQLBindParameter(hstmt,
ipar,
(SWORD)SQL_PARAM_INPUT_OUTPUT,
fCType,
fSqlType,
cbColDef,
ibScale,
rgbValue,
SQL_SETPARAM_VALUE_MAX,
pcbValue );
}

575
src/iodbc/result.c Normal file
View File

@ -0,0 +1,575 @@
/** Prepare for getting query result
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
RETCODE SQL_API SQLBindCol (
HSTMT hstmt,
UWORD icol,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR* pcbValue )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
switch(fCType)
{
case SQL_C_DEFAULT:
case SQL_C_CHAR:
case SQL_C_BINARY:
case SQL_C_BIT:
case SQL_C_TINYINT:
case SQL_C_STINYINT:
case SQL_C_UTINYINT:
case SQL_C_SHORT:
case SQL_C_SSHORT:
case SQL_C_USHORT:
case SQL_C_LONG:
case SQL_C_SLONG:
case SQL_C_ULONG:
case SQL_C_FLOAT:
case SQL_C_DOUBLE:
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
break;
default:
PUSHSQLERR ( pstmt->herr, en_S1003);
return SQL_ERROR;
}
if( cbValueMax < 0 )
{
PUSHSQLERR ( pstmt->herr, en_S1090 );
return SQL_ERROR;
}
/* check state */
if( pstmt->state > en_stmt_needdata
|| pstmt->asyn_on != en_NullProc )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver's function */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_BindCol );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_BindCol, (
pstmt->dhstmt,
icol,
fCType,
rgbValue,
cbValueMax,
pcbValue ) )
#if 0
retcode = hproc(pstmt->dhstmt,
icol,
fCType,
rgbValue,
cbValueMax,
pcbValue );
#endif
return retcode;
}
RETCODE SQL_API SQLGetCursorName(
HSTMT hstmt,
UCHAR FAR* szCursor,
SWORD cbCursorMax,
SWORD FAR* pcbCursor )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
if( cbCursorMax < (SWORD)0 )
{
PUSHSQLERR ( pstmt->herr, en_S1090 );
return SQL_ERROR;
}
/* check state */
if( pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
if( pstmt->state < en_stmt_cursoropen
&& pstmt->cursor_state == en_stmt_cursor_no )
{
PUSHSQLERR ( pstmt->herr, en_S1015 );
return SQL_ERROR;
}
/* call driver's function */
hproc = _iodbcdm_getproc ( pstmt->hdbc, en_GetCursorName );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_GetCursorName, (
pstmt->dhstmt,
szCursor,
cbCursorMax,
pcbCursor ) )
#if 0
retcode = hproc(pstmt->dhstmt,
szCursor,
cbCursorMax,
pcbCursor );
#endif
return retcode;
}
RETCODE SQL_API SQLRowCount(
HSTMT hstmt,
SDWORD FAR* pcrow )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pstmt->state >= en_stmt_needdata
|| pstmt->state <= en_stmt_prepared
|| pstmt->asyn_on != en_NullProc )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_RowCount );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_RowCount, (
pstmt->dhstmt, pcrow) )
#if 0
retcode = hproc ( pstmt->dhstmt, pcrow );
#endif
return retcode;
}
RETCODE SQL_API SQLNumResultCols(
HSTMT hstmt,
SWORD FAR* pccol )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
SWORD ccol;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
if( pstmt->state == en_stmt_allocated
|| pstmt->state >= en_stmt_needdata )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
}
else if( pstmt->asyn_on != en_NumResultCols )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_NumResultCols );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_NumResultCols, (
pstmt->dhstmt, &ccol) )
#if 0
retcode = hproc( pstmt->dhstmt, &ccol );
#endif
/* state transition */
if( pstmt->asyn_on == en_NumResultCols )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
case SQL_STILL_EXECUTING:
default:
break;
}
}
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
break;
case SQL_STILL_EXECUTING:
ccol = 0;
pstmt->asyn_on = en_NumResultCols;
break;
default:
ccol = 0;
break;
}
if( pccol )
{
*pccol = ccol;
}
return retcode;
}
RETCODE SQL_API SQLDescribeCol(
HSTMT hstmt,
UWORD icol,
UCHAR FAR* szColName,
SWORD cbColNameMax,
SWORD FAR* pcbColName,
SWORD FAR* pfSqlType,
UDWORD FAR* pcbColDef,
SWORD FAR* pibScale,
SWORD FAR* pfNullable )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check arguments */
if( icol == 0 )
{
sqlstat = en_S1002;
}
else if( cbColNameMax < 0 )
{
sqlstat = en_S1090;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
if( pstmt->asyn_on == en_stmt_allocated
|| pstmt->asyn_on >= en_stmt_needdata )
{
sqlstat = en_S1010;
}
}
else if( pstmt->asyn_on != en_DescribeCol )
{
sqlstat = en_S1010;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_DescribeCol );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_DescribeCol, (
pstmt->dhstmt,
icol,
szColName,
cbColNameMax,
pcbColName,
pfSqlType,
pcbColDef,
pibScale,
pfNullable) )
#if 0
retcode = hproc(pstmt->dhstmt,
icol,
szColName,
cbColNameMax,
pcbColName,
pfSqlType,
pcbColDef,
pibScale,
pfNullable );
#endif
/* state transition */
if( pstmt->asyn_on == en_DescribeCol )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_prepared:
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_DescribeCol;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLColAttributes(
HSTMT hstmt,
UWORD icol,
UWORD fDescType,
PTR rgbDesc,
SWORD cbDescMax,
SWORD FAR* pcbDesc,
SDWORD FAR* pfDesc )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check arguments */
if( icol == 0 && fDescType != SQL_COLUMN_COUNT )
{
sqlstat = en_S1002;
}
else if( cbDescMax < 0 )
{
sqlstat = en_S1090;
}
else if(/* fDescType < SQL_COLATT_OPT_MIN || */ /* turnoff warning */
( fDescType > SQL_COLATT_OPT_MAX
&& fDescType < SQL_COLUMN_DRIVER_START ) )
{
sqlstat = en_S1091;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
if( pstmt->asyn_on == en_stmt_allocated
|| pstmt->asyn_on >= en_stmt_needdata )
{
sqlstat = en_S1010;
}
}
else if( pstmt->asyn_on != en_ColAttributes )
{
sqlstat = en_S1010;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_ColAttributes );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_ColAttributes, (
pstmt->dhstmt,
icol,
fDescType,
rgbDesc,
cbDescMax,
pcbDesc,
pfDesc) )
#if 0
retcode = hproc(pstmt->dhstmt,
icol,
fDescType,
rgbDesc,
cbDescMax,
pcbDesc,
pfDesc );
#endif
/* state transition */
if( pstmt->asyn_on == en_ColAttributes )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_prepared:
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_ColAttributes;
}
break;
default:
break;
}
return retcode;
}

64
src/iodbc/shrsub.exp Normal file
View File

@ -0,0 +1,64 @@
SQLAllocEnv
SQLAllocConnect
SQLConnect
SQLDriverConnect
SQLBrowseConnect
SQLDataSources
SQLDrivers
SQLGetInfo
SQLGetFunctions
SQLGetTypeInfo
SQLSetConnectOption
SQLGetConnectOption
SQLSetStmtOption
SQLGetStmtOption
SQLAllocStmt
SQLPrepare
SQLBindParameter
SQLParamOptions
SQLGetCursorName
SQLSetCursorName
SQLSetScrollOptions
SQLSetParam
SQLExecute
SQLExecDirect
SQLNativeSql
SQLDescribeParam
SQLNumParams
SQLParamData
SQLPutData
SQLRowCount
SQLNumResultCols
SQLDescribeCol
SQLColAttributes
SQLBindCol
SQLFetch
SQLExtendedFetch
SQLGetData
SQLSetPos
SQLMoreResults
SQLError
SQLColumnPrivileges
SQLColumns
SQLForeignKeys
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLFreeStmt
SQLCancel
SQLTransact
SQLDisconnect
SQLFreeConnect
SQLFreeEnv

145
src/iodbc/windows.h Normal file
View File

@ -0,0 +1,145 @@
#ifndef DEBUG
#endif
#ifndef APWIN /* don't reinclude */
#define APWIN
#ifndef DEBUG
#endif
#ifdef WININC
# include <windows.h> /* normal windows.h */
# ifdef WIN32
# include <windowsx.h> /* windows extensions */
# define GetCurrentTask (HTASK)GetCurrentProcess
# define GetDOSEnvironment GetEnvironmentStrings
# define PCALL
# else
# define PCALL PASCAL
# endif
#else /* not windows */
/******* Common definitions and typedefs **********************/
#ifdef HPUX
# ifndef _VOID
# define VOID int
# endif
# ifndef _UCHAR
typedef char UCHAR;
# define _UCHAR
# endif
# ifndef _SCHAR
typedef char SCHAR;
# define _SCHAR
# endif
#endif /* HPUX */
#ifdef OSF1
# ifndef _UCHAR
typedef char UCHAR;
# define _UCHAR
# endif
# ifndef _SDWORD
# define _SDWORD
typedef int SDWORD;
# endif
# ifndef _UDWORD
# define _UDWORD
typedef unsigned int UDWORD;
# endif
# ifndef _LDOUBLE
# define _LDOUBLE
typedef double LDOUBLE;
# endif
# ifndef _DWORD
# define _DWORD
typedef int DWORD;
# endif
#endif /* OSF1 */
#if defined (SVR4) && defined(I386)
# ifndef _UCHAR
typedef char UCHAR;
# define _UCHAR
# endif
# ifndef _LDOUBLE
# define _LDOUBLE
typedef double LDOUBLE;
# endif
#endif /* SVR4 && I386 */
#ifndef _VOID
# define _VOID
# define VOID void
#endif
#ifdef WIN
# define LONG long
#endif
#ifndef _DWORD
# define _DWORD
/* typedef unsigned long DWORD; */
#endif
#ifndef _UINT
# define _UINT
typedef unsigned int UINT;
#endif
#ifdef PC
# define FAR _far
# define NEAR _near
# define PASCAL _pascal
# define CDECL _cdecl
# define WINAPI _far _pascal
# define CALLBACK _far _pascal
# define EXPORT _export
#else
# define FAR
# define NEAR
# define PASCAL
# define CDECL
# define WINAPI
# define CALLBACK
# define EXPORT
#endif
#define PCALL PASCAL
/****** Simple types & common helper macros ********************/
/* typedef int BOOL; */
#define FALSE 0
#define TRUE 1
typedef unsigned char BYTE;
/* typedef unsigned short WORD; */
#define LOBYTE(w) ((BYTE)(w))
#define HIBYTE(w) ((BYTE)(((UINT)(w) >> 8) & 0xFF))
#define LOWORD(l) ((WORD)(DWORD)(l))
#define HIWORD(l) ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF))
#define MAKELONG(low, high) ((LONG)(((WORD)(low)) |\
(((DWORD)((WORD)(high))) << 16)))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
/****** Common pointer types **********************************/
#ifndef NULL
#define NULL 0
#endif
/****** Common handle types *************************************/
typedef UINT HANDLE;
/* typedef UINT HWND; */
#endif /* ifdef not WIN */
#endif /* ifdef APWIN */
/* end of apwin.h */

View File

@ -30,3 +30,7 @@ if test ! -d gdk_imlib; then
mkdir gdk_imlib
fi
# create "/iodbc" if not present
if test ! -d iodbc; then
mkdir iodbc
fi

View File

@ -289,7 +289,7 @@ void MyDialog::OnHelloButton( wxCommandEvent &WXUNUSED(event) )
{
wxMessageDialog *dialog;
dialog = new wxMessageDialog( this, "Now, I will paint on Screen.", "wxGTK" );
dialog->ShowModal();
dialog->ShowModal();
delete dialog;
wxScreenDC dc;
@ -496,8 +496,9 @@ void MyFrame::OnSize( wxSizeEvent &WXUNUSED(event) )
void MyFrame::OnDialog( wxCommandEvent &WXUNUSED(event) )
{
MyDialog dialog( this );
dialog.ShowModal();
MyDialog *dialog = new MyDialog( this );
dialog->ShowModal();
dialog->Close( TRUE );
};
void MyFrame::OnFontDialog( wxCommandEvent &WXUNUSED(event) )